Kaydet (Commit) b862a216 authored tarafından Zolnai Tamás's avatar Zolnai Tamás

ODF filters: fallback glTF model to bitmap for older versions

Change-Id: I33161401a29f511e61429355dd2905d4643fe8ff
üst e627929e
......@@ -23,7 +23,7 @@
// defines ------------------------------------------------------------------
#define OWN_ATTR_VALUE_START 3900
#define OWN_ATTR_VALUE_END 3992
#define OWN_ATTR_VALUE_END 3993
#define RID_SFX_START 260
// RID_SFX_END 9999
......
......@@ -180,7 +180,8 @@
#define OWN_ATTR_MEDIA_TEMPFILEURL (OWN_ATTR_VALUE_START+90)
#define OWN_ATTR_INTEROPGRABBAG (OWN_ATTR_VALUE_START+91)
#define OWN_ATTR_MEDIA_MIMETYPE (OWN_ATTR_VALUE_START+92)
// ATTENTION: maximum is OWN_ATTR_VALUE_START+92, see include/svl/solar.hrc
#define OWN_ATTR_FALLBACK_GRAPHIC (OWN_ATTR_VALUE_START+93)
// ATTENTION: maximum is OWN_ATTR_VALUE_START+93 svx, see include/svl/solar.hrc
// #FontWork#
#define FONTWORK_PROPERTIES \
......
......@@ -733,6 +733,7 @@ SfxItemPropertyMapEntry const * ImplGetSvxMediaShapePropertyMap()
{OUString("PrivateStream"), OWN_ATTR_MEDIA_STREAM, cppu::UnoType<css::io::XInputStream>::get(), ::com::sun::star::beans::PropertyAttribute::READONLY, 0},
{OUString("PrivateTempFileURL"), OWN_ATTR_MEDIA_TEMPFILEURL, ::cppu::UnoType<OUString>::get(), ::com::sun::star::beans::PropertyAttribute::READONLY, 0},
{ OUString("MediaMimeType"), OWN_ATTR_MEDIA_MIMETYPE, ::cppu::UnoType<OUString>::get(), 0, 0},
{ OUString("FallbackGraphic"), OWN_ATTR_FALLBACK_GRAPHIC, cppu::UnoType<css::graphic::XGraphic>::get(), ::com::sun::star::beans::PropertyAttribute::READONLY, 0},
{ OUString(), 0, css::uno::Type(), 0, 0 }
};
......
......@@ -911,7 +911,8 @@ bool SvxMediaShape::getPropertyValueImpl( const OUString& rName, const SfxItemPr
(pProperty->nWID <= OWN_ATTR_MEDIA_ZOOM))
|| (pProperty->nWID == OWN_ATTR_MEDIA_STREAM)
|| (pProperty->nWID == OWN_ATTR_MEDIA_TEMPFILEURL)
|| (pProperty->nWID == OWN_ATTR_MEDIA_MIMETYPE))
|| (pProperty->nWID == OWN_ATTR_MEDIA_MIMETYPE)
|| (pProperty->nWID == OWN_ATTR_FALLBACK_GRAPHIC))
{
SdrMediaObj* pMedia = static_cast< SdrMediaObj* >( mpObj.get() );
const ::avmedia::MediaItem aItem( pMedia->getMediaProperties() );
......@@ -950,6 +951,10 @@ bool SvxMediaShape::getPropertyValueImpl( const OUString& rName, const SfxItemPr
rValue <<= aItem.getMimeType();
break;
case OWN_ATTR_FALLBACK_GRAPHIC:
rValue <<= pMedia->getSnapshot();
break;
default:
OSL_FAIL("SvxMediaShape::getPropertyValueImpl(), unknown property!");
}
......
......@@ -3154,8 +3154,10 @@ lcl_StoreMediaAndGetURL(SvXMLExport & rExport,
}
}
static void lcl_StoreJsonExternals(
SvXMLExport& rExport, const OUString& rURL)
static void lcl_StoreJsonExternalsAndFallback(
SvXMLExport& rExport,
const uno::Reference<beans::XPropertySet> xPropSet,
const OUString& rURL )
{
OUString sUrlPath;
if (rURL.startsWithIgnoreAsciiCase("vnd.sun.star.Package:", &sUrlPath))
......@@ -3184,20 +3186,57 @@ static void lcl_StoreJsonExternals(
xTarget->openStorageElement(sUrlPath.copy(0,sUrlPath.lastIndexOf("/")), embed::ElementModes::WRITE));
// Target of current model
const OUString sModelName = sUrlPath.copy(sUrlPath.lastIndexOf("/")+1);
const uno::Reference<embed::XStorage> xModelTarget(
xModelsTarget->openStorageElement(sUrlPath.copy(sUrlPath.lastIndexOf("/")+1), embed::ElementModes::WRITE));
xModelsTarget->openStorageElement(sModelName, embed::ElementModes::WRITE));
xModelStorage->copyToStorage(xModelTarget);
uno::Reference<embed::XTransactedObject> const xTransaction(xModelsTarget, uno::UNO_QUERY);
if (xTransaction.is())
/* Save the fallback image under the 'Model/Fallback/' folder
Place fallback image before the plugin tag otherwise older LO versions will parse an empty
plugin shape instead of the image. In current version this image will be ingored during import.*/
uno::Reference< graphic::XGraphic > xGraphic( xPropSet->getPropertyValue("FallbackGraphic"), uno::UNO_QUERY );
if( xGraphic.is() )
{
xTransaction->commit();
// Fallback storage
const uno::Reference<embed::XStorage> xFallbackTarget(
xModelsTarget->openStorageElement(OUString("Fallback"), embed::ElementModes::WRITE));
uno::Reference< io::XStream > xPictureStream(
xFallbackTarget->openStreamElement( sModelName + ".png", embed::ElementModes::WRITE ), uno::UNO_QUERY_THROW );
uno::Reference< graphic::XGraphicProvider > xProvider( graphic::GraphicProvider::create(comphelper::getProcessComponentContext()) );
uno::Sequence< beans::PropertyValue > aArgs( 2 );
aArgs[ 0 ].Name = "MimeType";
aArgs[ 0 ].Value <<= OUString( "image/png" );
aArgs[ 1 ].Name = "OutputStream";
aArgs[ 1 ].Value <<= xPictureStream->getOutputStream();
xProvider->storeGraphic( xGraphic, aArgs );
const uno::Reference<embed::XTransactedObject> xFallbackTransaction(xFallbackTarget, uno::UNO_QUERY);
if (xFallbackTransaction.is())
{
xFallbackTransaction->commit();
}
const OUString sFallbackURL( sUrlPath.copy(0,sUrlPath.lastIndexOf("/")) + "/Fallback/" + sModelName + ".png");
rExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, sFallbackURL );
rExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
rExport.AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
rExport.AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
SvXMLElementExport aImage( rExport, XML_NAMESPACE_DRAW, XML_IMAGE, false, true );
}
const uno::Reference<embed::XTransactedObject> xModelsTransaction(xModelsTarget, uno::UNO_QUERY);
if (xModelsTransaction.is())
{
xModelsTransaction->commit();
}
}
catch (uno::Exception const& e)
{
SAL_INFO("xmloff", "exception while storing embedded model: '" << e.Message << "'");
SAL_INFO("xmloff", "exception while saving embedded model: '" << e.Message << "'");
}
}
}
......@@ -3229,7 +3268,7 @@ void XMLShapeExport::ImpExportMediaShape(
OUString const persistentURL =
lcl_StoreMediaAndGetURL(GetExport(), xPropSet, aMediaURL, sMimeType);
if( sMimeType == "application/vnd.gltf+json" )
lcl_StoreJsonExternals(GetExport(), aMediaURL);
lcl_StoreJsonExternalsAndFallback(GetExport(), xPropSet, aMediaURL);
mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_HREF, persistentURL );
mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
......
......@@ -3056,6 +3056,7 @@ SdXMLPluginShapeContext::~SdXMLPluginShapeContext()
void SdXMLPluginShapeContext::StartElement( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList)
{
// watch for MimeType attribute to see if we have a media object
for( sal_Int16 n = 0, nAttrCount = ( xAttrList.is() ? xAttrList->getLength() : 0 ); n < nAttrCount; ++n )
{
......@@ -3583,6 +3584,18 @@ SvXMLImportContext *SdXMLFrameShapeContext::CreateChildContext( sal_uInt16 nPref
}
}
}
// For glTF models the fallback image is placed before the real shape.
// So we need to remove the fallback image after real shape is detected.
else if ( mxImplContext.Is() && IsXMLToken(mxImplContext->GetLocalName(), XML_IMAGE) &&
IsXMLToken( rLocalName, XML_PLUGIN ) )
{
SvXMLShapeContext* pShapeContext= GetImport().GetShapeImport()->CreateFrameChildContext(
GetImport(), nPrefix, rLocalName, xAttrList, mxShapes, mxAttrList );
pContext = pShapeContext;
if( pContext )
removeGraphicFromImportContext(*mxImplContext);
}
// call parent for content
if(!pContext)
......
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