22#include <oox/token/tokens.hxx>
26#include <rtl/math.hxx>
29#include <com/sun/star/animations/AnimationAdditiveMode.hpp>
30#include <com/sun/star/animations/AnimationCalcMode.hpp>
31#include <com/sun/star/animations/AnimationFill.hpp>
32#include <com/sun/star/animations/AnimationNodeType.hpp>
33#include <com/sun/star/animations/AnimationRestart.hpp>
34#include <com/sun/star/animations/AnimationTransformType.hpp>
35#include <com/sun/star/animations/AnimationValueType.hpp>
36#include <com/sun/star/animations/AnimationColorSpace.hpp>
37#include <com/sun/star/animations/Timing.hpp>
38#include <com/sun/star/animations/ValuePair.hpp>
39#include <com/sun/star/animations/XAnimateMotion.hpp>
40#include <com/sun/star/animations/XAnimateTransform.hpp>
41#include <com/sun/star/animations/XAnimationNode.hpp>
42#include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
43#include <com/sun/star/animations/XAnimateColor.hpp>
44#include <com/sun/star/animations/XCommand.hpp>
45#include <com/sun/star/animations/XAudio.hpp>
46#include <com/sun/star/animations/XTransitionFilter.hpp>
47#include <com/sun/star/animations/XIterateContainer.hpp>
48#include <com/sun/star/container/XEnumerationAccess.hpp>
49#include <com/sun/star/presentation/EffectCommands.hpp>
50#include <com/sun/star/presentation/EffectNodeType.hpp>
51#include <com/sun/star/presentation/EffectPresetClass.hpp>
52#include <com/sun/star/presentation/ParagraphTarget.hpp>
53#include <com/sun/star/presentation/TextAnimationType.hpp>
54#include <com/sun/star/text/XSimpleText.hpp>
55#include <com/sun/star/drawing/XShape.hpp>
56#include <com/sun/star/beans/XPropertySet.hpp>
76using ::com::sun::star::beans::NamedValue;
77using ::com::sun::star::drawing::XDrawPage;
78using ::com::sun::star::drawing::XShape;
79using ::com::sun::star::text::XSimpleText;
80using ::sax_fastparser::FSHelperPtr;
84void WriteAnimationProperty(
const FSHelperPtr& pFS,
const Any& rAny, sal_Int32 nToken = 0)
94 if ((aPair.First >>= x) && (aPair.Second >>= y))
102 pFS->singleElementNS(XML_p, nToken, XML_x, OString::number(x * 100000), XML_y,
103 OString::number(y * 100000));
111 TypeClass aClass = rAny.getValueType().getTypeClass();
114 && (aClass == TypeClass_LONG || aClass == TypeClass_DOUBLE || aClass == TypeClass_STRING);
117 pFS->startElementNS(XML_p, nToken);
119 switch (rAny.getValueType().getTypeClass())
122 if (!(rAny >>= nRgb))
126 pFS->singleElementNS(XML_a, XML_srgbClr, XML_val,
I32SHEX(nRgb));
128 case TypeClass_DOUBLE:
129 if (!(rAny >>= fDouble))
133 pFS->singleElementNS(XML_p, XML_fltVal, XML_val, OString::number(fDouble));
135 case TypeClass_STRING:
136 pFS->singleElementNS(XML_p, XML_strVal, XML_val, *o3tl::doAccess<OUString>(rAny));
143 pFS->endElementNS(XML_p, nToken);
146void WriteAnimateColorColor(
const FSHelperPtr& pFS,
const Any& rAny, sal_Int32 nToken)
148 if (!rAny.hasValue())
151 sal_Int32 nColor = 0;
154 pFS->startElementNS(XML_p, nToken);
156 if (nToken == XML_by)
159 SAL_WARN(
"sd.eppt",
"Export p:rgb in p:by of animClr isn't implemented yet.");
164 pFS->singleElementNS(XML_a, XML_srgbClr, XML_val,
I32SHEX(nColor));
167 pFS->endElementNS(XML_p, nToken);
170 Sequence<double> aHSL(3);
171 if (!(rAny >>= aHSL))
174 pFS->startElementNS(XML_p, nToken);
176 if (nToken == XML_by)
179 pFS->singleElementNS(XML_p, XML_hsl, XML_h, OString::number(aHSL[0] * 60000),
180 XML_s, OString::number(aHSL[1] * 100000), XML_l,
181 OString::number(aHSL[2] * 100000));
186 SAL_WARN(
"sd.eppt",
"Export p:hsl in p:from or p:to of animClr isn't implemented yet.");
189 pFS->endElementNS(XML_p, nToken);
192void WriteAnimateTo(
const FSHelperPtr& pFS,
const Any& rValue,
const OUString& rAttributeName)
194 if (!rValue.hasValue())
197 SAL_INFO(
"sd.eppt",
"to attribute name: " << rAttributeName.toUtf8());
199 WriteAnimationProperty(pFS, AnimationExporter::convertAnimateValue(rValue, rAttributeName),
203void WriteAnimateValues(
const FSHelperPtr& pFS,
const Reference<XAnimate>& rXAnimate)
205 const Sequence<double> aKeyTimes = rXAnimate->getKeyTimes();
206 if (!aKeyTimes.hasElements())
208 const Sequence<Any> aValues = rXAnimate->getValues();
209 const OUString&
sFormula = rXAnimate->getFormula();
210 const OUString& rAttributeName = rXAnimate->getAttributeName();
214 assert(aValues.getLength() == aKeyTimes.getLength());
216 pFS->startElementNS(XML_p, XML_tavLst);
218 for (
int i = 0;
i < aKeyTimes.getLength();
i++)
220 SAL_INFO(
"sd.eppt",
"animate value " << i <<
": " << aKeyTimes[i]);
221 if (aValues[i].hasValue())
223 pFS->startElementNS(XML_p, XML_tav, XML_fmla,
225 OString::number(
static_cast<sal_Int32
>(aKeyTimes[i] * 100000.0)));
226 pFS->startElementNS(XML_p, XML_val);
228 if (aValues[i] >>= aPair)
230 WriteAnimationProperty(
231 pFS, AnimationExporter::convertAnimateValue(aPair.First, rAttributeName));
232 WriteAnimationProperty(
233 pFS, AnimationExporter::convertAnimateValue(aPair.Second, rAttributeName));
236 WriteAnimationProperty(
237 pFS, AnimationExporter::convertAnimateValue(aValues[i], rAttributeName));
239 pFS->endElementNS(XML_p, XML_val);
240 pFS->endElementNS(XML_p, XML_tav);
244 pFS->endElementNS(XML_p, XML_tavLst);
248void WriteAnimationCondListForSeq(
const FSHelperPtr& pFS, sal_Int32 nToken)
250 const char* pEvent = (
nToken == XML_prevCondLst) ?
"onPrev" :
"onNext";
252 pFS->startElementNS(XML_p, nToken);
253 pFS->startElementNS(XML_p, XML_cond, XML_evt, pEvent);
254 pFS->startElementNS(XML_p, XML_tgtEl);
255 pFS->singleElementNS(XML_p, XML_sldTgt);
256 pFS->endElementNS(XML_p, XML_tgtEl);
257 pFS->endElementNS(XML_p, XML_cond);
258 pFS->endElementNS(XML_p, nToken);
261void WriteAnimationAttributeName(
const FSHelperPtr& pFS,
const OUString& rAttributeName)
263 if (rAttributeName.isEmpty())
266 pFS->startElementNS(XML_p, XML_attrNameLst);
268 SAL_INFO(
"sd.eppt",
"write attribute name: " << rAttributeName.toUtf8());
270 if (rAttributeName ==
"X;Y")
272 pFS->startElementNS(XML_p, XML_attrName);
273 pFS->writeEscaped(
"ppt_x");
274 pFS->endElementNS(XML_p, XML_attrName);
276 pFS->startElementNS(XML_p, XML_attrName);
277 pFS->writeEscaped(
"ppt_y");
278 pFS->endElementNS(XML_p, XML_attrName);
284 const char* pAttribute =
nullptr;
288 if (rAttributeName.equalsAscii(attrConv->
mpAPIName))
298 pFS->startElementNS(XML_p, XML_attrName);
299 pFS->writeEscaped(pAttribute);
300 pFS->endElementNS(XML_p, XML_attrName);
304 SAL_WARN(
"sd.eppt",
"unhandled animation attribute name: " << rAttributeName);
308 pFS->endElementNS(XML_p, XML_attrNameLst);
312sal_Int32 extractNodeType(
const Reference<XAnimationNode>& rXNode)
314 sal_Int16
nType = rXNode->getType();
315 sal_Int32 xmlNodeType = -1;
318 case AnimationNodeType::ITERATE:
319 case AnimationNodeType::PAR:
320 xmlNodeType = XML_par;
322 case AnimationNodeType::SEQ:
323 xmlNodeType = XML_seq;
325 case AnimationNodeType::ANIMATE:
326 xmlNodeType = XML_anim;
328 case AnimationNodeType::ANIMATEMOTION:
329 xmlNodeType = XML_animMotion;
331 case AnimationNodeType::ANIMATETRANSFORM:
333 Reference<XAnimateTransform> xTransform(rXNode, UNO_QUERY);
336 if (xTransform->getTransformType() == AnimationTransformType::SCALE)
337 xmlNodeType = XML_animScale;
338 else if (xTransform->getTransformType() == AnimationTransformType::ROTATE)
339 xmlNodeType = XML_animRot;
343 case AnimationNodeType::ANIMATECOLOR:
344 xmlNodeType = XML_animClr;
346 case AnimationNodeType::SET:
347 xmlNodeType = XML_set;
349 case AnimationNodeType::TRANSITIONFILTER:
350 xmlNodeType = XML_animEffect;
352 case AnimationNodeType::COMMAND:
353 xmlNodeType = XML_cmd;
355 case AnimationNodeType::AUDIO:
356 xmlNodeType = XML_audio;
359 SAL_WARN(
"sd.eppt",
"unhandled animation node: " << nType);
366const char* convertAnimationRestart(sal_Int16 nRestart)
368 const char* pRestart =
nullptr;
371 case AnimationRestart::ALWAYS:
374 case AnimationRestart::WHEN_NOT_ACTIVE:
375 pRestart =
"whenNotActive";
377 case AnimationRestart::NEVER:
385const char* convertEffectNodeType(sal_Int16 nType)
387 const char* pNodeType =
nullptr;
390 case EffectNodeType::TIMING_ROOT:
391 pNodeType =
"tmRoot";
393 case EffectNodeType::MAIN_SEQUENCE:
394 pNodeType =
"mainSeq";
396 case EffectNodeType::ON_CLICK:
397 pNodeType =
"clickEffect";
399 case EffectNodeType::AFTER_PREVIOUS:
400 pNodeType =
"afterEffect";
402 case EffectNodeType::WITH_PREVIOUS:
403 pNodeType =
"withEffect";
405 case EffectNodeType::INTERACTIVE_SEQUENCE:
406 pNodeType =
"interactiveSeq";
413const char* convertEffectPresetClass(sal_Int16 nPresetClass)
415 const char* pPresetClass =
nullptr;
416 switch (nPresetClass)
418 case EffectPresetClass::ENTRANCE:
419 pPresetClass =
"entr";
421 case EffectPresetClass::EXIT:
422 pPresetClass =
"exit";
424 case EffectPresetClass::EMPHASIS:
425 pPresetClass =
"emph";
427 case EffectPresetClass::MOTIONPATH:
428 pPresetClass =
"path";
430 case EffectPresetClass::OLEACTION:
431 pPresetClass =
"verb";
433 case EffectPresetClass::MEDIACALL:
434 pPresetClass =
"mediacall";
441const char* convertAnimationFill(sal_Int16 nFill)
443 const char* pFill =
nullptr;
446 case AnimationFill::FREEZE:
449 case AnimationFill::HOLD:
452 case AnimationFill::REMOVE:
455 case AnimationFill::TRANSITION:
456 pFill =
"transition";
463const char* convertTextAnimationType(sal_Int16 nType)
465 const char*
sType =
nullptr;
468 case TextAnimationType::BY_PARAGRAPH:
471 case TextAnimationType::BY_LETTER:
474 case TextAnimationType::BY_WORD:
482class PPTXAnimationExport
485 void WriteAnimationNodeAnimate(sal_Int32 nXmlNodeType);
486 void WriteAnimationNodeAnimateInside(
bool bSimple,
bool bWriteTo =
true);
487 void WriteAnimationNodeSeq();
488 void WriteAnimationNodeEffect();
489 void WriteAnimationNodeCommand();
491 void WriteAnimationNodeMedia();
492 void WriteAnimationNodeCommonPropsStart();
493 void WriteAnimationTarget(
const Any& rTarget);
494 void WriteAnimationCondList(
const std::vector<Cond>& rList, sal_Int32 nToken);
495 void WriteAnimationCond(
const Cond& rCond);
496 const Reference<XAnimationNode>& getCurrentNode()
const;
502 std::map<Reference<XAnimationNode>, sal_Int32> maAnimationNodeIdMap;
503 sal_Int32 GetNextAnimationNodeId(
const Reference<XAnimationNode>& rNode);
504 sal_Int32 GetAnimationNodeId(
const Reference<XAnimationNode>& rNode);
512bool IsAudioURL(std::u16string_view rURL)
527 PPTXAnimationExport aAnimationExport(rExport, pFS);
528 aAnimationExport.WriteAnimations(rXDrawPage);
533 : mrPowerPointExport(rExport)
539const Reference<XAnimationNode>& PPTXAnimationExport::getCurrentNode()
const
545void PPTXAnimationExport::WriteAnimationTarget(
const Any& rTarget)
547 sal_Int32 nParagraph = -1;
548 bool bParagraphTarget =
false;
550 Reference<XShape> rXShape;
555 ParagraphTarget aParagraphTarget;
556 if (rTarget >>= aParagraphTarget)
557 rXShape = aParagraphTarget.Shape;
560 nParagraph =
static_cast<sal_Int32
>(aParagraphTarget.Paragraph);
561 Reference<XSimpleText> xText(rXShape, UNO_QUERY);
564 bParagraphTarget =
true;
572 sal_Int32 nShapeID = mrPowerPointExport.GetShapeID(rXShape);
574 mpFS->startElementNS(XML_p, XML_tgtEl);
575 mpFS->startElementNS(XML_p, XML_spTgt, XML_spid, OString::number(nShapeID));
576 if (bParagraphTarget)
578 mpFS->startElementNS(XML_p, XML_txEl);
579 mpFS->singleElementNS(XML_p, XML_pRg, XML_st, OString::number(nParagraph), XML_end,
580 OString::number(nParagraph));
581 mpFS->endElementNS(XML_p, XML_txEl);
583 mpFS->endElementNS(XML_p, XML_spTgt);
584 mpFS->endElementNS(XML_p, XML_tgtEl);
587void PPTXAnimationExport::WriteAnimationCondList(
const std::vector<Cond>& rList, sal_Int32 nToken)
589 if (rList.size() > 0)
591 mpFS->startElementNS(XML_p, nToken);
593 for (
const Cond& rCond : rList)
594 WriteAnimationCond(rCond);
596 mpFS->endElementNS(XML_p, nToken);
600void PPTXAnimationExport::WriteAnimationCond(
const Cond& rCond)
607 mpFS->startElementNS(XML_p, XML_cond, XML_delay, rCond.
getDelay(), XML_evt,
610 mpFS->endElementNS(XML_p, XML_cond);
612 else if (rCond.
mxNode.is() && (nId = GetAnimationNodeId(rCond.
mxNode)) != -1)
614 mpFS->startElementNS(XML_p, XML_cond, XML_delay, rCond.
getDelay(), XML_evt,
616 mpFS->singleElementNS(XML_p, XML_tn, XML_val, OString::number(nId));
617 mpFS->endElementNS(XML_p, XML_cond);
621 mpFS->singleElementNS(XML_p, XML_cond, XML_delay, rCond.
getDelay(), XML_evt,
626 mpFS->singleElementNS(XML_p, XML_cond, XML_delay, rCond.
getDelay());
629void PPTXAnimationExport::WriteAnimationNodeAnimate(sal_Int32 nXmlNodeType)
631 const Reference<XAnimationNode>& rXNode = getCurrentNode();
632 Reference<XAnimate> rXAnimate(rXNode, UNO_QUERY);
636 const char* pCalcMode =
nullptr;
637 const char* pValueType =
nullptr;
638 bool bSimple = (nXmlNodeType != XML_anim);
643 switch (rXAnimate->getCalcMode())
645 case AnimationCalcMode::DISCRETE:
646 pCalcMode =
"discrete";
648 case AnimationCalcMode::LINEAR:
653 switch (AnimationExporter::GetValueTypeForAttributeName(rXAnimate->getAttributeName()))
655 case AnimationValueType::STRING:
658 case AnimationValueType::NUMBER:
661 case AnimationValueType::COLOR:
667 if (nXmlNodeType == XML_animMotion)
670 Reference<XAnimateMotion> xMotion(rXNode, UNO_QUERY);
673 xMotion->getPath() >>= aPath;
675 if (::basegfx::utils::importFromSvgD(aPolyPoly, aPath,
true,
nullptr))
676 aPath = ::basegfx::utils::exportToSvgD(aPolyPoly,
false,
false,
true,
true);
679 mpFS->startElementNS(XML_p, nXmlNodeType, XML_origin,
"layout", XML_path, aPath);
681 else if (nXmlNodeType == XML_animRot)
684 const char* pBy =
nullptr;
685 const char* pFrom =
nullptr;
686 const char* pTo =
nullptr;
689 Reference<XAnimateTransform> xTransform(rXNode, UNO_QUERY);
693 if (xTransform->getBy() >>= value)
695 aBy = OString::number(
static_cast<int>(value * PER_DEGREE));
699 if (xTransform->getFrom() >>= value)
701 aFrom = OString::number(
static_cast<int>(value * PER_DEGREE));
702 pFrom =
aFrom.getStr();
705 if (xTransform->getTo() >>= value)
707 aTo = OString::number(
static_cast<int>(value * PER_DEGREE));
712 mpFS->startElementNS(XML_p, nXmlNodeType, XML_by, pBy, XML_from, pFrom, XML_to, pTo);
714 else if (nXmlNodeType == XML_animClr)
716 Reference<XAnimateColor> xColor(rXNode, UNO_QUERY);
717 const char* pColorSpace =
"rgb";
718 const char* pDirection =
nullptr;
719 if (xColor.is() && xColor->getColorInterpolation() == AnimationColorSpace::HSL)
723 pDirection = xColor->getDirection() ?
"cw" :
"ccw";
725 mpFS->startElementNS(XML_p, nXmlNodeType, XML_clrSpc, pColorSpace, XML_dir, pDirection,
726 XML_calcmode, pCalcMode, XML_valueType, pValueType);
730 OUString sFrom, sTo, sBy;
731 if (rXAnimate.is() && nXmlNodeType == XML_anim)
733 OUString sAttributeName = rXAnimate->getAttributeName();
735 = AnimationExporter::convertAnimateValue(rXAnimate->getFrom(), sAttributeName);
737 Any aTo = AnimationExporter::convertAnimateValue(rXAnimate->getTo(), sAttributeName);
739 Any aBy = AnimationExporter::convertAnimateValue(rXAnimate->getBy(), sAttributeName);
743 mpFS->startElementNS(XML_p, nXmlNodeType, XML_calcmode, pCalcMode, XML_valueType,
747 bTo = sTo.isEmpty() && sFrom.isEmpty() && sBy.isEmpty();
750 WriteAnimationNodeAnimateInside(bSimple, bTo);
751 mpFS->endElementNS(XML_p, nXmlNodeType);
754void PPTXAnimationExport::WriteAnimationNodeAnimateInside(
bool bSimple,
bool bWriteTo)
756 const Reference<XAnimationNode>& rXNode = getCurrentNode();
757 Reference<XAnimate> rXAnimate(rXNode, UNO_QUERY);
761 const char* pAdditive =
nullptr;
765 switch (rXAnimate->getAdditive())
767 case AnimationAdditiveMode::BASE:
770 case AnimationAdditiveMode::SUM:
773 case AnimationAdditiveMode::REPLACE:
776 case AnimationAdditiveMode::MULTIPLY:
779 case AnimationAdditiveMode::NONE:
785 mpFS->startElementNS(XML_p, XML_cBhvr, XML_additive, pAdditive);
786 WriteAnimationNodeCommonPropsStart();
788 Reference<XIterateContainer> xIterate(rXNode->getParent(), UNO_QUERY);
789 WriteAnimationTarget(xIterate.is() ? xIterate->getTarget() : rXAnimate->getTarget());
791 Reference<XAnimateTransform> xTransform(rXNode, UNO_QUERY);
795 if (xTransform.is() && xTransform->getTransformType() == AnimationTransformType::ROTATE)
798 WriteAnimationAttributeName(mpFS, xTransform.is() ? sNewAttr : rXAnimate->getAttributeName());
800 mpFS->endElementNS(XML_p, XML_cBhvr);
801 WriteAnimateValues(mpFS, rXAnimate);
803 Reference<XAnimateColor> xColor(rXNode, UNO_QUERY);
807 WriteAnimateColorColor(mpFS, xColor->getBy(), XML_by);
808 WriteAnimateColorColor(mpFS, xColor->getFrom(), XML_from);
809 WriteAnimateColorColor(mpFS, xColor->getTo(), XML_to);
811 else if (xTransform.is() && xTransform->getTransformType() == AnimationTransformType::SCALE)
813 WriteAnimationProperty(mpFS, rXAnimate->getBy(), XML_by);
814 WriteAnimationProperty(mpFS, rXAnimate->getFrom(), XML_from);
815 WriteAnimationProperty(mpFS, rXAnimate->getTo(), XML_to);
818 WriteAnimateTo(mpFS, rXAnimate->getTo(), rXAnimate->getAttributeName());
821void PPTXAnimationExport::WriteAnimationNodeCommonPropsStart()
823 const Reference<XAnimationNode>& rXNode = getCurrentNode();
824 std::optional<OString> sDuration;
825 std::optional<OString> sRepeatCount;
826 const char* pRestart =
nullptr;
827 const char* pNodeType =
nullptr;
828 const char* pPresetClass =
nullptr;
829 const char* pFill =
nullptr;
830 double fDuration = 0;
831 double fRepeatCount = 0;
835 aAny = rXNode->getDuration();
840 if (aAny >>= eTiming)
842 if (eTiming == Timing_INDEFINITE)
843 sDuration =
"indefinite";
849 pRestart = convertAnimationRestart(rXNode->getRestart());
854 pNodeType = convertEffectNodeType(nType);
855 if (nType == EffectNodeType::TIMING_ROOT)
858 sDuration =
"indefinite";
862 else if (nType == EffectNodeType::MAIN_SEQUENCE)
864 sDuration =
"indefinite";
869 sDuration = OString::number(
static_cast<sal_Int32
>(fDuration * 1000.0));
871 sal_uInt32 nPresetClass =
mpContext->getEffectPresetClass();
872 if (nPresetClass != EffectPresetClass::CUSTOM)
873 pPresetClass = convertEffectPresetClass(nPresetClass);
875 sal_uInt32 nPresetId = 0;
876 bool bPresetId =
false;
877 const OUString& rPresetId =
mpContext->getEffectPresetId();
878 if (rPresetId.getLength() > 0)
880 nPresetId = AnimationExporter::GetPresetID(rPresetId, nPresetClass, bPresetId);
884 sal_uInt32 nPresetSubType = 0;
885 bool bPresetSubType =
false;
886 const OUString& sPresetSubType =
mpContext->getEffectPresetSubType();
887 if (sPresetSubType.getLength() > 0)
890 = AnimationExporter::TranslatePresetSubType(nPresetClass, nPresetId, sPresetSubType);
891 bPresetSubType =
true;
894 if (nType != EffectNodeType::TIMING_ROOT && nType != EffectNodeType::MAIN_SEQUENCE)
897 sal_Int16 nFill = AnimationExporter::GetFillMode(rXNode, AnimationFill::AUTO);
898 pFill = convertAnimationFill(nFill);
901 bool bAutoReverse = rXNode->getAutoReverse();
903 aAny = rXNode->getRepeatCount();
908 if (aAny >>= eTiming)
910 if (eTiming == Timing_INDEFINITE)
911 sRepeatCount =
"indefinite";
914 aAny >>= fRepeatCount;
917 if (fRepeatCount != 0)
918 sRepeatCount = OString::number(
static_cast<sal_Int32
>(fRepeatCount * 1000.0));
920 mpFS->startElementNS(
921 XML_p, XML_cTn, XML_id, OString::number(GetNextAnimationNodeId(rXNode)), XML_dur, sDuration,
923 pNodeType, XML_fill, pFill, XML_presetClass, pPresetClass, XML_presetID,
928 WriteAnimationCondList(
mpContext->getBeginCondList(), XML_stCondLst);
929 WriteAnimationCondList(
mpContext->getEndCondList(), XML_endCondLst);
931 if (rXNode->getType() == AnimationNodeType::ITERATE)
933 Reference<XIterateContainer> xIterate(rXNode, UNO_QUERY);
936 const char*
sType = convertTextAnimationType(xIterate->getIterateType());
938 mpFS->startElementNS(XML_p, XML_iterate, XML_type, sType);
939 mpFS->singleElementNS(XML_p, XML_tmAbs, XML_val,
940 OString::number(xIterate->getIterateInterval() * 1000));
941 mpFS->endElementNS(XML_p, XML_iterate);
945 const std::vector<NodeContextPtr>& aChildNodes =
mpContext->getChildNodes();
946 if (!aChildNodes.empty())
948 bool bSubTnLst =
false;
949 mpFS->startElementNS(XML_p, XML_childTnLst);
952 if (pChildContext->isValid())
954 if (pChildContext->isOnSubTnLst())
960 mpFS->endElementNS(XML_p, XML_childTnLst);
964 mpFS->startElementNS(XML_p, XML_subTnLst);
967 if (pChildContext->isValid() && pChildContext->isOnSubTnLst())
970 mpFS->endElementNS(XML_p, XML_subTnLst);
973 mpFS->endElementNS(XML_p, XML_cTn);
976void PPTXAnimationExport::WriteAnimationNodeSeq()
978 SAL_INFO(
"sd.eppt",
"write animation node SEQ");
980 mpFS->startElementNS(XML_p, XML_seq);
982 WriteAnimationNodeCommonPropsStart();
984 WriteAnimationCondListForSeq(mpFS, XML_prevCondLst);
985 WriteAnimationCondListForSeq(mpFS, XML_nextCondLst);
987 mpFS->endElementNS(XML_p, XML_seq);
990void PPTXAnimationExport::WriteAnimationNodeEffect()
992 SAL_INFO(
"sd.eppt",
"write animation node FILTER");
993 Reference<XTransitionFilter> xFilter(getCurrentNode(), UNO_QUERY);
997 xFilter->getTransition(), xFilter->getSubtype(), xFilter->getDirection());
998 const char* pMode = xFilter->getMode() ?
"in" :
"out";
999 mpFS->startElementNS(XML_p, XML_animEffect, XML_filter, pFilter, XML_transition, pMode);
1001 WriteAnimationNodeAnimateInside(
false);
1003 mpFS->endElementNS(XML_p, XML_animEffect);
1007void PPTXAnimationExport::WriteAnimationNodeCommand()
1009 SAL_INFO(
"sd.eppt",
"write animation node COMMAND");
1010 Reference<XCommand> xCommand(getCurrentNode(), UNO_QUERY);
1014 const char* pType =
"call";
1016 switch (xCommand->getCommand())
1018 case EffectCommands::VERB:
1022 case EffectCommands::PLAY:
1025 uno::Sequence<beans::NamedValue> aParamSeq;
1026 xCommand->getParameter() >>= aParamSeq;
1028 auto it =
aMap.find(
"MediaTime");
1029 if (it !=
aMap.end())
1031 double fMediaTime = 0;
1032 it->second >>= fMediaTime;
1035 = rtl::math::doubleToString(fMediaTime, rtl_math_StringFormat_F, 1,
'.');
1036 aCommand +=
"From(" + aMediaTime +
")";
1040 case EffectCommands::TOGGLEPAUSE:
1043 case EffectCommands::STOP:
1047 SAL_WARN(
"sd.eppt",
"unknown command: " << xCommand->getCommand());
1051 mpFS->startElementNS(XML_p, XML_cmd, XML_type, pType, XML_cmd,
aCommand.getStr());
1053 WriteAnimationNodeAnimateInside(
false);
1054 mpFS->startElementNS(XML_p, XML_cBhvr);
1055 WriteAnimationNodeCommonPropsStart();
1056 WriteAnimationTarget(xCommand->getTarget());
1057 mpFS->endElementNS(XML_p, XML_cBhvr);
1059 mpFS->endElementNS(XML_p, XML_cmd);
1062void PPTXAnimationExport::WriteAnimationNodeMedia()
1064 SAL_INFO(
"sd.eppt",
"write animation node media");
1065 Reference<XAudio> xAudio(getCurrentNode(), UNO_QUERY);
1068 uno::Reference<drawing::XShape> xShape;
1077 bool bValid =
false;
1078 if ((xAudio->getSource() >>= sUrl) && !sUrl.isEmpty() && IsAudioURL(sUrl))
1083 bool bVideo =
false;
1086 if (xAudio->getSource() >>= xShape)
1088 uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY);
1089 bool bHasMediaURL = xShapeProps->getPropertySetInfo()->hasPropertyByName(
"MediaURL");
1090 if (bHasMediaURL && (xShapeProps->getPropertyValue(
"MediaURL") >>= sUrl))
1092 bVideo = IsVideoURL(sUrl);
1093 bValid = IsAudioURL(sUrl) || bVideo;
1103 mrPowerPointExport.embedEffectAudio(mpFS, sUrl, sRelId, sName);
1108 mpFS->startElementNS(XML_p, XML_video);
1109 mpFS->startElementNS(XML_p, XML_cMediaNode);
1113 bool bNarration = xAudio->getNarration();
1114 mpFS->startElementNS(XML_p, XML_audio, XML_isNarration, bNarration ?
"1" :
"0");
1115 bool bHideDuringShow = xAudio->getHideDuringShow();
1116 mpFS->startElementNS(XML_p, XML_cMediaNode, XML_showWhenStopped,
1117 bHideDuringShow ?
"0" :
"1");
1120 animations::Timing eTiming{};
1122 = (xAudio->getRepeatCount() >>= eTiming) && eTiming == animations::Timing_INDEFINITE;
1123 if (bVideo && bLooping)
1125 mpFS->startElementNS(XML_p, XML_cTn, XML_repeatCount,
"indefinite");
1129 mpFS->startElementNS(XML_p, XML_cTn);
1131 WriteAnimationCondList(
mpContext->getBeginCondList(), XML_stCondLst);
1132 WriteAnimationCondList(
mpContext->getEndCondList(), XML_endCondLst);
1133 mpFS->endElementNS(XML_p, XML_cTn);
1135 mpFS->startElementNS(XML_p, XML_tgtEl);
1138 sal_Int32 nShapeID = mrPowerPointExport.GetShapeID(xShape);
1139 mpFS->singleElementNS(XML_p, XML_spTgt, XML_spid, OString::number(nShapeID));
1143 mpFS->singleElementNS(XML_p, XML_sndTgt,
FSNS(XML_r, XML_embed),
1147 mpFS->endElementNS(XML_p, XML_tgtEl);
1149 mpFS->endElementNS(XML_p, XML_cMediaNode);
1152 mpFS->endElementNS(XML_p, XML_video);
1156 mpFS->endElementNS(XML_p, XML_audio);
1165 const Reference<XAnimationNode>& rXNode = getCurrentNode();
1167 SAL_INFO(
"sd.eppt",
"export node type: " << rXNode->getType());
1168 sal_Int32 xmlNodeType = extractNodeType(rXNode);
1170 switch (xmlNodeType)
1173 mpFS->startElementNS(XML_p, xmlNodeType);
1174 WriteAnimationNodeCommonPropsStart();
1175 mpFS->endElementNS(XML_p, xmlNodeType);
1178 WriteAnimationNodeSeq();
1183 case XML_animMotion:
1186 WriteAnimationNodeAnimate(xmlNodeType);
1188 case XML_animEffect:
1189 WriteAnimationNodeEffect();
1192 WriteAnimationNodeCommand();
1195 WriteAnimationNodeMedia();
1198 SAL_WARN(
"sd.eppt",
"export ooxml node type: " << xmlNodeType);
1207 Reference<XAnimationNodeSupplier> xNodeSupplier(rXDrawPage, UNO_QUERY);
1208 if (!xNodeSupplier.is())
1211 const Reference<XAnimationNode> xNode(xNodeSupplier->getAnimationNode());
1215 Reference<XEnumerationAccess> xEnumerationAccess(xNode, UNO_QUERY);
1216 if (!xEnumerationAccess.is())
1219 Reference<XEnumeration> xEnumeration = xEnumerationAccess->createEnumeration();
1220 if (!(xEnumeration.is() && xEnumeration->hasMoreElements()))
1223 auto pNodeContext = std::make_unique<NodeContext>(xNode,
false,
false);
1224 if (pNodeContext->isValid())
1226 mpFS->startElementNS(XML_p, XML_timing);
1227 mpFS->startElementNS(XML_p, XML_tnLst);
1231 mpFS->endElementNS(XML_p, XML_tnLst);
1232 mpFS->endElementNS(XML_p, XML_timing);
1236sal_Int32 PPTXAnimationExport::GetNextAnimationNodeId(
const Reference<XAnimationNode>& xNode)
1238 sal_Int32
nId = mrPowerPointExport.GetNextAnimationNodeID();
1239 maAnimationNodeIdMap[xNode] =
nId;
1243sal_Int32 PPTXAnimationExport::GetAnimationNodeId(
const Reference<XAnimationNode>& xNode)
1246 const auto& aIter = maAnimationNodeIdMap.find(xNode);
1247 if (aIter != maAnimationNodeIdMap.end())
1249 nId = aIter->second;
static const char * FindTransitionName(const sal_Int16 nType, const sal_Int16 nSubType, const bool bDirection)
constexpr sal_Int32 FSNS(sal_Int32 namespc, sal_Int32 element)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
bool endsWithIgnoreAsciiCase(std::u16string_view s1, std::u16string_view s2, std::u16string_view *rest=nullptr)
void WriteAnimations(const FSHelperPtr &pFS, const Reference< XDrawPage > &rXDrawPage, PowerPointExport &rExport)
std::unique_ptr< NodeContext > NodeContextPtr
const ImplAttributeNameConversion * getAttributeConversionList()
SvStream & WriteAnimationNode(SvStream &rOut, AnimationNode const &rNode)
const char * UseIf(const char *s, bool bUse)
std::shared_ptr< FastSerializerHelper > FSHelperPtr
HashMap_OWString_Interface aMap
ParserContextSharedPtr mpContext
const char * getDelay() const
css::uno::Reference< css::drawing::XShape > mxShape
css::uno::Reference< css::animations::XAnimationNode > mxNode
OString I32SHEX(sal_Int32 x)