/
PasteLabActionHandler.cs
111 lines (92 loc) · 4.92 KB
/
PasteLabActionHandler.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
using System.Collections.Generic;
using Microsoft.Office.Interop.PowerPoint;
using PowerPointLabs.ActionFramework.Common.Extension;
using PowerPointLabs.ActionFramework.Common.Interface;
using PowerPointLabs.ActionFramework.Common.Log;
using PowerPointLabs.Models;
using PowerPointLabs.Utils;
namespace PowerPointLabs.ActionFramework.PasteLab
{
abstract class PasteLabActionHandler : ActionHandler
{
private static readonly string SelectOrderTagName = "PasteLabSelectOrder";
private static readonly string SelectChildOrderTagName = "PasteLabSelectChildOrder";
// Sealed method: Subclasses should override ExecutePasteAction instead
protected sealed override void ExecuteAction(string ribbonId)
{
this.StartNewUndoEntry();
PowerPointPresentation presentation = this.GetCurrentPresentation();
PowerPointSlide slide = this.GetCurrentSlide();
Selection selection = this.GetCurrentSelection();
if (ClipboardUtil.IsClipboardEmpty())
{
Logger.Log(ribbonId + " failed. Clipboard is empty.");
return;
}
ShapeRange passedSelectedShapes = null;
ShapeRange passedSelectedChildShapes = null;
if (ShapeUtil.IsSelectionShape(selection) && !IsSelectionIgnored(ribbonId))
{
// When pasting some objects, the selection may change to the pasted object (e.g. jpg from desktop).
// Therefore we must capture the selection first.
ShapeRange selectedShapes = selection.ShapeRange;
// Save clipboard onto a temp slide, because CorruptionCorrrection uses Copy-Paste
PowerPointSlide tempClipboardSlide = presentation.AddSlide(index: slide.Index);
ShapeRange tempClipboardShapes = ClipboardUtil.PasteShapesFromClipboard(tempClipboardSlide);
// Nothing is pasted, stop now
if (tempClipboardShapes == null)
{
tempClipboardSlide.Delete();
return;
}
// Preserve selection by tagging them
for (int i = 1; i <= selectedShapes.Count; i++)
{
selectedShapes[i].Tags.Add(SelectOrderTagName, i.ToString());
}
ShapeRange selectedChildShapes = null;
if (selection.HasChildShapeRange)
{
selectedChildShapes = selection.ChildShapeRange;
for (int i = 1; i <= selectedChildShapes.Count; i++)
{
selectedChildShapes[i].Tags.Add(SelectChildOrderTagName, i.ToString());
}
}
// Corruption correction
ShapeRange correctedShapes = ShapeUtil.CorruptionCorrection(selectedShapes, slide);
// Reselect the preserved selections
List<Shape> correctedShapeList = new List<Shape>();
List<Shape> correctedChildShapeList = new List<Shape>();
foreach (Shape shape in correctedShapes)
{
correctedShapeList.Add(shape);
correctedChildShapeList.AddRange(ShapeUtil.GetChildrenWithNonEmptyTag(shape, SelectChildOrderTagName));
}
correctedShapeList.Sort((sh1, sh2) => int.Parse(sh1.Tags[SelectOrderTagName]) - int.Parse(sh2.Tags[SelectOrderTagName]));
correctedChildShapeList.Sort((sh1, sh2) => int.Parse(sh1.Tags[SelectChildOrderTagName]) - int.Parse(sh2.Tags[SelectChildOrderTagName]));
passedSelectedShapes = slide.ToShapeRange(correctedShapeList);
passedSelectedChildShapes = slide.ToShapeRange(correctedChildShapeList);
// Remove shape tags after they have been used
ShapeUtil.DeleteTagFromShapes(passedSelectedShapes, SelectOrderTagName);
ShapeUtil.DeleteTagFromShapes(passedSelectedChildShapes, SelectChildOrderTagName);
// Revert clipboard
tempClipboardShapes.Copy();
tempClipboardSlide.Delete();
}
ShapeRange result = ExecutePasteAction(ribbonId, presentation, slide, passedSelectedShapes, passedSelectedChildShapes);
if (result != null)
{
result.Select();
}
}
protected abstract ShapeRange ExecutePasteAction(string ribbonId, PowerPointPresentation presentation, PowerPointSlide slide,
ShapeRange selectedShapes, ShapeRange selectedChildShapes);
private bool IsSelectionIgnored(string ribbonId)
{
return ribbonId.StartsWith("PasteAtCursorPosition") ||
ribbonId.StartsWith("PasteAtOriginalPosition") ||
ribbonId.StartsWith("PasteToFillSlide");
}
}
}