summaryrefslogtreecommitdiff
path: root/sd
diff options
context:
space:
mode:
authorMark Hung <marklh9@gmail.com>2019-04-27 19:02:25 +0800
committerMark Hung <marklh9@gmail.com>2019-04-30 15:03:19 +0200
commitb593634d3cfbb2fc8522d99ce1c3f2a11445ea59 (patch)
tree290fea894a03fd9779b064dd7c5ec04b5b120a35 /sd
parent83abdf803a023067ebc207fd82dde987df233754 (diff)
tdf#124230 pptx: make exported animation sound work.
1. Fix target path for the embedded media. Move the media file to /ppt/media ( was /media ) and use the relative path ../media for the target path when adding the relation. This is necessary for MSO to play the sound. 2. Write timenode id for the start or end conditions if the animation node for the begin event or the end event is available. Events like BEGIN or END has to refer a timenode. Without specifying referred timenode in start and end condition, Impress will not activate the audio node after importing the document. Change-Id: I6027be2e836e2f86061e401c8af806b2b1993a49 Reviewed-on: https://gerrit.libreoffice.org/71427 Tested-by: Jenkins Reviewed-by: Mark Hung <marklh9@gmail.com>
Diffstat (limited to 'sd')
-rw-r--r--sd/qa/unit/export-tests-ooxml2.cxx15
-rw-r--r--sd/source/filter/eppt/pptx-animations.cxx39
-rw-r--r--sd/source/filter/eppt/pptx-epptooxml.cxx5
3 files changed, 50 insertions, 9 deletions
diff --git a/sd/qa/unit/export-tests-ooxml2.cxx b/sd/qa/unit/export-tests-ooxml2.cxx
index 7c27e0a315cc..66c6154f1da2 100644
--- a/sd/qa/unit/export-tests-ooxml2.cxx
+++ b/sd/qa/unit/export-tests-ooxml2.cxx
@@ -2087,31 +2087,38 @@ void SdOOXMLExportTest2::testTdf44223()
= loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf44223.pptx"), PPTX);
xDocShRef = saveAndReload(xDocShRef.get(), PPTX, &tempFile);
- std::shared_ptr<SvStream> const pStream1(parseExportStream(tempFile, "media/audio1.wav"));
+ std::shared_ptr<SvStream> const pStream1(parseExportStream(tempFile, "ppt/media/audio1.wav"));
CPPUNIT_ASSERT_EQUAL(sal_uInt64(11140), pStream1->remainingSize());
- std::shared_ptr<SvStream> const pStream2(parseExportStream(tempFile, "media/audio2.wav"));
+ std::shared_ptr<SvStream> const pStream2(parseExportStream(tempFile, "ppt/media/audio2.wav"));
CPPUNIT_ASSERT_EQUAL(sal_uInt64(28074), pStream2->remainingSize());
xmlDocPtr pXmlContentType = parseExport(tempFile, "[Content_Types].xml");
assertXPath(pXmlContentType,
- "/ContentType:Types/ContentType:Override[@PartName='/media/audio1.wav']",
+ "/ContentType:Types/ContentType:Override[@PartName='/ppt/media/audio1.wav']",
"ContentType",
"audio/x-wav");
assertXPath(pXmlContentType,
- "/ContentType:Types/ContentType:Override[@PartName='/media/audio2.wav']",
+ "/ContentType:Types/ContentType:Override[@PartName='/ppt/media/audio2.wav']",
"ContentType",
"audio/x-wav");
xmlDocPtr pDoc1 = parseExport(tempFile, "ppt/slides/slide1.xml");
+ // Start condition: 0s after timenode id 5 begins.
assertXPath(pDoc1 , "//p:audio/p:cMediaNode/p:cTn/p:stCondLst/p:cond", "evt", "begin");
assertXPath(pDoc1 , "//p:audio/p:cMediaNode/p:cTn/p:stCondLst/p:cond", "delay", "0");
+ assertXPath(pDoc1 , "//p:audio/p:cMediaNode/p:cTn/p:stCondLst/p:cond/p:tn", "val", "5");
xmlDocPtr pDoc2 = parseExport(tempFile, "ppt/slides/slide2.xml");
assertXPath(pDoc2 , "//p:transition/p:sndAc/p:stSnd/p:snd[@r:embed]", 2);
+ xmlDocPtr pRels1 = parseExport(tempFile, "ppt/slides/_rels/slide1.xml.rels");
+ assertXPath(pRels1, "//rels:Relationship[@Id='rId1']", "Type",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/audio");
+ assertXPath(pRels1, "//rels:Relationship[@Id='rId1']", "Target", "../media/audio1.wav");
+
xDocShRef->DoClose();
}
diff --git a/sd/source/filter/eppt/pptx-animations.cxx b/sd/source/filter/eppt/pptx-animations.cxx
index a8c062b5c7df..da5223c50ec7 100644
--- a/sd/source/filter/eppt/pptx-animations.cxx
+++ b/sd/source/filter/eppt/pptx-animations.cxx
@@ -59,6 +59,7 @@
#include "pptexanimations.hxx"
#include "pptx-animations.hxx"
#include "../ppt/pptanimations.hxx"
+#include <comphelper/stl_types.hxx>
using namespace ::com::sun::star::animations;
using namespace ::com::sun::star::container;
@@ -569,6 +570,7 @@ struct Cond
OString msDelay;
const char* mpEvent;
Reference<XShape> mxShape;
+ Reference<XAnimationNode> mxNode;
Cond(const Any& rAny, bool bIsMainSeqChild);
@@ -596,7 +598,8 @@ Cond::Cond(const Any& rAny, bool bIsMainSeqChild)
else
{
mpEvent = convertEventTrigger(aEvent.Trigger);
- aEvent.Source >>= mxShape;
+ if (!(aEvent.Source >>= mxShape))
+ aEvent.Source >>= mxNode;
if (aEvent.Offset >>= fDelay)
bHasFDelay = true;
@@ -632,6 +635,11 @@ class PPTXAnimationExport
const FSHelperPtr& mpFS;
const NodeContext* mpContext;
+ std::map<Reference<XAnimationNode>, sal_Int32, ::comphelper::OInterfaceCompare<XAnimationNode>>
+ maAnimationNodeIdMap;
+ sal_Int32 GetNextAnimationNodeId(const Reference<XAnimationNode>& rNode);
+ sal_Int32 GetAnimationNodeId(const Reference<XAnimationNode>& rNode);
+
public:
PPTXAnimationExport(PowerPointExport& rExport, const FSHelperPtr& pFS);
void WriteAnimations(const Reference<XDrawPage>& rXDrawPage);
@@ -751,6 +759,7 @@ void PPTXAnimationExport::WriteAnimationCondList(const Any& rAny, sal_Int32 nTok
void PPTXAnimationExport::WriteAnimationCond(const Cond& rCond)
{
+ sal_Int32 nId = -1;
if (rCond.mpEvent)
{
if (rCond.mxShape.is())
@@ -760,6 +769,13 @@ void PPTXAnimationExport::WriteAnimationCond(const Cond& rCond)
WriteAnimationTarget(makeAny(rCond.mxShape));
mpFS->endElementNS(XML_p, XML_cond);
}
+ else if (rCond.mxNode.is() && (nId = GetAnimationNodeId(rCond.mxNode)) != -1)
+ {
+ mpFS->startElementNS(XML_p, XML_cond, XML_delay, rCond.getDelay(), XML_evt,
+ rCond.mpEvent);
+ mpFS->singleElementNS(XML_p, XML_tn, XML_val, OString::number(nId));
+ mpFS->endElementNS(XML_p, XML_cond);
+ }
else
{
mpFS->singleElementNS(XML_p, XML_cond, XML_delay, rCond.getDelay(), XML_evt,
@@ -1041,8 +1057,7 @@ void PPTXAnimationExport::WriteAnimationNodeCommonPropsStart()
bool bAutoReverse = rXNode->getAutoReverse();
mpFS->startElementNS(
- XML_p, XML_cTn, XML_id, OString::number(mrPowerPointExport.GetNextAnimationNodeID()),
- XML_dur,
+ XML_p, XML_cTn, XML_id, OString::number(GetNextAnimationNodeId(rXNode)), XML_dur,
fDuration != 0 ? OString::number(static_cast<sal_Int32>(fDuration * 1000.0)).getStr()
: pDuration,
XML_autoRev, bAutoReverse ? "1" : nullptr, XML_restart, pRestart, XML_nodeType, pNodeType,
@@ -1261,6 +1276,24 @@ void PPTXAnimationExport::WriteAnimations(const Reference<XDrawPage>& rXDrawPage
}
}
+sal_Int32 PPTXAnimationExport::GetNextAnimationNodeId(const Reference<XAnimationNode>& xNode)
+{
+ sal_Int32 nId = mrPowerPointExport.GetNextAnimationNodeID();
+ maAnimationNodeIdMap[xNode] = nId;
+ return nId;
+}
+
+sal_Int32 PPTXAnimationExport::GetAnimationNodeId(const Reference<XAnimationNode>& xNode)
+{
+ sal_Int32 nId = -1;
+ const auto& aIter = maAnimationNodeIdMap.find(xNode);
+ if (aIter != maAnimationNodeIdMap.end())
+ {
+ nId = aIter->second;
+ }
+ return nId;
+}
+
NodeContext::NodeContext(const Reference<XAnimationNode>& xNode, bool bMainSeqChild,
bool bIsIterateChild)
: mxNode(xNode)
diff --git a/sd/source/filter/eppt/pptx-epptooxml.cxx b/sd/source/filter/eppt/pptx-epptooxml.cxx
index abe09c4a8964..a7d51cfcd57e 100644
--- a/sd/source/filter/eppt/pptx-epptooxml.cxx
+++ b/sd/source/filter/eppt/pptx-epptooxml.cxx
@@ -1971,14 +1971,15 @@ void PowerPointExport::embedEffectAudio(const FSHelperPtr& pFS, const OUString&
int nLastSlash = sUrl.lastIndexOf('/');
sName = sUrl.copy(nLastSlash >= 0 ? nLastSlash + 1 : 0);
- OUString sPath = OUStringBuffer().append("/media/")
+ OUString sPath = OUStringBuffer().append("../media/")
.append(sName)
.makeStringAndClear();
sRelId = addRelation(pFS->getOutputStream(),
oox::getRelationship(Relationship::AUDIO), sPath);
- uno::Reference<io::XOutputStream> xOutputStream = openFragmentStream(sPath, "audio/x-wav");
+ uno::Reference<io::XOutputStream> xOutputStream = openFragmentStream(sPath.replaceAt(0, 2, "/ppt"),
+ "audio/x-wav");
comphelper::OStorageHelper::CopyInputToOutput(xAudioStream, xOutputStream);
}