diff options
author | Michael Stahl <mstahl@redhat.com> | 2015-12-19 23:55:34 +0100 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2015-12-20 00:56:07 +0100 |
commit | d60398ff5b42ff77a4002dcd13b7fb8c9a73eade (patch) | |
tree | 2a4e19b4ba3299dc328e60bd1f865e618fcc0131 /oox/source | |
parent | 9d0d41f0f3c5215770bc7246a089d54a7244df55 (diff) |
oox: save ProgId on import, and use it in ShapeExport::WriteOLE2Shape()
Uses the same approach as DOCX import to preserve the ProgID; it would
be much better if the MediaType of the stream were preserved instead and
the other things derived from that, but this here was rather quick to do...
This makes the round-tripping of OOXML OLEs in PPTX work again, which
was broken by an earlier commit.
Change-Id: Ic7d0362f0c14bf0e522185713666bcd58db2cf64
Diffstat (limited to 'oox/source')
-rw-r--r-- | oox/source/core/filterbase.cxx | 2 | ||||
-rw-r--r-- | oox/source/export/shapes.cxx | 49 | ||||
-rw-r--r-- | oox/source/ole/oleobjecthelper.cxx | 18 |
3 files changed, 63 insertions, 6 deletions
diff --git a/oox/source/core/filterbase.cxx b/oox/source/core/filterbase.cxx index 9c7383a44c53..3fefcc082639 100644 --- a/oox/source/core/filterbase.cxx +++ b/oox/source/core/filterbase.cxx @@ -366,7 +366,7 @@ ModelObjectHelper& FilterBase::getModelObjectHelper() const OleObjectHelper& FilterBase::getOleObjectHelper() const { if( !mxImpl->mxOleObjHelper ) - mxImpl->mxOleObjHelper.reset( new OleObjectHelper( mxImpl->mxModelFactory ) ); + mxImpl->mxOleObjHelper.reset(new OleObjectHelper(mxImpl->mxModelFactory, mxImpl->mxModel)); return *mxImpl->mxOleObjHelper; } diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx index 0c087e87c585..db6ec66c5d29 100644 --- a/oox/source/export/shapes.cxx +++ b/oox/source/export/shapes.cxx @@ -316,7 +316,7 @@ uno::Reference<io::XInputStream> GetOLEObjectStream( { lcl_ConvertProgID(i_rProgID, o_rMediaType, o_rRelationType, o_rSuffix); xInStream = xParentStorage->cloneStreamElement(entryName)->getInputStream(); - // TODO: is it possible to take the sMediaType from the stream? + // TODO: make it possible to take the sMediaType from the stream } else // the object is ODF - either the whole document is { // ODF, or the OLE was edited so it was converted to ODF @@ -1609,6 +1609,44 @@ ShapeExport& ShapeExport::WriteOLE2Shape( Reference< XShape > xShape ) uno::Reference<embed::XEmbeddedObject> const xObj( xPropSet->getPropertyValue("EmbeddedObject"), uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> const xParent( + uno::Reference<container::XChild>(xObj, uno::UNO_QUERY)->getParent(), + uno::UNO_QUERY); + + uno::Sequence<beans::PropertyValue> grabBag; + xParent->getPropertyValue("InteropGrabBag") >>= grabBag; + + OUString const entryName( + uno::Reference<embed::XEmbedPersist>(xObj, uno::UNO_QUERY)->getEntryName()); + OUString progID; + + for (auto const& it : grabBag) + { + if (it.Name == "EmbeddedObjects") + { + uno::Sequence<beans::PropertyValue> objects; + it.Value >>= objects; + for (auto const& object : objects) + { + if (object.Name == entryName) + { + uno::Sequence<beans::PropertyValue> props; + object.Value >>= props; + for (auto const& prop : props) + { + if (prop.Name == "ProgID") + { + prop.Value >>= progID; + break; + } + } + break; + } + } + break; + } + } + OUString sMediaType; OUString sRelationType; OUString sSuffix; @@ -1616,7 +1654,7 @@ ShapeExport& ShapeExport::WriteOLE2Shape( Reference< XShape > xShape ) uno::Reference<io::XInputStream> const xInStream = oox::GetOLEObjectStream( - mpFB->getComponentContext(), xObj, OUString(), + mpFB->getComponentContext(), xObj, progID, sMediaType, sRelationType, sSuffix, pProgID); if (!xInStream.is()) @@ -1624,6 +1662,13 @@ ShapeExport& ShapeExport::WriteOLE2Shape( Reference< XShape > xShape ) return *this; } + OString anotherProgID; + if (!pProgID && !progID.isEmpty()) + { + anotherProgID = OUStringToOString(progID, RTL_TEXTENCODING_UTF8); + pProgID = anotherProgID.getStr(); + } + assert(!sMediaType.isEmpty()); assert(!sRelationType.isEmpty()); assert(!sSuffix.isEmpty()); diff --git a/oox/source/ole/oleobjecthelper.cxx b/oox/source/ole/oleobjecthelper.cxx index 5e6c057b0b56..12356c35d515 100644 --- a/oox/source/ole/oleobjecthelper.cxx +++ b/oox/source/ole/oleobjecthelper.cxx @@ -49,10 +49,14 @@ OleObjectInfo::OleObjectInfo() : { } -OleObjectHelper::OleObjectHelper( const Reference< XMultiServiceFactory >& rxModelFactory ) : - maEmbeddedObjScheme( "vnd.sun.star.EmbeddedObject:" ), - mnObjectId( 100 ) +OleObjectHelper::OleObjectHelper( + const Reference< XMultiServiceFactory >& rxModelFactory, + uno::Reference<frame::XModel> const& xModel) + : m_xModel(xModel) + , maEmbeddedObjScheme("vnd.sun.star.EmbeddedObject:") + , mnObjectId( 100 ) { + assert(m_xModel.is()); if( rxModelFactory.is() ) try { mxResolver.set( rxModelFactory->createInstance( "com.sun.star.document.ImportEmbeddedObjectResolver" ), UNO_QUERY ); @@ -74,6 +78,10 @@ OleObjectHelper::~OleObjectHelper() } } +// TODO: this is probably a sub-optimal approach: ideally the media type +// of the stream from [Content_Types].xml should be stored somewhere for this +// purpose, but currently the media type of all OLE streams in the storage is +// just "application/vnd.sun.star.oleobject" void SaveInteropProperties(uno::Reference<frame::XModel> const& xModel, OUString const& rObjectName, OUString const*const pOldObjectName, OUString const& rProgId, OUString const& rDrawAspect) @@ -137,6 +145,10 @@ bool OleObjectHelper::importOleObject( PropertyMap& rPropMap, const OleObjectInf xOutStrm->writeBytes( rOleObject.maEmbeddedData ); xOutStrm->closeOutput(); + SaveInteropProperties(m_xModel, aObjectId, nullptr, + rOleObject.maProgId, + rOleObject.mbShowAsIcon ? OUString("Icon") : OUString("Content")); + OUString aUrl = mxResolver->resolveEmbeddedObjectURL( aObjectId ); OSL_ENSURE( aUrl.match( maEmbeddedObjScheme ), "OleObjectHelper::importOleObject - unexpected URL scheme" ); OUString aPersistName = aUrl.copy( maEmbeddedObjScheme.getLength() ); |