Kaydet (Commit) d60398ff authored tarafından Michael Stahl's avatar Michael Stahl

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
üst 9d0d41f0
...@@ -57,7 +57,8 @@ class OleObjectHelper ...@@ -57,7 +57,8 @@ class OleObjectHelper
{ {
public: public:
explicit OleObjectHelper( explicit OleObjectHelper(
const css::uno::Reference< css::lang::XMultiServiceFactory >& rxModelFactory ); const css::uno::Reference<css::lang::XMultiServiceFactory>& rxModelFactory,
const css::uno::Reference<css::frame::XModel>& xModel);
~OleObjectHelper(); ~OleObjectHelper();
bool importOleObject( bool importOleObject(
...@@ -66,6 +67,7 @@ public: ...@@ -66,6 +67,7 @@ public:
const css::awt::Size& rObjSize ); const css::awt::Size& rObjSize );
private: private:
css::uno::Reference<css::frame::XModel> m_xModel;
css::uno::Reference< css::document::XEmbeddedObjectResolver > mxResolver; css::uno::Reference< css::document::XEmbeddedObjectResolver > mxResolver;
const OUString maEmbeddedObjScheme; const OUString maEmbeddedObjScheme;
sal_Int32 mnObjectId; sal_Int32 mnObjectId;
......
...@@ -366,7 +366,7 @@ ModelObjectHelper& FilterBase::getModelObjectHelper() const ...@@ -366,7 +366,7 @@ ModelObjectHelper& FilterBase::getModelObjectHelper() const
OleObjectHelper& FilterBase::getOleObjectHelper() const OleObjectHelper& FilterBase::getOleObjectHelper() const
{ {
if( !mxImpl->mxOleObjHelper ) if( !mxImpl->mxOleObjHelper )
mxImpl->mxOleObjHelper.reset( new OleObjectHelper( mxImpl->mxModelFactory ) ); mxImpl->mxOleObjHelper.reset(new OleObjectHelper(mxImpl->mxModelFactory, mxImpl->mxModel));
return *mxImpl->mxOleObjHelper; return *mxImpl->mxOleObjHelper;
} }
......
...@@ -316,7 +316,7 @@ uno::Reference<io::XInputStream> GetOLEObjectStream( ...@@ -316,7 +316,7 @@ uno::Reference<io::XInputStream> GetOLEObjectStream(
{ {
lcl_ConvertProgID(i_rProgID, o_rMediaType, o_rRelationType, o_rSuffix); lcl_ConvertProgID(i_rProgID, o_rMediaType, o_rRelationType, o_rSuffix);
xInStream = xParentStorage->cloneStreamElement(entryName)->getInputStream(); 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 else // the object is ODF - either the whole document is
{ // ODF, or the OLE was edited so it was converted to ODF { // ODF, or the OLE was edited so it was converted to ODF
...@@ -1609,6 +1609,44 @@ ShapeExport& ShapeExport::WriteOLE2Shape( Reference< XShape > xShape ) ...@@ -1609,6 +1609,44 @@ ShapeExport& ShapeExport::WriteOLE2Shape( Reference< XShape > xShape )
uno::Reference<embed::XEmbeddedObject> const xObj( uno::Reference<embed::XEmbeddedObject> const xObj(
xPropSet->getPropertyValue("EmbeddedObject"), uno::UNO_QUERY); 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 sMediaType;
OUString sRelationType; OUString sRelationType;
OUString sSuffix; OUString sSuffix;
...@@ -1616,7 +1654,7 @@ ShapeExport& ShapeExport::WriteOLE2Shape( Reference< XShape > xShape ) ...@@ -1616,7 +1654,7 @@ ShapeExport& ShapeExport::WriteOLE2Shape( Reference< XShape > xShape )
uno::Reference<io::XInputStream> const xInStream = uno::Reference<io::XInputStream> const xInStream =
oox::GetOLEObjectStream( oox::GetOLEObjectStream(
mpFB->getComponentContext(), xObj, OUString(), mpFB->getComponentContext(), xObj, progID,
sMediaType, sRelationType, sSuffix, pProgID); sMediaType, sRelationType, sSuffix, pProgID);
if (!xInStream.is()) if (!xInStream.is())
...@@ -1624,6 +1662,13 @@ ShapeExport& ShapeExport::WriteOLE2Shape( Reference< XShape > xShape ) ...@@ -1624,6 +1662,13 @@ ShapeExport& ShapeExport::WriteOLE2Shape( Reference< XShape > xShape )
return *this; return *this;
} }
OString anotherProgID;
if (!pProgID && !progID.isEmpty())
{
anotherProgID = OUStringToOString(progID, RTL_TEXTENCODING_UTF8);
pProgID = anotherProgID.getStr();
}
assert(!sMediaType.isEmpty()); assert(!sMediaType.isEmpty());
assert(!sRelationType.isEmpty()); assert(!sRelationType.isEmpty());
assert(!sSuffix.isEmpty()); assert(!sSuffix.isEmpty());
......
...@@ -49,10 +49,14 @@ OleObjectInfo::OleObjectInfo() : ...@@ -49,10 +49,14 @@ OleObjectInfo::OleObjectInfo() :
{ {
} }
OleObjectHelper::OleObjectHelper( const Reference< XMultiServiceFactory >& rxModelFactory ) : OleObjectHelper::OleObjectHelper(
maEmbeddedObjScheme( "vnd.sun.star.EmbeddedObject:" ), const Reference< XMultiServiceFactory >& rxModelFactory,
mnObjectId( 100 ) uno::Reference<frame::XModel> const& xModel)
: m_xModel(xModel)
, maEmbeddedObjScheme("vnd.sun.star.EmbeddedObject:")
, mnObjectId( 100 )
{ {
assert(m_xModel.is());
if( rxModelFactory.is() ) try if( rxModelFactory.is() ) try
{ {
mxResolver.set( rxModelFactory->createInstance( "com.sun.star.document.ImportEmbeddedObjectResolver" ), UNO_QUERY ); mxResolver.set( rxModelFactory->createInstance( "com.sun.star.document.ImportEmbeddedObjectResolver" ), UNO_QUERY );
...@@ -74,6 +78,10 @@ OleObjectHelper::~OleObjectHelper() ...@@ -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, void SaveInteropProperties(uno::Reference<frame::XModel> const& xModel,
OUString const& rObjectName, OUString const*const pOldObjectName, OUString const& rObjectName, OUString const*const pOldObjectName,
OUString const& rProgId, OUString const& rDrawAspect) OUString const& rProgId, OUString const& rDrawAspect)
...@@ -137,6 +145,10 @@ bool OleObjectHelper::importOleObject( PropertyMap& rPropMap, const OleObjectInf ...@@ -137,6 +145,10 @@ bool OleObjectHelper::importOleObject( PropertyMap& rPropMap, const OleObjectInf
xOutStrm->writeBytes( rOleObject.maEmbeddedData ); xOutStrm->writeBytes( rOleObject.maEmbeddedData );
xOutStrm->closeOutput(); xOutStrm->closeOutput();
SaveInteropProperties(m_xModel, aObjectId, nullptr,
rOleObject.maProgId,
rOleObject.mbShowAsIcon ? OUString("Icon") : OUString("Content"));
OUString aUrl = mxResolver->resolveEmbeddedObjectURL( aObjectId ); OUString aUrl = mxResolver->resolveEmbeddedObjectURL( aObjectId );
OSL_ENSURE( aUrl.match( maEmbeddedObjScheme ), "OleObjectHelper::importOleObject - unexpected URL scheme" ); OSL_ENSURE( aUrl.match( maEmbeddedObjScheme ), "OleObjectHelper::importOleObject - unexpected URL scheme" );
OUString aPersistName = aUrl.copy( maEmbeddedObjScheme.getLength() ); OUString aPersistName = aUrl.copy( maEmbeddedObjScheme.getLength() );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment