PPTSlide.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. using DocumentFormat.OpenXml;
  2. using DocumentFormat.OpenXml.Packaging;
  3. using DocumentFormat.OpenXml.Presentation;
  4. using HTEXLib.Animations;
  5. using HTEXLib.Builders;
  6. using HTEXLib.Models.Inner;
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Linq;
  10. using System.Text;
  11. using System.Xml.Linq;
  12. namespace HTEXLib.Models
  13. {
  14. public class PPTSlide:PPTShapeBase
  15. {
  16. public PPTSlide(SlidePart openXmlPart, int slideIndex, DefaultTextStyle defaultTextStyle,SlideSize SlideSizes, SlideMasterPart slideMasterPart, XElement root,IEnumerable<XElement> media,TableStylesPart tableStylesPart)
  17. {
  18. base.tableStylesPart = tableStylesPart;
  19. base.SlidePart = openXmlPart;
  20. base.slideMasterPart = slideMasterPart;
  21. base.Root = root;
  22. base.Media = media;
  23. this.advanceAfterTime = -1;
  24. this.slideIndex = slideIndex;
  25. // this.fileName = fileName;
  26. this.defaultTextStyle = defaultTextStyle;
  27. SlideLayoutPart = openXmlPart.SlideLayoutPart;
  28. SetShapeNonVisualProperties(openXmlPart);
  29. SetSpecificProperties(openXmlPart);
  30. SetSpecificProperties(SlideLayoutPart);
  31. SetBackground(openXmlPart, slideMasterPart);
  32. Id = "s1s0";
  33. //页面过渡 切换 https://docs.microsoft.com/zh-cn/dotnet/api/documentformat.openxml.presentation.transition?view=openxml-2.8.1
  34. Transition transition = openXmlPart.Slide.Transition;
  35. if (transition == null) {
  36. transition= openXmlPart.Slide.Descendants<DocumentFormat.OpenXml.Presentation.Transition>().FirstOrDefault();
  37. }
  38. Transition = JSONGenerator.GenerateTransitionAnimationObject(transition);
  39. Animations = new List<IAnimation>();
  40. animtimes = new List<Animtime>();
  41. // AddAnimations(openXmlPart.Slide.Timing, Animations, SlideSizes);
  42. // AddAnimations(openXmlPart.SlideLayoutPart.SlideLayout.Timing, Animations, SlideSizes);
  43. // AddAnimations(slideMasterPart.SlideMaster.Timing, Animations, SlideSizes);
  44. //播放母版的动画
  45. AddTimings(slideMasterPart.SlideMaster.Timing, animtimes, SlideSizes);
  46. //播放样式表的动画
  47. AddTimings(openXmlPart.SlideLayoutPart.SlideLayout.Timing, animtimes, SlideSizes);
  48. //播放单页动画
  49. AddTimings(openXmlPart.Slide.Timing, animtimes, SlideSizes);
  50. List<NonVisualDrawingProperties> nonVisualDrawingProperties = ((SlidePart)this.SlidePart).Slide.Descendants<NonVisualDrawingProperties>().ToList();
  51. animtimes.ForEach(x => {
  52. NonVisualDrawingProperties nonVisualDrawing= nonVisualDrawingProperties.Where(y => y.Id == x.targetId).FirstOrDefault();
  53. if (nonVisualDrawing != null) {
  54. x.text = nonVisualDrawing.Parent.Parent.InnerText;
  55. }
  56. });
  57. //TODO 处理layout 及 master 的 Transition Timing。
  58. //master 和 layout 过渡效果直接覆盖给slide
  59. IAnimation transition_animation = AddTransition(openXmlPart.Slide.Transition, "slide");
  60. // IAnimation layout_transition = AddTransition(openXmlPart.SlideLayoutPart.SlideLayout.Transition, "layout");
  61. // IAnimation master_transition = AddTransition(slideMasterPart.SlideMaster.Transition, "master");
  62. }
  63. private void SetBackground(SlidePart slidePart, SlideMasterPart slideMasterPart)
  64. {
  65. background= slidePart.Slide.CommonSlideData.Background;
  66. backgroundFrom = "slide";
  67. if (background == null) {
  68. backgroundFrom = "layout";
  69. background = slidePart.SlideLayoutPart.SlideLayout.CommonSlideData.Background;
  70. }
  71. if (background == null) {
  72. backgroundFrom = "master";
  73. background = slideMasterPart.SlideMaster.CommonSlideData.Background;
  74. }
  75. }
  76. public List<string> lazyFiles { get; set; } = new List<string>();
  77. public Background background { get; set; }
  78. public string backgroundFrom { get; set; }
  79. //Slide specific properties
  80. public DefaultTextStyle defaultTextStyle { get; set; }
  81. public PPTContainerShape ContainerShape { get; set; } = new PPTContainerShape();
  82. public TextStyles textStyles { get; set; }
  83. public SlideLayoutPart SlideLayoutPart { get; set; }
  84. public List<Animtime> animtimes { get; set; }
  85. public List<IAnimation> Animations { get; set; }
  86. public string Id { get; set; }
  87. public IAnimation Transition { get; set; }
  88. public int slideIndex;
  89. // public string fileName;
  90. public int advanceAfterTime { get; set; }
  91. //Petco:Check if there is objects with animation.
  92. public void CheckAndSetAnimatableProperty(string animObjectId)
  93. {
  94. int tryParse = 0;
  95. if (int.TryParse(animObjectId, out tryParse))
  96. {
  97. foreach (PPTShapeBase shape in ContainerShape.Elements)
  98. SetAnimatable(animObjectId, shape);
  99. }
  100. else
  101. {
  102. foreach (PPTShapeBase shapeBase in ContainerShape.Elements)
  103. if (typeof(PPTShape).Equals(shapeBase.GetType()) && ((PPTShape)shapeBase).IsText)
  104. foreach (PPTParagraph text in ((PPTShape)shapeBase).Texts)
  105. {
  106. if ((shapeBase.NonVisualShapeProp.Id + "p" + text.Paragraph).Equals("s1s" + animObjectId))
  107. {
  108. text.Animatable = true;
  109. }
  110. }
  111. }
  112. }
  113. private static void SetAnimatable(string animObjectId, PPTShapeBase bshape)
  114. {
  115. string shapeId = bshape.NonVisualShapeProp.Id;
  116. string shapeObjectId = "s1s" + animObjectId;
  117. if (shapeId.Equals(shapeObjectId))
  118. {
  119. bshape.Animatable = true;
  120. }
  121. }
  122. private void SetShapeNonVisualProperties(SlidePart slidePart)
  123. {
  124. var nonVisualShapeProp = new PPTNonVisualShapeProp
  125. {
  126. Id = "s1s1",
  127. Name = slidePart.Slide.LocalName,
  128. Type = "PPTSlide"
  129. };
  130. base.NonVisualShapeProp = nonVisualShapeProp;
  131. }
  132. private void SetSpecificProperties(SlidePart slidePart)
  133. {
  134. textStyles = slidePart.SlideLayoutPart.SlideMasterPart.SlideMaster.TextStyles;
  135. var groupShapeBuilder = new PPTContainerShapeBuilder();
  136. var elms = groupShapeBuilder.GetPPTContainerShape(slidePart, this).Elements;
  137. if (elms != null) {
  138. ContainerShape.Elements.AddRange(elms);
  139. }
  140. }
  141. private void SetSpecificProperties(SlideLayoutPart slideLayoutPart)
  142. {
  143. textStyles = SlideLayoutPart.SlideMasterPart.SlideMaster.TextStyles;
  144. var groupShapeBuilder = new PPTContainerShapeBuilder();
  145. var elms = groupShapeBuilder.GetPPTContainerShape(slideLayoutPart, this).Elements;
  146. if (elms != null)
  147. {
  148. ContainerShape.Elements.AddRange(elms);
  149. }
  150. }
  151. public void MakeShapeInvisible(String shapeId)
  152. {
  153. foreach (PPTShapeBase shape in ContainerShape.Elements)
  154. if (("s1s" + shape.NonVisualShapeProp.TimingId).Equals(shapeId))
  155. {
  156. shape.Invisible = true;
  157. return;
  158. }
  159. else if (typeof(PPTShape).Equals(shape.GetType()) && ((PPTShape)shape).IsText)
  160. {
  161. foreach (PPTParagraph text in ((PPTShape)shape).Texts)
  162. if ((shape.NonVisualShapeProp.TimingId + "p" + text.Paragraph).Equals(shapeId))
  163. {
  164. text.Invisible = true;
  165. return;
  166. }
  167. }
  168. }
  169. private void AddTimings(OpenXmlCompositeElement element, List<Animtime> resultList, SlideSize SlideSizes)
  170. {
  171. if (element == null)
  172. return;
  173. Animtime animationForThisNode = null;
  174. if (element.GetType().Equals(typeof(CommonTimeNode)))
  175. {
  176. CommonTimeNode node = (CommonTimeNode)element;
  177. animationForThisNode = new AnimtimeGenerator(this).GetAnimtimeByCommonTimeNode(node);
  178. if (animationForThisNode != null) {
  179. resultList.Add(animationForThisNode);
  180. }
  181. }
  182. foreach (OpenXmlElement obj in element.ChildElements)
  183. {
  184. if (obj.GetType().IsSubclassOf(typeof(OpenXmlCompositeElement)))
  185. {
  186. if (animationForThisNode == null)
  187. AddTimings((OpenXmlCompositeElement)obj, resultList, SlideSizes);
  188. else {
  189. // AddTimings((OpenXmlCompositeElement)obj, animationForThisNode.InnerAnimations, SlideSizes);
  190. }
  191. }
  192. }
  193. }
  194. public void AddAnimations(OpenXmlCompositeElement element, List<IAnimation> resultList, SlideSize SlideSizes)
  195. {
  196. if (element == null)
  197. return;
  198. List<AnimateMotion> motions = new List<AnimateMotion>();
  199. IAnimation animationForThisNode = null;
  200. if (element.GetType().Equals(typeof(CommonTimeNode)))
  201. {
  202. CommonTimeNode node = (CommonTimeNode)element;
  203. animationForThisNode = new JSONGenerator(this).getSimpleAnimationFromCommonTimeNodePreset(node, SlideSizes);
  204. if (animationForThisNode != null)
  205. {
  206. resultList.Add(animationForThisNode);
  207. //Check if object id is presented in animation list.
  208. CheckAndSetAnimatableProperty(animationForThisNode.ObjectId);
  209. if ((animationForThisNode.InnerAnimations == null ||
  210. animationForThisNode.InnerAnimations.Count == 0) &&
  211. animationForThisNode.IsItEntranceAnimation())
  212. MakeShapeInvisible("s1s" + animationForThisNode.ObjectId);
  213. else if (animationForThisNode.InnerAnimations != null)
  214. foreach (IAnimation anAnimation in animationForThisNode.InnerAnimations)
  215. if (anAnimation.IsItEntranceAnimation())
  216. MakeShapeInvisible("s1s" + animationForThisNode.ObjectId);
  217. return;
  218. }
  219. else
  220. {
  221. /*
  222. * Sometimes there are common time nodes without animations in them. They are used for grouping animations.
  223. * Usually animations are grouped for timing purposes like adding delay to all, or start a group after another.
  224. * It's a tree structure and here we try to follow it as much as possible. Later we will strip the unnecessary nodes
  225. */
  226. animationForThisNode = new SimpleAnimation();
  227. if (node.NodeType != null)
  228. ((SimpleAnimation)animationForThisNode).timingType = node.NodeType;
  229. int delay = 0;
  230. if (node.StartConditionList != null)
  231. foreach (Condition cond in node.StartConditionList)
  232. if (cond.Delay != null && "indefinite" != cond.Delay.Value && cond.Delay.HasValue)
  233. delay = delay + int.Parse(cond.Delay.Value);
  234. if (delay > 0)
  235. {
  236. animationForThisNode.Start = delay;
  237. }
  238. }
  239. if (animationForThisNode != null)
  240. {
  241. animationForThisNode.InnerAnimations = new List<IAnimation>();
  242. resultList.Add(animationForThisNode);
  243. }
  244. }
  245. //Go recursive in the Open XML tree
  246. foreach (OpenXmlElement obj in element.ChildElements)
  247. {
  248. if (obj.GetType().IsSubclassOf(typeof(OpenXmlCompositeElement)))
  249. {
  250. if (animationForThisNode == null)
  251. AddAnimations((OpenXmlCompositeElement)obj, resultList, SlideSizes);
  252. else
  253. AddAnimations((OpenXmlCompositeElement)obj, animationForThisNode.InnerAnimations, SlideSizes);
  254. }
  255. }
  256. }
  257. private IAnimation AddTransition(Transition trans,string partForm)
  258. {
  259. if (trans == null || trans.FirstChild == null)
  260. return null;
  261. TransitionAnimation result = new TransitionAnimation();
  262. if (trans.Speed != null && TransitionSpeedValues.Fast.Equals(trans.Speed.Value))
  263. result.Length = 500;
  264. if (trans.Speed != null && TransitionSpeedValues.Medium.Equals(trans.Speed.Value))
  265. result.Length = 1000;
  266. else if (trans.Speed != null && TransitionSpeedValues.Slow.Equals(trans.Speed.Value))
  267. result.Length = 2000;
  268. //用于播放 设置持续时长
  269. else if (trans.Duration != null)
  270. result.Length = int.Parse(trans.Duration.Value);
  271. else
  272. result.Length = 1000;
  273. result.Start = 0;
  274. result.InitialState = -1;
  275. result.Repetitions = 1;
  276. //指定鼠标单击是否推进幻灯片。如果未指定此属性,则假设值为true。
  277. if (trans.AdvanceOnClick != null)
  278. result.AdvanceOnClick = trans.AdvanceOnClick.Value;
  279. else result.AdvanceOnClick = true;
  280. //advTm小于 动画总时长 以动画总时长为准
  281. //当前页动画时长 |___ _____ ______ __|
  282. //当前页advTm时长 |________________|
  283. //advTm大于 动画总时长,以advTm 时长为准,动画间隔被平均
  284. //当前页动画时长 |___ _____ ______ __|
  285. //当前页advTm时长 |_________________________|
  286. if (trans.AdvanceAfterTime != null) {
  287. result.advTm = int.Parse(trans.AdvanceAfterTime.Value);
  288. }
  289. if (typeof(DocumentFormat.OpenXml.Presentation.BlindsTransition) == trans.FirstChild.GetType()) {
  290. var child = trans.GetFirstChild<BlindsTransition>();
  291. result.Type = AnimationTypes.Blinds;
  292. //§19.5.18
  293. //Horizontal = 0, horz Vertical = 1 vert
  294. result.typeExt = new Dictionary<string, object>() { { result.Type, child.Direction } };
  295. }
  296. else if (typeof(DocumentFormat.OpenXml.Presentation.CheckerTransition) == trans.FirstChild.GetType()) {
  297. var child = trans.GetFirstChild<CheckerTransition>();
  298. result.Type = AnimationTypes.Checker;
  299. // §19.5.24
  300. //Horizontal = 0, horz Vertical = 1 vert
  301. result.typeExt = new Dictionary<string, object>() { { result.Type, child.Direction } };
  302. }
  303. else if (typeof(DocumentFormat.OpenXml.Presentation.CircleTransition) == trans.FirstChild.GetType()) {
  304. var child = trans.GetFirstChild<CircleTransition>();
  305. result.Type = AnimationTypes.Circle;
  306. // §19.5.26
  307. result.typeExt = new Dictionary<string, object>() { { result.Type,""} };
  308. }
  309. else if (typeof(DocumentFormat.OpenXml.Presentation.DissolveTransition) == trans.FirstChild.GetType()) {
  310. var child = trans.GetFirstChild<DissolveTransition>();
  311. //§19.5.36
  312. result.Type = AnimationTypes.Dissolve;// AnimationTypes.DissolveIn;
  313. result.typeExt = new Dictionary<string, object>() { { result.Type,""} };
  314. }
  315. else if (typeof(DocumentFormat.OpenXml.Presentation.CombTransition) == trans.FirstChild.GetType()) {
  316. var child = trans.GetFirstChild<CombTransition>();
  317. result.Type = AnimationTypes.Comb;
  318. // §19.5.30
  319. //Horizontal = 0, horz Vertical = 1 vert
  320. result.typeExt = new Dictionary<string, object>() { { result.Type, child.Direction } };
  321. }
  322. else if (typeof(DocumentFormat.OpenXml.Presentation.CoverTransition) == trans.FirstChild.GetType()) {
  323. var child = trans.GetFirstChild<CoverTransition>();
  324. result.Type = AnimationTypes.Cover;
  325. // §19.5.32
  326. //u up 默认 , d down , l left ,r right ,ld left down ,lu left up, rd right down ,ru right up
  327. result.typeExt = new Dictionary<string, object>() { { result.Type, child.Direction } };
  328. }
  329. else if (typeof(DocumentFormat.OpenXml.Presentation.CutTransition) == trans.FirstChild.GetType()) {
  330. var child = trans.GetFirstChild<CutTransition>();
  331. result.Type = AnimationTypes.Cut;
  332. bool flag = false;
  333. if (child.ThroughBlack != null && child.ThroughBlack.Value) {
  334. result.Type = AnimationTypes.CutThroughBlack;
  335. flag = true;
  336. }
  337. // §19.5.34
  338. result.typeExt = new Dictionary<string, object>() { { result.Type, flag} };
  339. }
  340. else if (typeof(DocumentFormat.OpenXml.Presentation.DiamondTransition) == trans.FirstChild.GetType()) {
  341. var child = trans.GetFirstChild<DiamondTransition>();
  342. result.Type = AnimationTypes.Diamond;
  343. //§19.5.35
  344. result.typeExt = new Dictionary<string, object>() { { result.Type,"" } };
  345. }
  346. else if (typeof(DocumentFormat.OpenXml.Presentation.FadeTransition) == trans.FirstChild.GetType()) {
  347. var child = trans.GetFirstChild<FadeTransition>();
  348. result.Type = AnimationTypes.Fade;
  349. bool flag = false;
  350. if (child.ThroughBlack != null && child.ThroughBlack.Value)
  351. {
  352. result.Type = AnimationTypes.FadeThroughBlack;
  353. flag = true;
  354. }
  355. // §19.5.41
  356. result.typeExt = new Dictionary<string, object>() { { result.Type, flag } };
  357. }
  358. else if (typeof(DocumentFormat.OpenXml.Presentation.NewsflashTransition) == trans.FirstChild.GetType()) {
  359. var child = trans.GetFirstChild<NewsflashTransition>();
  360. result.Type = AnimationTypes.Newsflash;
  361. // §19.5.50
  362. result.typeExt = new Dictionary<string, object>() { { result.Type,"" } };
  363. }
  364. else if (typeof(DocumentFormat.OpenXml.Presentation.PlusTransition) == trans.FirstChild.GetType()) {
  365. var child = trans.GetFirstChild<PlusTransition>();
  366. result.Type = AnimationTypes.Plus;
  367. // §19.5.54
  368. result.typeExt = new Dictionary<string, object>() { { result.Type, ""} };
  369. }
  370. else if (typeof(DocumentFormat.OpenXml.Presentation.PullTransition) == trans.FirstChild.GetType()) {
  371. var child = trans.GetFirstChild<PullTransition>();
  372. result.Type = AnimationTypes.Pull;
  373. // §19.5.58
  374. //u up 默认 , d down , l left ,r right ,ld left down ,lu left up, rd right down ,ru right up
  375. result.typeExt = new Dictionary<string, object>() { { result.Type, child.Direction } };
  376. }
  377. else if (typeof(DocumentFormat.OpenXml.Presentation.PushTransition) == trans.FirstChild.GetType()) {
  378. var child = trans.GetFirstChild<PushTransition>();
  379. result.Type = AnimationTypes.Push;
  380. // §19.5.59
  381. //u up 默认 d down l left r right
  382. result.typeExt =new Dictionary<string, object>() { { result.Type, child.Direction } };
  383. }
  384. else if (typeof(DocumentFormat.OpenXml.Presentation.RandomTransition) == trans.FirstChild.GetType()) {
  385. var child = trans.GetFirstChild<RandomTransition>();
  386. result.Type = AnimationTypes.Random;
  387. //§19.5.60
  388. result.typeExt = new Dictionary<string, object>() { { result.Type,"" } };
  389. }
  390. else if (typeof(DocumentFormat.OpenXml.Presentation.RandomBarTransition) == trans.FirstChild.GetType()) {
  391. var child = trans.GetFirstChild<RandomBarTransition>();
  392. result.Type = AnimationTypes.RandomBars;
  393. // Horizontal = 0, horz Vertical = 1 vert
  394. // §19.5.61
  395. result.typeExt = new Dictionary<string, object>() { { result.Type, child.Direction } };
  396. }
  397. else if (typeof(DocumentFormat.OpenXml.Presentation.SplitTransition) == trans.FirstChild.GetType()) {
  398. var child = trans.GetFirstChild<SplitTransition>();
  399. result.Type = AnimationTypes.Split;
  400. // Out = 0, out In = 1 in
  401. var dir = child.Direction;
  402. // Horizontal = 0, horz Vertical = 1 vert
  403. // §19.5.71
  404. var orient = child.Orientation;
  405. result.typeExt = new Dictionary<string, object>() { { result.Type,new { dir , orient } } };
  406. }
  407. else if (typeof(DocumentFormat.OpenXml.Presentation.StripsTransition) == trans.FirstChild.GetType()) {
  408. var child = trans.GetFirstChild<StripsTransition>();
  409. result.Type = AnimationTypes.Strips;
  410. // Left-Up lu , Right-Up ru ,Left-Downld , Right-Down rd
  411. // §19.5.74
  412. result.typeExt = new Dictionary<string, object>() { { result.Type, child.Direction } };
  413. }
  414. else if (typeof(DocumentFormat.OpenXml.Presentation.WedgeTransition) == trans.FirstChild.GetType()) {
  415. var child = trans.GetFirstChild<WedgeTransition>();
  416. result.Type = AnimationTypes.Wedge;
  417. // §19.5.94
  418. result.typeExt = new Dictionary<string, object>() { { result.Type, "" } };
  419. }
  420. else if (typeof(DocumentFormat.OpenXml.Presentation.WheelTransition) == trans.FirstChild.GetType()) {
  421. var child = trans.GetFirstChild<WheelTransition>();
  422. result.Type = AnimationTypes.Wheel;
  423. //19.5.95
  424. // 1,一个扇形中心旋转一圈,右上角开始, 2 两个扇形旋转, 3三个扇形旋转,4 四个扇形旋转, 8 八个扇形旋转
  425. result.typeExt = new Dictionary<string, object>() { { result.Type, child.Spokes } };
  426. }
  427. else if (typeof(DocumentFormat.OpenXml.Presentation.WipeTransition) == trans.FirstChild.GetType()) {
  428. var child = trans.GetFirstChild<WipeTransition>();
  429. result.Type = AnimationTypes.Wipe;
  430. //u up 默认 , d down , l left ,r right
  431. // §19.5.96
  432. result.typeExt = new Dictionary<string, object>() { { result.Type, child.Direction } };
  433. }
  434. else if (typeof(DocumentFormat.OpenXml.Presentation.ZoomTransition) == trans.FirstChild.GetType()) {
  435. var child = trans.GetFirstChild<ZoomTransition>();
  436. result.Type = AnimationTypes.Zoom;
  437. // Out = 0, out In = 1 in
  438. // §19.5.97
  439. result.typeExt = new Dictionary<string, object>() { { result.Type, child.Direction } };
  440. }
  441. var SoundAction = trans.GetFirstChild<SoundAction>();
  442. if (SoundAction != null) {
  443. var loop = false;
  444. if (SoundAction.StartSoundAction.Loop != null) {
  445. loop = true;
  446. }
  447. var url = "";
  448. var name = "";
  449. if (SoundAction.StartSoundAction.Sound != null) {
  450. var Sound = SoundAction.StartSoundAction.Sound;
  451. var Embed = Sound.Embed;
  452. DataPartReferenceRelationship part = null;
  453. if (partForm == "slide")
  454. {
  455. part = SlidePart.DataPartReferenceRelationships.Where(x => x.Id == Embed).FirstOrDefault();
  456. }
  457. if (partForm == "layout")
  458. {
  459. part = SlideLayoutPart.DataPartReferenceRelationships.Where(x => x.Id == Embed).FirstOrDefault();
  460. }
  461. if (partForm == "master")
  462. {
  463. part = slideMasterPart.DataPartReferenceRelationships.Where(x => x.Id == Embed).FirstOrDefault();
  464. }
  465. if (part != null)
  466. {
  467. url = part.Uri.ToString().Replace("../", "/ppt/");
  468. var thumbnail = Media.Where(x => x.Attributes().Select(y => y.Value == url).FirstOrDefault()).FirstOrDefault();
  469. //if (thumbnail != null)
  470. //{
  471. // var contentType = thumbnail.Attribute("{http://schemas.microsoft.com/office/2006/xmlPackage}contentType").Value;
  472. // //var data = thumbnail.Value;
  473. // //url = "data:" + contentType + ";base64," + data;
  474. // //url = url.Replace("\r\n", "");
  475. // result.url = url;
  476. // // htexBlipFill.urlType = "base64";
  477. // // htexBlipFill.contentType = contentType;
  478. //}
  479. }
  480. result.typeExt = new Dictionary<string, object>() { { "sndAc", new { loop, url, name } } };
  481. }
  482. }
  483. ///TODO Office2013|Office2010
  484. return result;
  485. }
  486. }
  487. }