diff options
author | Jan Holesovsky <kendy@collabora.com> | 2017-09-05 16:53:14 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2017-09-07 10:28:21 +0200 |
commit | 50f8e0e479e70fca3620da192e5a2cc4ca12bc2c (patch) | |
tree | 91fe75ed22a8df68251191e47d3091139edd0cdd /oox | |
parent | 7b65e7eea560da718c3cbc76a049a8d60b2809e9 (diff) |
tdf#106867: Export videos in PPTX.
Contains also:
tdf#106867: Implement pptx export of AnimationNodeType::COMMAND.
tdf#106867: Import target for commands in PPTX.
tdf#106867: Write also the extended markup to fully support embedded videos.
tdf#106867: Unit test for the export of embedded videos.
Change-Id: I7f4f389a72aa7ecef65d87f07bb69ba8f3374a14
Reviewed-on: https://gerrit.libreoffice.org/42017
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
Tested-by: Miklos Vajna <vmiklos@collabora.co.uk>
Diffstat (limited to 'oox')
-rw-r--r-- | oox/CppunitTest_oox_tokenmap.mk | 1 | ||||
-rw-r--r-- | oox/Library_oox.mk | 3 | ||||
-rw-r--r-- | oox/source/export/drawingml.cxx | 98 | ||||
-rw-r--r-- | oox/source/export/shapes.cxx | 42 | ||||
-rw-r--r-- | oox/source/ppt/timenode.cxx | 6 |
5 files changed, 141 insertions, 9 deletions
diff --git a/oox/CppunitTest_oox_tokenmap.mk b/oox/CppunitTest_oox_tokenmap.mk index 1e903a25a368..e71bcf6ba6bc 100644 --- a/oox/CppunitTest_oox_tokenmap.mk +++ b/oox/CppunitTest_oox_tokenmap.mk @@ -35,6 +35,7 @@ endif endif $(eval $(call gb_CppunitTest_use_libraries,oox_tokenmap,\ + avmedia \ basegfx \ comphelper \ cppu \ diff --git a/oox/Library_oox.mk b/oox/Library_oox.mk index fcd7215c23a4..e44015aaa595 100644 --- a/oox/Library_oox.mk +++ b/oox/Library_oox.mk @@ -38,6 +38,7 @@ $(eval $(call gb_Library_use_api,oox,\ )) $(eval $(call gb_Library_use_libraries,oox,\ + avmedia \ basegfx \ comphelper \ cppu \ @@ -47,7 +48,7 @@ $(eval $(call gb_Library_use_libraries,oox,\ drawinglayer \ msfilter \ sal \ - i18nlangtag \ + i18nlangtag \ sax \ sfx \ svl \ diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index bb90a48eb96d..3e9cc01e9ed7 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -41,6 +41,7 @@ #include <com/sun/star/beans/XPropertySetInfo.hpp> #include <com/sun/star/container/XEnumerationAccess.hpp> #include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/document/XStorageBasedDocument.hpp> #include <com/sun/star/drawing/BitmapMode.hpp> #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp> #include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp> @@ -56,6 +57,7 @@ #include <com/sun/star/drawing/TextVerticalAdjust.hpp> #include <com/sun/star/drawing/XShape.hpp> #include <com/sun/star/drawing/FillStyle.hpp> +#include <com/sun/star/embed/ElementModes.hpp> #include <com/sun/star/i18n/ScriptType.hpp> #include <com/sun/star/io/XOutputStream.hpp> #include <com/sun/star/style/LineSpacing.hpp> @@ -69,6 +71,8 @@ #include <com/sun/star/text/XTextField.hpp> #include <com/sun/star/text/XTextRange.hpp> #include <com/sun/star/style/CaseMap.hpp> + +#include <comphelper/storagehelper.hxx> #include <o3tl/any.hxx> #include <tools/stream.hxx> #include <unotools/fontdefs.hxx> @@ -87,6 +91,7 @@ #include <editeng/flditem.hxx> #include <svx/sdtfsitm.hxx> #include <svx/svdoashp.hxx> +#include <svx/svdomedia.hxx> #include <svx/unoapi.hxx> #include <svx/unoshape.hxx> @@ -944,6 +949,99 @@ OUString DrawingML::WriteImage( const Graphic& rGraphic , bool bRelPathToMedia ) return sRelId; } +void DrawingML::WriteMediaNonVisualProperties(const css::uno::Reference<css::drawing::XShape>& xShape) +{ + SdrMediaObj* pMediaObj = dynamic_cast<SdrMediaObj*>(GetSdrObjectFromXShape(xShape)); + if (!pMediaObj) + return; + + // extension + OUString aExtension; + const OUString& rURL(pMediaObj->getURL()); + int nLastDot = rURL.lastIndexOf('.'); + if (nLastDot >= 0) + aExtension = rURL.copy(nLastDot); + + bool bEmbed = rURL.startsWith("vnd.sun.star.Package:"); + + // mime type + OUString aMimeType(pMediaObj->getMediaProperties().getMimeType()); + if (aMimeType == "application/vnd.sun.star.media") + { + // try to set something better + // TODO fix the importer to actually set the mimetype on import + if (aExtension.equalsIgnoreAsciiCase(".avi")) + aMimeType = "video/x-msvideo"; + else if (aExtension.equalsIgnoreAsciiCase(".flv")) + aMimeType = "video/x-flv"; + else if (aExtension.equalsIgnoreAsciiCase(".mp4")) + aMimeType = "video/mp4"; + else if (aExtension.equalsIgnoreAsciiCase(".mov")) + aMimeType = "video/quicktime"; + else if (aExtension.equalsIgnoreAsciiCase(".ogv")) + aMimeType = "video/ogg"; + else if (aExtension.equalsIgnoreAsciiCase(".wmv")) + aMimeType = "video/x-ms-wmv"; + } + + OUString aVideoFileRelId; + OUString aMediaRelId; + + static const OUString aVideoRelationship("http://schemas.openxmlformats.org/officeDocument/2006/relationships/video"); + static const OUString aMediaRelationship("http://schemas.microsoft.com/office/2007/relationships/media"); + + if (bEmbed) + { + // copy the video stream + Reference<XOutputStream> xOutStream = mpFB->openFragmentStream(OUStringBuffer() + .appendAscii(GetComponentDir()) + .append("/media/media") + .append((sal_Int32) mnImageCounter) + .append(aExtension) + .makeStringAndClear(), + aMimeType); + + uno::Reference<io::XInputStream> xInputStream(pMediaObj->GetInputStream()); + comphelper::OStorageHelper::CopyInputToOutput(xInputStream, xOutStream); + + xOutStream->closeOutput(); + + // create the relation + OUString aPath = OUStringBuffer().appendAscii(GetRelationCompPrefix()) + .append("media/media") + .append((sal_Int32) mnImageCounter++) + .append(aExtension) + .makeStringAndClear(); + aVideoFileRelId = mpFB->addRelation(mpFS->getOutputStream(), aVideoRelationship, aPath); + aMediaRelId = mpFB->addRelation(mpFS->getOutputStream(), aMediaRelationship, aPath); + } + else + { + aVideoFileRelId = mpFB->addRelation(mpFS->getOutputStream(), aVideoRelationship, rURL); + aMediaRelId = mpFB->addRelation(mpFS->getOutputStream(), aMediaRelationship, rURL); + } + + GetFS()->startElementNS(XML_p, XML_nvPr, FSEND); + + GetFS()->singleElementNS(XML_a, XML_videoFile, + FSNS(XML_r, XML_link), USS(aVideoFileRelId), + FSEND); + + GetFS()->startElementNS(XML_p, XML_extLst, FSEND); + GetFS()->startElementNS(XML_p, XML_ext, + XML_uri, "{DAA4B4D4-6D71-4841-9C94-3DE7FCFB9230}", // media extensions; google this ID for details + FSEND); + + GetFS()->singleElementNS(XML_p14, XML_media, + bEmbed? FSNS(XML_r, XML_embed): FSNS(XML_r, XML_link), USS(aMediaRelId), + FSEND); + + GetFS()->endElementNS(XML_p, XML_ext); + GetFS()->endElementNS(XML_p, XML_extLst); + + GetFS()->endElementNS(XML_p, XML_nvPr); +} + OUString DrawingML::WriteBlip( const Reference< XPropertySet >& rXPropSet, const OUString& rURL, bool bRelPathToMedia, const Graphic *pGraphic ) { OUString sRelId; diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx index 3391ae3d1ec1..767328311a69 100644 --- a/oox/source/export/shapes.cxx +++ b/oox/source/export/shapes.cxx @@ -58,6 +58,7 @@ #include <com/sun/star/embed/XEmbeddedObject.hpp> #include <com/sun/star/embed/XEmbedPersist.hpp> #include <com/sun/star/frame/XStorable.hpp> +#include <com/sun/star/graphic/XGraphic.hpp> #include <com/sun/star/i18n/ScriptType.hpp> #include <com/sun/star/io/XOutputStream.hpp> #include <com/sun/star/style/ParagraphAdjust.hpp> @@ -77,6 +78,7 @@ #include <tools/stream.hxx> #include <tools/globname.hxx> #include <comphelper/classids.hxx> +#include <comphelper/sequence.hxx> #include <comphelper/storagehelper.hxx> #include <sot/exchange.hxx> #include <vcl/cvtgrf.hxx> @@ -1099,10 +1101,15 @@ void ShapeExport::WriteGraphicObjectShapePart( const Reference< XShape >& xShape SAL_INFO("oox.shape", "graphicObject without text"); OUString sGraphicURL; + OUString sMediaURL; Reference< XPropertySet > xShapeProps( xShape, UNO_QUERY ); - if( !pGraphic && ( !xShapeProps.is() || !( xShapeProps->getPropertyValue( "GraphicURL" ) >>= sGraphicURL ) ) ) + + bool bHasGraphicURL = xShapeProps.is() && xShapeProps->getPropertySetInfo()->hasPropertyByName("GraphicURL") && (xShapeProps->getPropertyValue("GraphicURL") >>= sGraphicURL); + bool bHasMediaURL = xShapeProps.is() && xShapeProps->getPropertySetInfo()->hasPropertyByName("MediaURL") && (xShapeProps->getPropertyValue("MediaURL") >>= sMediaURL); + + if (!pGraphic && !bHasGraphicURL && !bHasMediaURL) { - SAL_INFO("oox.shape", "no graphic URL found"); + SAL_INFO("oox.shape", "no graphic or media URL found"); return; } @@ -1125,26 +1132,48 @@ void ShapeExport::WriteGraphicObjectShapePart( const Reference< XShape >& xShape if ( ( bHaveDesc = GetProperty( xShapeProps, "Description" ) ) ) mAny >>= sDescr; - pFS->singleElementNS( mnXmlNamespace, XML_cNvPr, + pFS->startElementNS( mnXmlNamespace, XML_cNvPr, XML_id, I32S( GetNewShapeID( xShape ) ), XML_name, bHaveName ? USS( sName ) : OString( "Picture " + OString::number( mnPictureIdMax++ )).getStr(), XML_descr, bHaveDesc ? USS( sDescr ) : nullptr, FSEND ); + // OOXTODO: //cNvPr children: XML_extLst, XML_hlinkClick, XML_hlinkHover + if (bHasMediaURL) + pFS->singleElementNS(XML_a, XML_hlinkClick, + FSNS(XML_r, XML_id), "", + XML_action, "ppaction://media", + FSEND); + + pFS->endElementNS(mnXmlNamespace, XML_cNvPr); pFS->singleElementNS( mnXmlNamespace, XML_cNvPicPr, // OOXTODO: XML_preferRelativeSize FSEND ); - WriteNonVisualProperties( xShape ); + if (bHasMediaURL) + WriteMediaNonVisualProperties(xShape); + else + WriteNonVisualProperties(xShape); pFS->endElementNS( mnXmlNamespace, XML_nvPicPr ); pFS->startElementNS( mnXmlNamespace, XML_blipFill, FSEND ); - WriteBlip( xShapeProps, sGraphicURL, false, pGraphic ); + if (pGraphic || bHasGraphicURL) + WriteBlip(xShapeProps, sGraphicURL, false, pGraphic); + else if (bHasMediaURL) + { + Reference<graphic::XGraphic> rGraphic; + if (xShapeProps->getPropertySetInfo()->hasPropertyByName("FallbackGraphic")) + xShapeProps->getPropertyValue("FallbackGraphic") >>= rGraphic; + + Graphic aGraphic(rGraphic); + WriteBlip(xShapeProps, sMediaURL, false, &aGraphic); + } - WriteSrcRect( xShapeProps, sGraphicURL ); + if (bHasGraphicURL) + WriteSrcRect(xShapeProps, sGraphicURL); // now we stretch always when we get pGraphic (when changing that // behavior, test n#780830 for regression, where the OLE sheet might get tiled @@ -1420,6 +1449,7 @@ static const NameToConvertMapType& lcl_GetConverters() shape_converters[ "com.sun.star.drawing.GroupShape" ] = &ShapeExport::WriteGroupShape; shape_converters[ "com.sun.star.presentation.GraphicObjectShape" ] = &ShapeExport::WriteGraphicObjectShape; + shape_converters[ "com.sun.star.presentation.MediaShape" ] = &ShapeExport::WriteGraphicObjectShape; shape_converters[ "com.sun.star.presentation.OLE2Shape" ] = &ShapeExport::WriteOLE2Shape; shape_converters[ "com.sun.star.presentation.TableShape" ] = &ShapeExport::WriteTableShape; shape_converters[ "com.sun.star.presentation.TextShape" ] = &ShapeExport::WriteTextShape; diff --git a/oox/source/ppt/timenode.cxx b/oox/source/ppt/timenode.cxx index 2e5a02e9fabd..321a4c9297ec 100644 --- a/oox/source/ppt/timenode.cxx +++ b/oox/source/ppt/timenode.cxx @@ -313,8 +313,10 @@ namespace oox { namespace ppt { xAnimate->setBy( aValue ); break; case NP_TARGET: - if( xAnimate.is() ) - xAnimate->setTarget( aValue ); + if (xAnimate.is()) + xAnimate->setTarget(aValue); + if (xCommand.is()) + xCommand->setTarget(aValue); break; case NP_SUBITEM: if( xAnimate.is() ) |