python-pptx2 2.13.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. pptx2/__init__.py +152 -0
  2. pptx2/_color.py +75 -0
  3. pptx2/_slide_importer.py +597 -0
  4. pptx2/_svg.py +155 -0
  5. pptx2/_template_applier.py +292 -0
  6. pptx2/_textstyle.py +187 -0
  7. pptx2/accessibility.py +365 -0
  8. pptx2/action.py +270 -0
  9. pptx2/animation.py +2237 -0
  10. pptx2/api.py +49 -0
  11. pptx2/audit.py +258 -0
  12. pptx2/chart/__init__.py +0 -0
  13. pptx2/chart/analytics.py +381 -0
  14. pptx2/chart/axis.py +543 -0
  15. pptx2/chart/category.py +200 -0
  16. pptx2/chart/chart.py +670 -0
  17. pptx2/chart/data.py +864 -0
  18. pptx2/chart/datalabel.py +406 -0
  19. pptx2/chart/legend.py +86 -0
  20. pptx2/chart/marker.py +70 -0
  21. pptx2/chart/palettes.py +129 -0
  22. pptx2/chart/plot.py +462 -0
  23. pptx2/chart/point.py +101 -0
  24. pptx2/chart/quick_layouts.py +325 -0
  25. pptx2/chart/series.py +334 -0
  26. pptx2/chart/xlsx.py +272 -0
  27. pptx2/chart/xmlwriter.py +1845 -0
  28. pptx2/compose/__init__.py +28 -0
  29. pptx2/compose/from_spec.py +1094 -0
  30. pptx2/design/__init__.py +8 -0
  31. pptx2/design/components.py +607 -0
  32. pptx2/design/figures.py +389 -0
  33. pptx2/design/layout.py +370 -0
  34. pptx2/design/recipes.py +1967 -0
  35. pptx2/design/style.py +209 -0
  36. pptx2/design/tokens.py +915 -0
  37. pptx2/diagrams.py +754 -0
  38. pptx2/dml/__init__.py +0 -0
  39. pptx2/dml/chtfmt.py +40 -0
  40. pptx2/dml/color.py +496 -0
  41. pptx2/dml/effect.py +909 -0
  42. pptx2/dml/fill.py +691 -0
  43. pptx2/dml/line.py +287 -0
  44. pptx2/dml/picture.py +212 -0
  45. pptx2/dml/three_d.py +381 -0
  46. pptx2/enum/__init__.py +0 -0
  47. pptx2/enum/action.py +71 -0
  48. pptx2/enum/animation.py +31 -0
  49. pptx2/enum/base.py +218 -0
  50. pptx2/enum/chart.py +574 -0
  51. pptx2/enum/dml.py +740 -0
  52. pptx2/enum/lang.py +685 -0
  53. pptx2/enum/presentation.py +133 -0
  54. pptx2/enum/shapes.py +1029 -0
  55. pptx2/enum/text.py +230 -0
  56. pptx2/exc.py +42 -0
  57. pptx2/formats.py +139 -0
  58. pptx2/geometry.py +420 -0
  59. pptx2/inherit.py +109 -0
  60. pptx2/lint.py +2256 -0
  61. pptx2/math.py +177 -0
  62. pptx2/media.py +197 -0
  63. pptx2/opc/__init__.py +0 -0
  64. pptx2/opc/constants.py +332 -0
  65. pptx2/opc/oxml.py +188 -0
  66. pptx2/opc/package.py +762 -0
  67. pptx2/opc/packuri.py +109 -0
  68. pptx2/opc/serialized.py +296 -0
  69. pptx2/opc/shared.py +20 -0
  70. pptx2/opc/spec.py +45 -0
  71. pptx2/oxml/__init__.py +555 -0
  72. pptx2/oxml/action.py +53 -0
  73. pptx2/oxml/chart/__init__.py +0 -0
  74. pptx2/oxml/chart/axis.py +337 -0
  75. pptx2/oxml/chart/chart.py +481 -0
  76. pptx2/oxml/chart/datalabel.py +253 -0
  77. pptx2/oxml/chart/legend.py +72 -0
  78. pptx2/oxml/chart/marker.py +61 -0
  79. pptx2/oxml/chart/plot.py +365 -0
  80. pptx2/oxml/chart/series.py +425 -0
  81. pptx2/oxml/chart/shared.py +220 -0
  82. pptx2/oxml/coreprops.py +288 -0
  83. pptx2/oxml/dml/__init__.py +0 -0
  84. pptx2/oxml/dml/color.py +135 -0
  85. pptx2/oxml/dml/effect.py +213 -0
  86. pptx2/oxml/dml/fill.py +316 -0
  87. pptx2/oxml/dml/line.py +12 -0
  88. pptx2/oxml/dml/three_d.py +110 -0
  89. pptx2/oxml/ns.py +135 -0
  90. pptx2/oxml/presentation.py +313 -0
  91. pptx2/oxml/shapes/__init__.py +19 -0
  92. pptx2/oxml/shapes/autoshape.py +467 -0
  93. pptx2/oxml/shapes/connector.py +107 -0
  94. pptx2/oxml/shapes/graphfrm.py +347 -0
  95. pptx2/oxml/shapes/groupshape.py +329 -0
  96. pptx2/oxml/shapes/picture.py +270 -0
  97. pptx2/oxml/shapes/shared.py +577 -0
  98. pptx2/oxml/simpletypes.py +1027 -0
  99. pptx2/oxml/slide.py +563 -0
  100. pptx2/oxml/table.py +650 -0
  101. pptx2/oxml/text.py +815 -0
  102. pptx2/oxml/theme.py +36 -0
  103. pptx2/oxml/xmlchemy.py +717 -0
  104. pptx2/package.py +222 -0
  105. pptx2/parts/__init__.py +0 -0
  106. pptx2/parts/chart.py +95 -0
  107. pptx2/parts/coreprops.py +167 -0
  108. pptx2/parts/diagram.py +37 -0
  109. pptx2/parts/embeddedpackage.py +93 -0
  110. pptx2/parts/image.py +275 -0
  111. pptx2/parts/media.py +37 -0
  112. pptx2/parts/presentation.py +136 -0
  113. pptx2/parts/slide.py +371 -0
  114. pptx2/presentation.py +408 -0
  115. pptx2/py.typed +0 -0
  116. pptx2/render.py +586 -0
  117. pptx2/section.py +272 -0
  118. pptx2/shapes/__init__.py +26 -0
  119. pptx2/shapes/autoshape.py +442 -0
  120. pptx2/shapes/base.py +1078 -0
  121. pptx2/shapes/connector.py +297 -0
  122. pptx2/shapes/freeform.py +337 -0
  123. pptx2/shapes/graphfrm.py +316 -0
  124. pptx2/shapes/group.py +264 -0
  125. pptx2/shapes/picture.py +422 -0
  126. pptx2/shapes/placeholder.py +468 -0
  127. pptx2/shapes/shapetree.py +2027 -0
  128. pptx2/shared.py +82 -0
  129. pptx2/skill/SKILL.md +450 -0
  130. pptx2/skill/__init__.py +78 -0
  131. pptx2/skill/__main__.py +64 -0
  132. pptx2/skill/references/animations.md +189 -0
  133. pptx2/skill/references/basics.md +421 -0
  134. pptx2/skill/references/charts.md +254 -0
  135. pptx2/skill/references/compose.md +234 -0
  136. pptx2/skill/references/design.md +366 -0
  137. pptx2/skill/references/effects.md +249 -0
  138. pptx2/skill/references/end-to-end-deck.md +231 -0
  139. pptx2/skill/references/geometry-and-arrows.md +334 -0
  140. pptx2/skill/references/lint.md +275 -0
  141. pptx2/skill/references/math.md +86 -0
  142. pptx2/skill/references/picture-effects.md +129 -0
  143. pptx2/skill/references/render.md +151 -0
  144. pptx2/skill/references/smart-art.md +75 -0
  145. pptx2/skill/references/space-aware-authoring.md +249 -0
  146. pptx2/skill/references/tables.md +244 -0
  147. pptx2/skill/references/theme.md +127 -0
  148. pptx2/skill/references/three-d.md +109 -0
  149. pptx2/skill/references/transitions.md +100 -0
  150. pptx2/slide.py +1244 -0
  151. pptx2/smart_art.py +220 -0
  152. pptx2/spec.py +633 -0
  153. pptx2/table.py +1181 -0
  154. pptx2/table_styles.py +184 -0
  155. pptx2/templates/default.pptx +0 -0
  156. pptx2/templates/docx-icon.emf +0 -0
  157. pptx2/templates/generic-icon.emf +0 -0
  158. pptx2/templates/notes.xml +23 -0
  159. pptx2/templates/notesMaster.xml +352 -0
  160. pptx2/templates/pptx-icon.emf +0 -0
  161. pptx2/templates/theme.xml +321 -0
  162. pptx2/templates/xlsx-icon.emf +0 -0
  163. pptx2/text/__init__.py +0 -0
  164. pptx2/text/fonts.py +482 -0
  165. pptx2/text/layout.py +374 -0
  166. pptx2/text/text.py +1272 -0
  167. pptx2/theme.py +721 -0
  168. pptx2/types.py +36 -0
  169. pptx2/util.py +263 -0
  170. python_pptx2-2.13.0.dist-info/METADATA +351 -0
  171. python_pptx2-2.13.0.dist-info/RECORD +175 -0
  172. python_pptx2-2.13.0.dist-info/WHEEL +5 -0
  173. python_pptx2-2.13.0.dist-info/entry_points.txt +3 -0
  174. python_pptx2-2.13.0.dist-info/licenses/LICENSE +22 -0
  175. python_pptx2-2.13.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,577 @@
