summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
authorJan Holesovsky <kendy@collabora.com>2017-09-05 16:53:14 +0200
committerMiklos Vajna <vmiklos@collabora.co.uk>2017-09-07 10:28:21 +0200
commit50f8e0e479e70fca3620da192e5a2cc4ca12bc2c (patch)
tree91fe75ed22a8df68251191e47d3091139edd0cdd /oox
parent7b65e7eea560da718c3cbc76a049a8d60b2809e9 (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.mk1
-rw-r--r--oox/Library_oox.mk3
-rw-r--r--oox/source/export/drawingml.cxx98
-rw-r--r--oox/source/export/shapes.cxx42
-rw-r--r--oox/source/ppt/timenode.cxx6
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() )