1
+ """Common shape-related oxml objects."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING, Callable
6
+
7
+ from pptx2.dml.fill import CT_GradientFillProperties
8
+ from pptx2.enum.dml import (
9
+ MSO_LINE_CAP_STYLE,
10
+ MSO_LINE_COMPOUND_STYLE,
11
+ MSO_LINE_END_SIZE,
12
+ MSO_LINE_END_TYPE,
13
+ )
14
+ from pptx2.enum.shapes import PP_PLACEHOLDER
15
+ from pptx2.oxml.ns import qn
16
+ from pptx2.oxml.simpletypes import (
17
+ ST_Angle,
18
+ ST_Coordinate,
19
+ ST_Direction,
20
+ ST_DrawingElementId,
21
+ ST_LineWidth,
22
+ ST_PlaceholderSize,
23
+ ST_PositiveCoordinate,
24
+ XsdBoolean,
25
+ XsdString,
26
+ XsdUnsignedInt,
27
+ )
28
+ from pptx2.oxml.xmlchemy import (
29
+ BaseOxmlElement,
30
+ Choice,
31
+ OptionalAttribute,
32
+ OxmlElement,
33
+ RequiredAttribute,
34
+ ZeroOrOne,
35
+ ZeroOrOneChoice,
36
+ )
37
+ from pptx2.util import Emu
38
+
39
+ if TYPE_CHECKING:
40
+ from pptx2.oxml.action import CT_Hyperlink
41
+ from pptx2.oxml.dml.three_d import CT_Scene3D, CT_Shape3D
42
+ from pptx2.oxml.shapes.autoshape import CT_CustomGeometry2D, CT_PresetGeometry2D
43
+ from pptx2.util import Length
44
+
45
+
46
+ class BaseShapeElement(BaseOxmlElement):
47
+ """Provides common behavior for shape element classes like CT_Shape, CT_Picture, etc."""
48
+
49
+ spPr: CT_ShapeProperties
50
+
51
+ @property
52
+ def cx(self) -> Length:
53
+ return self._get_xfrm_attr("cx")
54
+
55
+ @cx.setter
56
+ def cx(self, value):
57
+ self._set_xfrm_attr("cx", value)
58
+
59
+ @property
60
+ def cy(self) -> Length:
61
+ return self._get_xfrm_attr("cy")
62
+
63
+ @cy.setter
64
+ def cy(self, value):
65
+ self._set_xfrm_attr("cy", value)
66
+
67
+ @property
68
+ def flipH(self):
69
+ return bool(self._get_xfrm_attr("flipH"))
70
+
71
+ @flipH.setter
72
+ def flipH(self, value):
73
+ self._set_xfrm_attr("flipH", value)
74
+
75
+ @property
76
+ def flipV(self):
77
+ return bool(self._get_xfrm_attr("flipV"))
78
+
79
+ @flipV.setter
80
+ def flipV(self, value):
81
+ self._set_xfrm_attr("flipV", value)
82
+
83
+ def get_or_add_xfrm(self):
84
+ """Return the `a:xfrm` grandchild element, newly-added if not present.
85
+
86
+ This version works for `p:sp`, `p:cxnSp`, and `p:pic` elements, others will need to
87
+ override.
88
+ """
89
+ return self.spPr.get_or_add_xfrm()
90
+
91
+ @property
92
+ def has_ph_elm(self):
93
+ """
94
+ True if this shape element has a `p:ph` descendant, indicating it
95
+ is a placeholder shape. False otherwise.
96
+ """
97
+ return self.ph is not None
98
+
99
+ @property
100
+ def ph(self) -> CT_Placeholder | None:
101
+ """The `p:ph` descendant element if there is one, None otherwise."""
102
+ ph_elms = self.xpath("./*[1]/p:nvPr/p:ph")
103
+ if len(ph_elms) == 0:
104
+ return None
105
+ return ph_elms[0]
106
+
107
+ @property
108
+ def ph_idx(self) -> int:
109
+ """Integer value of placeholder idx attribute.
110
+
111
+ Raises |ValueError| if shape is not a placeholder.
112
+ """
113
+ ph = self.ph
114
+ if ph is None:
115
+ raise ValueError("not a placeholder shape")
116
+ return ph.idx
117
+
118
+ @property
119
+ def ph_orient(self) -> str:
120
+ """Placeholder orientation, e.g. 'vert'.
121
+
122
+ Raises |ValueError| if shape is not a placeholder.
123
+ """
124
+ ph = self.ph
125
+ if ph is None:
126
+ raise ValueError("not a placeholder shape")
127
+ return ph.orient
128
+
129
+ @property
130
+ def ph_sz(self) -> str:
131
+ """Placeholder size, e.g. ST_PlaceholderSize.HALF.
132
+
133
+ Raises `ValueError` if shape is not a placeholder.
134
+ """
135
+ ph = self.ph
136
+ if ph is None:
137
+ raise ValueError("not a placeholder shape")
138
+ return ph.sz
139
+
140
+ @property
141
+ def ph_type(self):
142
+ """Placeholder type, e.g. ST_PlaceholderType.TITLE ('title').
143
+
144
+ Raises `ValueError` if shape is not a placeholder.
145
+ """
146
+ ph = self.ph
147
+ if ph is None:
148
+ raise ValueError("not a placeholder shape")
149
+ return ph.type
150
+
151
+ @property
152
+ def rot(self) -> float:
153
+ """Float representing degrees this shape is rotated clockwise."""
154
+ xfrm = self.xfrm
155
+ if xfrm is None or xfrm.rot is None:
156
+ return 0.0
157
+ return xfrm.rot
158
+
159
+ @rot.setter
160
+ def rot(self, value: float):
161
+ self.get_or_add_xfrm().rot = value
162
+
163
+ @property
164
+ def shape_id(self):
165
+ """
166
+ Integer id of this shape
167
+ """
168
+ return self._nvXxPr.cNvPr.id
169
+
170
+ @property
171
+ def shape_name(self):
172
+ """
173
+ Name of this shape
174
+ """
175
+ return self._nvXxPr.cNvPr.name
176
+
177
+ @property
178
+ def txBody(self):
179
+ """Child `p:txBody` element, None if not present."""
180
+ return self.find(qn("p:txBody"))
181
+
182
+ @property
183
+ def x(self) -> Length:
184
+ return self._get_xfrm_attr("x")
185
+
186
+ @x.setter
187
+ def x(self, value):
188
+ self._set_xfrm_attr("x", value)
189
+
190
+ @property
191
+ def xfrm(self):
192
+ """The `a:xfrm` grandchild element or |None| if not found.
193
+
194
+ This version works for `p:sp`, `p:cxnSp`, and `p:pic` elements, others will need to
195
+ override.
196
+ """
197
+ return self.spPr.xfrm
198
+
199
+ @property
200
+ def y(self) -> Length:
201
+ return self._get_xfrm_attr("y")
202
+
203
+ @y.setter
204
+ def y(self, value):
205
+ self._set_xfrm_attr("y", value)
206
+
207
+ @property
208
+ def _nvXxPr(self):
209
+ """
210
+ Required non-visual shape properties element for this shape. Actual
211
+ name depends on the shape type, e.g. `p:nvPicPr` for picture
212
+ shape.
213
+ """
214
+ return self.xpath("./*[1]")[0]
215
+
216
+ def _get_xfrm_attr(self, name: str) -> Length | None:
217
+ xfrm = self.xfrm
218
+ if xfrm is None:
219
+ return None
220
+ return getattr(xfrm, name)
221
+
222
+ def _set_xfrm_attr(self, name, value):
223
+ xfrm = self.get_or_add_xfrm()
224
+ setattr(xfrm, name, value)
225
+
226
+
227
+ class CT_ApplicationNonVisualDrawingProps(BaseOxmlElement):
228
+ """`p:nvPr` element."""
229
+
230
+ get_or_add_ph: Callable[[], CT_Placeholder]
231
+
232
+ ph = ZeroOrOne(
233
+ "p:ph",
234
+ successors=(
235
+ "a:audioCd",
236
+ "a:wavAudioFile",
237
+ "a:audioFile",
238
+ "a:videoFile",
239
+ "a:quickTimeFile",
240
+ "p:custDataLst",
241
+ "p:extLst",
242
+ ),
243
+ )
244
+
245
+
246
+ class CT_LineProperties(BaseOxmlElement):
247
+ """Custom element class for <a:ln> element"""
248
+
249
+ _tag_seq = (
250
+ "a:noFill",
251
+ "a:solidFill",
252
+ "a:gradFill",
253
+ "a:pattFill",
254
+ "a:prstDash",
255
+ "a:custDash",
256
+ "a:round",
257
+ "a:bevel",
258
+ "a:miter",
259
+ "a:headEnd",
260
+ "a:tailEnd",
261
+ "a:extLst",
262
+ )
263
+ eg_lineFillProperties = ZeroOrOneChoice(
264
+ (
265
+ Choice("a:noFill"),
266
+ Choice("a:solidFill"),
267
+ Choice("a:gradFill"),
268
+ Choice("a:pattFill"),
269
+ ),
270
+ successors=_tag_seq[4:],
271
+ )
272
+ prstDash = ZeroOrOne("a:prstDash", successors=_tag_seq[5:])
273
+ custDash = ZeroOrOne("a:custDash", successors=_tag_seq[6:])
274
+ eg_lineJoinProperties = ZeroOrOneChoice(
275
+ (Choice("a:round"), Choice("a:bevel"), Choice("a:miter")),
276
+ successors=_tag_seq[9:],
277
+ )
278
+ headEnd = ZeroOrOne("a:headEnd", successors=_tag_seq[10:])
279
+ tailEnd = ZeroOrOne("a:tailEnd", successors=_tag_seq[11:])
280
+ del _tag_seq
281
+ w = OptionalAttribute("w", ST_LineWidth, default=Emu(0))
282
+ cap = OptionalAttribute("cap", MSO_LINE_CAP_STYLE)
283
+ cmpd = OptionalAttribute("cmpd", MSO_LINE_COMPOUND_STYLE)
284
+
285
+ @property
286
+ def eg_fillProperties(self):
287
+ """
288
+ Required to fulfill the interface used by dml.fill.
289
+ """
290
+ return self.eg_lineFillProperties
291
+
292
+ @property
293
+ def prstDash_val(self):
294
+ """Return value of `val` attribute of `a:prstDash` child.
295
+
296
+ Return |None| if not present.
297
+ """
298
+ prstDash = self.prstDash
299
+ if prstDash is None:
300
+ return None
301
+ return prstDash.val
302
+
303
+ @prstDash_val.setter
304
+ def prstDash_val(self, val):
305
+ self._remove_custDash()
306
+ prstDash = self.get_or_add_prstDash()
307
+ prstDash.val = val
308
+
309
+
310
+ class CT_LineEndProperties(BaseOxmlElement):
311
+ """`a:headEnd` / `a:tailEnd` custom element class.
312
+
313
+ Defines the arrowhead at one end of a stroked line.
314
+ """
315
+
316
+ type: MSO_LINE_END_TYPE | None = OptionalAttribute( # pyright: ignore[reportAssignmentType]
317
+ "type", MSO_LINE_END_TYPE
318
+ )
319
+ w: MSO_LINE_END_SIZE | None = OptionalAttribute( # pyright: ignore[reportAssignmentType]
320
+ "w", MSO_LINE_END_SIZE
321
+ )
322
+ len: MSO_LINE_END_SIZE | None = OptionalAttribute( # pyright: ignore[reportAssignmentType]
323
+ "len", MSO_LINE_END_SIZE
324
+ )
325
+
326
+
327
+ class CT_LineJoinMiterProperties(BaseOxmlElement):
328
+ """`a:miter` custom element class.
329
+
330
+ Specifies a miter join with an optional `lim` (limit) attribute.
331
+ """
332
+
333
+ lim = OptionalAttribute("lim", ST_PositiveCoordinate)
334
+
335
+
336
+ class CT_NonVisualDrawingProps(BaseOxmlElement):
337
+ """`p:cNvPr` custom element class."""
338
+
339
+ get_or_add_hlinkClick: Callable[[], CT_Hyperlink]
340
+ get_or_add_hlinkHover: Callable[[], CT_Hyperlink]
341
+
342
+ _tag_seq = ("a:hlinkClick", "a:hlinkHover", "a:extLst")
343
+ hlinkClick: CT_Hyperlink | None = ZeroOrOne("a:hlinkClick", successors=_tag_seq[1:])
344
+ hlinkHover: CT_Hyperlink | None = ZeroOrOne("a:hlinkHover", successors=_tag_seq[2:])
345
+ # ``a:extLst`` is the official OOXML extension hook on cNvPr. The
346
+ # descriptor's ``get_or_add_extLst()`` keeps schema-correct child
347
+ # ordering (after hlinkClick / hlinkHover) so callers don't have to
348
+ # hand-roll insertion.
349
+ extLst = ZeroOrOne("a:extLst", successors=())
350
+ id = RequiredAttribute("id", ST_DrawingElementId)
351
+ name = RequiredAttribute("name", XsdString)
352
+ del _tag_seq
353
+
354
+
355
+ class CT_Placeholder(BaseOxmlElement):
356
+ """`p:ph` custom element class."""
357
+
358
+ type: PP_PLACEHOLDER = OptionalAttribute( # pyright: ignore[reportAssignmentType]
359
+ "type", PP_PLACEHOLDER, default=PP_PLACEHOLDER.OBJECT
360
+ )
361
+ orient: str = OptionalAttribute( # pyright: ignore[reportAssignmentType]
362
+ "orient", ST_Direction, default=ST_Direction.HORZ
363
+ )
364
+ sz: str = OptionalAttribute( # pyright: ignore[reportAssignmentType]
365
+ "sz", ST_PlaceholderSize, default=ST_PlaceholderSize.FULL
366
+ )
367
+ idx: int = OptionalAttribute( # pyright: ignore[reportAssignmentType]
368
+ "idx", XsdUnsignedInt, default=0
369
+ )
370
+
371
+
372
+ class CT_Point2D(BaseOxmlElement):
373
+ """
374
+ Custom element class for <a:off> element.
375
+ """
376
+
377
+ x: Length = RequiredAttribute("x", ST_Coordinate) # pyright: ignore[reportAssignmentType]
378
+ y: Length = RequiredAttribute("y", ST_Coordinate) # pyright: ignore[reportAssignmentType]
379
+
380
+
381
+ class CT_PositiveSize2D(BaseOxmlElement):
382
+ """
383
+ Custom element class for <a:ext> element.
384
+ """
385
+
386
+ cx = RequiredAttribute("cx", ST_PositiveCoordinate)
387
+ cy = RequiredAttribute("cy", ST_PositiveCoordinate)
388
+
389
+
390
+ class CT_ShapeProperties(BaseOxmlElement):
391
+ """Custom element class for `p:spPr` element.
392
+
393
+ Shared by `p:sp`, `p:cxnSp`, and `p:pic` elements as well as a few more obscure ones.
394
+ """
395
+
396
+ get_or_add_xfrm: Callable[[], CT_Transform2D]
397
+ get_or_add_ln: Callable[[], CT_LineProperties]
398
+ get_or_add_scene3d: Callable[[], CT_Scene3D]
399
+ get_or_add_sp3d: Callable[[], CT_Shape3D]
400
+ _add_prstGeom: Callable[[], CT_PresetGeometry2D]
401
+ _remove_custGeom: Callable[[], None]
402
+
403
+ _tag_seq = (
404
+ "a:xfrm",
405
+ "a:custGeom",
406
+ "a:prstGeom",
407
+ "a:noFill",
408
+ "a:solidFill",
409
+ "a:gradFill",
410
+ "a:blipFill",
411
+ "a:pattFill",
412
+ "a:grpFill",
413
+ "a:ln",
414
+ "a:effectLst",
415
+ "a:effectDag",
416
+ "a:scene3d",
417
+ "a:sp3d",
418
+ "a:extLst",
419
+ )
420
+ xfrm: CT_Transform2D | None = ZeroOrOne( # pyright: ignore[reportAssignmentType]
421
+ "a:xfrm", successors=_tag_seq[1:]
422
+ )
423
+ custGeom: CT_CustomGeometry2D | None = ZeroOrOne( # pyright: ignore[reportAssignmentType]
424
+ "a:custGeom", successors=_tag_seq[2:]
425
+ )
426
+ prstGeom: CT_PresetGeometry2D | None = ZeroOrOne( # pyright: ignore[reportAssignmentType]
427
+ "a:prstGeom", successors=_tag_seq[3:]
428
+ )
429
+ eg_fillProperties = ZeroOrOneChoice(
430
+ (
431
+ Choice("a:noFill"),
432
+ Choice("a:solidFill"),
433
+ Choice("a:gradFill"),
434
+ Choice("a:blipFill"),
435
+ Choice("a:pattFill"),
436
+ Choice("a:grpFill"),
437
+ ),
438
+ successors=_tag_seq[9:],
439
+ )
440
+ ln: CT_LineProperties | None = ZeroOrOne( # pyright: ignore[reportAssignmentType]
441
+ "a:ln", successors=_tag_seq[10:]
442
+ )
443
+ effectLst = ZeroOrOne("a:effectLst", successors=_tag_seq[11:])
444
+ scene3d: CT_Scene3D | None = ZeroOrOne( # pyright: ignore[reportAssignmentType]
445
+ "a:scene3d", successors=_tag_seq[13:]
446
+ )
447
+ sp3d: CT_Shape3D | None = ZeroOrOne( # pyright: ignore[reportAssignmentType]
448
+ "a:sp3d", successors=_tag_seq[14:]
449
+ )
450
+ del _tag_seq
451
+
452
+ @property
453
+ def cx(self):
454
+ """
455
+ Shape width as an instance of Emu, or None if not present.
456
+ """
457
+ cx_str_lst = self.xpath("./a:xfrm/a:ext/@cx")
458
+ if not cx_str_lst:
459
+ return None
460
+ return Emu(cx_str_lst[0])
461
+
462
+ @property
463
+ def cy(self):
464
+ """
465
+ Shape height as an instance of Emu, or None if not present.
466
+ """
467
+ cy_str_lst = self.xpath("./a:xfrm/a:ext/@cy")
468
+ if not cy_str_lst:
469
+ return None
470
+ return Emu(cy_str_lst[0])
471
+
472
+ @property
473
+ def x(self) -> Length | None:
474
+ """Distance between the left edge of the slide and left edge of the shape.
475
+
476
+ 0 if not present.
477
+ """
478
+ x_str_lst = self.xpath("./a:xfrm/a:off/@x")
479
+ if not x_str_lst:
480
+ return None
481
+ return Emu(x_str_lst[0])
482
+
483
+ @property
484
+ def y(self):
485
+ """
486
+ The offset of the top of the shape from the top of the slide, as an
487
+ instance of Emu. None if not present.
488
+ """
489
+ y_str_lst = self.xpath("./a:xfrm/a:off/@y")
490
+ if not y_str_lst:
491
+ return None
492
+ return Emu(y_str_lst[0])
493
+
494
+ def _new_gradFill(self):
495
+ return CT_GradientFillProperties.new_gradFill()
496
+
497
+
498
+ class CT_Transform2D(BaseOxmlElement):
499
+ """`a:xfrm` custom element class.
500
+
501
+ NOTE: this is a composite including CT_GroupTransform2D, which appears
502
+ with the `a:xfrm` tag in a group shape (including a slide `p:spTree`).
503
+ """
504
+
505
+ _tag_seq = ("a:off", "a:ext", "a:chOff", "a:chExt")
506
+ off: CT_Point2D | None = ZeroOrOne( # pyright: ignore[reportAssignmentType]
507
+ "a:off", successors=_tag_seq[1:]
508
+ )
509
+ ext = ZeroOrOne("a:ext", successors=_tag_seq[2:])
510
+ chOff = ZeroOrOne("a:chOff", successors=_tag_seq[3:])
511
+ chExt = ZeroOrOne("a:chExt", successors=_tag_seq[4:])
512
+ del _tag_seq
513
+ rot: float | None = OptionalAttribute( # pyright: ignore[reportAssignmentType]
514
+ "rot", ST_Angle, default=0.0
515
+ )
516
+ flipH = OptionalAttribute("flipH", XsdBoolean, default=False)
517
+ flipV = OptionalAttribute("flipV", XsdBoolean, default=False)
518
+
519
+ @property
520
+ def x(self):
521
+ off = self.off
522
+ if off is None:
523
+ return None
524
+ return off.x
525
+
526
+ @x.setter
527
+ def x(self, value):
528
+ off = self.get_or_add_off()
529
+ off.x = value
530
+
531
+ @property
532
+ def y(self):
533
+ off = self.off
534
+ if off is None:
535
+ return None
536
+ return off.y
537
+
538
+ @y.setter
539
+ def y(self, value):
540
+ off = self.get_or_add_off()
541
+ off.y = value
542
+
543
+ @property
544
+ def cx(self):
545
+ ext = self.ext
546
+ if ext is None:
547
+ return None
548
+ return ext.cx
549
+
550
+ @cx.setter
551
+ def cx(self, value):
552
+ ext = self.get_or_add_ext()
553
+ ext.cx = value
554
+
555
+ @property
556
+ def cy(self):
557
+ ext = self.ext
558
+ if ext is None:
559
+ return None
560
+ return ext.cy
561
+
562
+ @cy.setter
563
+ def cy(self, value):
564
+ ext = self.get_or_add_ext()
565
+ ext.cy = value
566
+
567
+ def _new_ext(self):
568
+ ext = OxmlElement("a:ext")
569
+ ext.cx = 0
570
+ ext.cy = 0
571
+ return ext
572
+
573
+ def _new_off(self):
574
+ off = OxmlElement("a:off")
575
+ off.x = 0
576
+ off.y = 0
577
+ return off