ps-python-pptx 1.1.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 (117) hide show
  1. pptx/__init__.py +84 -0
  2. pptx/action.py +270 -0
  3. pptx/api.py +49 -0
  4. pptx/chart/__init__.py +0 -0
  5. pptx/chart/axis.py +523 -0
  6. pptx/chart/category.py +200 -0
  7. pptx/chart/chart.py +280 -0
  8. pptx/chart/data.py +864 -0
  9. pptx/chart/datalabel.py +288 -0
  10. pptx/chart/legend.py +79 -0
  11. pptx/chart/marker.py +70 -0
  12. pptx/chart/plot.py +412 -0
  13. pptx/chart/point.py +101 -0
  14. pptx/chart/series.py +258 -0
  15. pptx/chart/xlsx.py +272 -0
  16. pptx/chart/xmlwriter.py +1840 -0
  17. pptx/dml/__init__.py +0 -0
  18. pptx/dml/chtfmt.py +40 -0
  19. pptx/dml/color.py +301 -0
  20. pptx/dml/effect.py +41 -0
  21. pptx/dml/fill.py +468 -0
  22. pptx/dml/line.py +100 -0
  23. pptx/enum/__init__.py +0 -0
  24. pptx/enum/action.py +71 -0
  25. pptx/enum/base.py +175 -0
  26. pptx/enum/chart.py +492 -0
  27. pptx/enum/dml.py +405 -0
  28. pptx/enum/lang.py +685 -0
  29. pptx/enum/shapes.py +1029 -0
  30. pptx/enum/text.py +371 -0
  31. pptx/exc.py +23 -0
  32. pptx/media.py +197 -0
  33. pptx/opc/__init__.py +0 -0
  34. pptx/opc/constants.py +331 -0
  35. pptx/opc/oxml.py +188 -0
  36. pptx/opc/package.py +762 -0
  37. pptx/opc/packuri.py +109 -0
  38. pptx/opc/serialized.py +296 -0
  39. pptx/opc/shared.py +20 -0
  40. pptx/opc/spec.py +44 -0
  41. pptx/oxml/__init__.py +492 -0
  42. pptx/oxml/action.py +53 -0
  43. pptx/oxml/chart/__init__.py +0 -0
  44. pptx/oxml/chart/axis.py +297 -0
  45. pptx/oxml/chart/chart.py +282 -0
  46. pptx/oxml/chart/datalabel.py +252 -0
  47. pptx/oxml/chart/legend.py +72 -0
  48. pptx/oxml/chart/marker.py +61 -0
  49. pptx/oxml/chart/plot.py +345 -0
  50. pptx/oxml/chart/series.py +254 -0
  51. pptx/oxml/chart/shared.py +219 -0
  52. pptx/oxml/coreprops.py +288 -0
  53. pptx/oxml/dml/__init__.py +0 -0
  54. pptx/oxml/dml/color.py +111 -0
  55. pptx/oxml/dml/fill.py +197 -0
  56. pptx/oxml/dml/line.py +12 -0
  57. pptx/oxml/ns.py +129 -0
  58. pptx/oxml/presentation.py +130 -0
  59. pptx/oxml/shapes/__init__.py +19 -0
  60. pptx/oxml/shapes/autoshape.py +455 -0
  61. pptx/oxml/shapes/connector.py +107 -0
  62. pptx/oxml/shapes/graphfrm.py +342 -0
  63. pptx/oxml/shapes/groupshape.py +280 -0
  64. pptx/oxml/shapes/picture.py +270 -0
  65. pptx/oxml/shapes/shared.py +523 -0
  66. pptx/oxml/simpletypes.py +740 -0
  67. pptx/oxml/slide.py +347 -0
  68. pptx/oxml/table.py +588 -0
  69. pptx/oxml/text.py +748 -0
  70. pptx/oxml/theme.py +29 -0
  71. pptx/oxml/xmlchemy.py +717 -0
  72. pptx/package.py +222 -0
  73. pptx/parts/__init__.py +0 -0
  74. pptx/parts/chart.py +95 -0
  75. pptx/parts/coreprops.py +167 -0
  76. pptx/parts/embeddedpackage.py +93 -0
  77. pptx/parts/image.py +275 -0
  78. pptx/parts/media.py +37 -0
  79. pptx/parts/presentation.py +126 -0
  80. pptx/parts/slide.py +297 -0
  81. pptx/parts/theme.py +13 -0
  82. pptx/presentation.py +113 -0
  83. pptx/py.typed +0 -0
  84. pptx/shapes/__init__.py +26 -0
  85. pptx/shapes/autoshape.py +355 -0
  86. pptx/shapes/base.py +293 -0
  87. pptx/shapes/connector.py +297 -0
  88. pptx/shapes/freeform.py +337 -0
  89. pptx/shapes/graphfrm.py +166 -0
  90. pptx/shapes/group.py +69 -0
  91. pptx/shapes/picture.py +203 -0
  92. pptx/shapes/placeholder.py +407 -0
  93. pptx/shapes/shapetree.py +1190 -0
  94. pptx/shared.py +82 -0
  95. pptx/slide.py +577 -0
  96. pptx/spec.py +632 -0
  97. pptx/table.py +520 -0
  98. pptx/templates/default.pptx +0 -0
  99. pptx/templates/docx-icon.emf +0 -0
  100. pptx/templates/generic-icon.emf +0 -0
  101. pptx/templates/notes.xml +23 -0
  102. pptx/templates/notesMaster.xml +352 -0
  103. pptx/templates/pptx-icon.emf +0 -0
  104. pptx/templates/theme.xml +321 -0
  105. pptx/templates/xlsx-icon.emf +0 -0
  106. pptx/text/__init__.py +0 -0
  107. pptx/text/fonts.py +399 -0
  108. pptx/text/layout.py +325 -0
  109. pptx/text/text.py +770 -0
  110. pptx/theme.py +135 -0
  111. pptx/types.py +36 -0
  112. pptx/util.py +284 -0
  113. ps_python_pptx-1.1.0.dist-info/METADATA +75 -0
  114. ps_python_pptx-1.1.0.dist-info/RECORD +117 -0
  115. ps_python_pptx-1.1.0.dist-info/WHEEL +5 -0
  116. ps_python_pptx-1.1.0.dist-info/licenses/LICENSE +20 -0
  117. ps_python_pptx-1.1.0.dist-info/top_level.txt +1 -0
pptx/dml/fill.py ADDED
@@ -0,0 +1,468 @@
1
+ """DrawingML objects related to fill."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import math
6
+ from collections.abc import Sequence
7
+ from typing import TYPE_CHECKING
8
+
9
+ from pptx.dml.color import ColorFormat, RGBColor
10
+ from pptx.enum.dml import MSO_FILL, MSO_THEME_COLOR
11
+ from pptx.oxml.dml.fill import (
12
+ CT_BlipFillProperties,
13
+ CT_GradientFillProperties,
14
+ CT_GroupFillProperties,
15
+ CT_NoFillProperties,
16
+ CT_PatternFillProperties,
17
+ CT_SolidColorFillProperties,
18
+ )
19
+ from pptx.oxml.xmlchemy import BaseOxmlElement, OxmlElement
20
+ from pptx.shared import ElementProxy
21
+ from pptx.util import lazyproperty
22
+
23
+ if TYPE_CHECKING:
24
+ from pptx.enum.dml import MSO_FILL_TYPE
25
+ from pptx.oxml.xmlchemy import BaseOxmlElement
26
+
27
+
28
+ class FillFormat(object):
29
+ """Provides access to the current fill properties.
30
+
31
+ Also provides methods to change the fill type.
32
+ """
33
+
34
+ def __init__(self, eg_fill_properties_parent: BaseOxmlElement, fill_obj: _Fill):
35
+ super(FillFormat, self).__init__()
36
+ self._xPr = eg_fill_properties_parent
37
+ self._fill = fill_obj
38
+
39
+ @classmethod
40
+ def from_fill_parent(cls, eg_fillProperties_parent: BaseOxmlElement) -> FillFormat:
41
+ """
42
+ Return a |FillFormat| instance initialized to the settings contained
43
+ in *eg_fillProperties_parent*, which must be an element having
44
+ EG_FillProperties in its child element sequence in the XML schema.
45
+ """
46
+ fill_elm = eg_fillProperties_parent.eg_fillProperties
47
+ fill = _Fill(fill_elm)
48
+ fill_format = cls(eg_fillProperties_parent, fill)
49
+ return fill_format
50
+
51
+ @property
52
+ def back_color(self):
53
+ """Return a |ColorFormat| object representing background color.
54
+
55
+ This property is only applicable to pattern fills and lines.
56
+ """
57
+ return self._fill.back_color
58
+
59
+ def background(self):
60
+ """
61
+ Sets the fill type to noFill, i.e. transparent.
62
+ """
63
+ noFill = self._xPr.get_or_change_to_noFill()
64
+ self._fill = _NoFill(noFill)
65
+
66
+ @property
67
+ def fore_color(self):
68
+ """
69
+ Return a |ColorFormat| instance representing the foreground color of
70
+ this fill.
71
+ """
72
+ return self._fill.fore_color
73
+
74
+ def set_gradient(self, stops, *, angle=0.0, radial=False, center=(0.5, 0.5)):
75
+ """Replace the fill with an explicit linear or circular radial gradient.
76
+
77
+ Stops are (position, color) pairs with ascending positions from 0 to 1.
78
+ Colors are RGBColor or MSO_THEME_COLOR values. At least two are required.
79
+ Angle is in counter-clockwise degrees. For radial gradients, center is
80
+ an (x, y) pair of fractions measured from the upper-left corner.
81
+ Invalid arguments leave the existing fill unchanged.
82
+ """
83
+ values = list(stops)
84
+ if len(values) < 2:
85
+ raise ValueError("a gradient requires at least two stops")
86
+ if not isinstance(radial, bool):
87
+ raise TypeError("radial must be bool")
88
+ if not math.isfinite(angle):
89
+ raise ValueError("gradient angle must be finite")
90
+ if len(center) != 2 or any(not math.isfinite(v) or not 0 <= v <= 1 for v in center):
91
+ raise ValueError("center must contain two fractions between 0 and 1")
92
+ gradient = OxmlElement("a:gradFill")
93
+ gradient.set("rotWithShape", "1")
94
+ stop_list = OxmlElement("a:gsLst")
95
+ previous = -1.0
96
+ for position, color in values:
97
+ if not math.isfinite(position) or not previous <= position <= 1 or position < 0:
98
+ raise ValueError("gradient positions must be ascending fractions from 0 to 1")
99
+ previous = position
100
+ stop = OxmlElement("a:gs")
101
+ stop.pos = position
102
+ if isinstance(color, RGBColor):
103
+ color_element = OxmlElement("a:srgbClr")
104
+ color_element.set("val", str(color))
105
+ elif isinstance(color, MSO_THEME_COLOR):
106
+ color_element = OxmlElement("a:schemeClr")
107
+ color_element.set("val", MSO_THEME_COLOR.to_xml(color))
108
+ else:
109
+ raise TypeError("gradient colors must be RGBColor or MSO_THEME_COLOR")
110
+ stop.append(color_element)
111
+ stop_list.append(stop)
112
+ gradient.append(stop_list)
113
+ if radial:
114
+ path = OxmlElement("a:path")
115
+ path.set("path", "circle")
116
+ rect = OxmlElement("a:fillToRect")
117
+ x, y = center
118
+ for name, value in zip(("l", "t", "r", "b"), (x, y, 1 - x, 1 - y)):
119
+ rect.set(name, str(round(value * 100000)))
120
+ path.append(rect)
121
+ gradient.append(path)
122
+ else:
123
+ linear = OxmlElement("a:lin")
124
+ linear.set("ang", str(round(((360.0 - angle) % 360.0) * 60000) % 21600000))
125
+ linear.set("scaled", "0")
126
+ gradient.append(linear)
127
+ old = self._xPr.get_or_change_to_gradFill()
128
+ old.getparent().replace(old, gradient)
129
+ self._fill = _GradFill(gradient)
130
+
131
+ def _set_picture(self, relationship_id):
132
+ """Set a stretched picture fill using a relationship owned by the containing part."""
133
+ fill = self._xPr.get_or_change_to_blipFill()
134
+ fill[:] = []
135
+ blip = OxmlElement("a:blip")
136
+ blip.rEmbed = relationship_id
137
+ fill.append(blip)
138
+ stretch = OxmlElement("a:stretch")
139
+ stretch.append(OxmlElement("a:fillRect"))
140
+ fill.append(stretch)
141
+ self._fill = _BlipFill(fill)
142
+
143
+ def gradient(self):
144
+ """Sets the fill type to gradient.
145
+
146
+ If the fill is not already a gradient, a default gradient is added.
147
+ The default gradient corresponds to the default in the built-in
148
+ PowerPoint "White" template. This gradient is linear at angle
149
+ 90-degrees (upward), with two stops. The first stop is Accent-1 with
150
+ tint 100%, shade 100%, and satMod 130%. The second stop is Accent-1
151
+ with tint 50%, shade 100%, and satMod 350%.
152
+ """
153
+ gradFill = self._xPr.get_or_change_to_gradFill()
154
+ self._fill = _GradFill(gradFill)
155
+
156
+ @property
157
+ def gradient_angle(self):
158
+ """Angle in float degrees of line of a linear gradient.
159
+
160
+ Read/Write. May be |None|, indicating the angle should be inherited
161
+ from the style hierarchy. An angle of 0.0 corresponds to
162
+ a left-to-right gradient. Increasing angles represent
163
+ counter-clockwise rotation of the line, for example 90.0 represents
164
+ a bottom-to-top gradient. Raises |TypeError| when the fill type is
165
+ not MSO_FILL_TYPE.GRADIENT. Raises |ValueError| for a non-linear
166
+ gradient (e.g. a radial gradient).
167
+ """
168
+ if self.type != MSO_FILL.GRADIENT:
169
+ raise TypeError("Fill is not of type MSO_FILL_TYPE.GRADIENT")
170
+ return self._fill.gradient_angle
171
+
172
+ @gradient_angle.setter
173
+ def gradient_angle(self, value):
174
+ if self.type != MSO_FILL.GRADIENT:
175
+ raise TypeError("Fill is not of type MSO_FILL_TYPE.GRADIENT")
176
+ self._fill.gradient_angle = value
177
+
178
+ @property
179
+ def gradient_stops(self):
180
+ """|GradientStops| object providing access to stops of this gradient.
181
+
182
+ Raises |TypeError| when fill is not gradient (call `fill.gradient()`
183
+ first). Each stop represents a color between which the gradient
184
+ smoothly transitions.
185
+ """
186
+ if self.type != MSO_FILL.GRADIENT:
187
+ raise TypeError("Fill is not of type MSO_FILL_TYPE.GRADIENT")
188
+ return self._fill.gradient_stops
189
+
190
+ @property
191
+ def pattern(self):
192
+ """Return member of :ref:`MsoPatternType` indicating fill pattern.
193
+
194
+ Raises |TypeError| when fill is not patterned (call
195
+ `fill.patterned()` first). Returns |None| if no pattern has been set;
196
+ PowerPoint may display the default `PERCENT_5` pattern in this case.
197
+ Assigning |None| will remove any explicit pattern setting, although
198
+ relying on the default behavior is discouraged and may produce
199
+ rendering differences across client applications.
200
+ """
201
+ return self._fill.pattern
202
+
203
+ @pattern.setter
204
+ def pattern(self, pattern_type):
205
+ self._fill.pattern = pattern_type
206
+
207
+ def patterned(self):
208
+ """Selects the pattern fill type.
209
+
210
+ Note that calling this method does not by itself set a foreground or
211
+ background color of the pattern. Rather it enables subsequent
212
+ assignments to properties like fore_color to set the pattern and
213
+ colors.
214
+ """
215
+ pattFill = self._xPr.get_or_change_to_pattFill()
216
+ self._fill = _PattFill(pattFill)
217
+
218
+ def solid(self):
219
+ """
220
+ Sets the fill type to solid, i.e. a solid color. Note that calling
221
+ this method does not set a color or by itself cause the shape to
222
+ appear with a solid color fill; rather it enables subsequent
223
+ assignments to properties like fore_color to set the color.
224
+ """
225
+ solidFill = self._xPr.get_or_change_to_solidFill()
226
+ self._fill = _SolidFill(solidFill)
227
+
228
+ @property
229
+ def type(self) -> MSO_FILL_TYPE:
230
+ """The type of this fill, e.g. `MSO_FILL_TYPE.SOLID`."""
231
+ return self._fill.type
232
+
233
+
234
+ class _Fill(object):
235
+ """
236
+ Object factory for fill object of class matching fill element, such as
237
+ _SolidFill for ``<a:solidFill>``; also serves as the base class for all
238
+ fill classes
239
+ """
240
+
241
+ def __new__(cls, xFill):
242
+ if xFill is None:
243
+ fill_cls = _NoneFill
244
+ elif isinstance(xFill, CT_BlipFillProperties):
245
+ fill_cls = _BlipFill
246
+ elif isinstance(xFill, CT_GradientFillProperties):
247
+ fill_cls = _GradFill
248
+ elif isinstance(xFill, CT_GroupFillProperties):
249
+ fill_cls = _GrpFill
250
+ elif isinstance(xFill, CT_NoFillProperties):
251
+ fill_cls = _NoFill
252
+ elif isinstance(xFill, CT_PatternFillProperties):
253
+ fill_cls = _PattFill
254
+ elif isinstance(xFill, CT_SolidColorFillProperties):
255
+ fill_cls = _SolidFill
256
+ else:
257
+ fill_cls = _Fill
258
+ return super(_Fill, cls).__new__(fill_cls)
259
+
260
+ @property
261
+ def back_color(self):
262
+ """Raise TypeError for types that do not override this property."""
263
+ tmpl = "fill type %s has no background color, call .patterned() first"
264
+ raise TypeError(tmpl % self.__class__.__name__)
265
+
266
+ @property
267
+ def fore_color(self):
268
+ """Raise TypeError for types that do not override this property."""
269
+ tmpl = "fill type %s has no foreground color, call .solid() or .patterned() first"
270
+ raise TypeError(tmpl % self.__class__.__name__)
271
+
272
+ @property
273
+ def pattern(self):
274
+ """Raise TypeError for fills that do not override this property."""
275
+ tmpl = "fill type %s has no pattern, call .patterned() first"
276
+ raise TypeError(tmpl % self.__class__.__name__)
277
+
278
+ @property
279
+ def type(self) -> MSO_FILL_TYPE: # pragma: no cover
280
+ raise NotImplementedError(
281
+ f".type property must be implemented on {self.__class__.__name__}"
282
+ )
283
+
284
+
285
+ class _BlipFill(_Fill):
286
+ @property
287
+ def type(self):
288
+ return MSO_FILL.PICTURE
289
+
290
+
291
+ class _GradFill(_Fill):
292
+ """Proxies an `a:gradFill` element."""
293
+
294
+ def __init__(self, gradFill):
295
+ self._element = self._gradFill = gradFill
296
+
297
+ @property
298
+ def gradient_angle(self):
299
+ """Angle in float degrees of line of a linear gradient.
300
+
301
+ Read/Write. May be |None|, indicating the angle is inherited from the
302
+ style hierarchy. An angle of 0.0 corresponds to a left-to-right
303
+ gradient. Increasing angles represent clockwise rotation of the line,
304
+ for example 90.0 represents a top-to-bottom gradient. Raises
305
+ |TypeError| when the fill type is not MSO_FILL_TYPE.GRADIENT. Raises
306
+ |ValueError| for a non-linear gradient (e.g. a radial gradient).
307
+ """
308
+ # ---case 1: gradient path is explicit, but not linear---
309
+ path = self._gradFill.path
310
+ if path is not None:
311
+ raise ValueError("not a linear gradient")
312
+
313
+ # ---case 2: gradient path is inherited (no a:lin OR a:path)---
314
+ lin = self._gradFill.lin
315
+ if lin is None:
316
+ return None
317
+
318
+ # ---case 3: gradient path is explicitly linear---
319
+ # angle is stored in XML as a clockwise angle, whereas the UI
320
+ # reports it as counter-clockwise from horizontal-pointing-right.
321
+ # Since the UI is consistent with trigonometry conventions, we
322
+ # respect that in the API.
323
+ clockwise_angle = lin.ang
324
+ counter_clockwise_angle = 0.0 if clockwise_angle == 0.0 else (360.0 - clockwise_angle)
325
+ return counter_clockwise_angle
326
+
327
+ @gradient_angle.setter
328
+ def gradient_angle(self, value):
329
+ lin = self._gradFill.lin
330
+ if lin is None:
331
+ raise ValueError("not a linear gradient")
332
+ lin.ang = 360.0 - value
333
+
334
+ @lazyproperty
335
+ def gradient_stops(self):
336
+ """|_GradientStops| object providing access to gradient colors.
337
+
338
+ Each stop represents a color between which the gradient smoothly
339
+ transitions.
340
+ """
341
+ return _GradientStops(self._gradFill.get_or_add_gsLst())
342
+
343
+ @property
344
+ def type(self):
345
+ return MSO_FILL.GRADIENT
346
+
347
+
348
+ class _GrpFill(_Fill):
349
+ @property
350
+ def type(self):
351
+ return MSO_FILL.GROUP
352
+
353
+
354
+ class _NoFill(_Fill):
355
+ @property
356
+ def type(self):
357
+ return MSO_FILL.BACKGROUND
358
+
359
+
360
+ class _NoneFill(_Fill):
361
+ @property
362
+ def type(self):
363
+ return None
364
+
365
+
366
+ class _PattFill(_Fill):
367
+ """Provides access to patterned fill properties."""
368
+
369
+ def __init__(self, pattFill):
370
+ super(_PattFill, self).__init__()
371
+ self._element = self._pattFill = pattFill
372
+
373
+ @lazyproperty
374
+ def back_color(self):
375
+ """Return |ColorFormat| object that controls background color."""
376
+ bgClr = self._pattFill.get_or_add_bgClr()
377
+ return ColorFormat.from_colorchoice_parent(bgClr)
378
+
379
+ @lazyproperty
380
+ def fore_color(self):
381
+ """Return |ColorFormat| object that controls foreground color."""
382
+ fgClr = self._pattFill.get_or_add_fgClr()
383
+ return ColorFormat.from_colorchoice_parent(fgClr)
384
+
385
+ @property
386
+ def pattern(self):
387
+ """Return member of :ref:`MsoPatternType` indicating fill pattern.
388
+
389
+ Returns |None| if no pattern has been set; PowerPoint may display the
390
+ default `PERCENT_5` pattern in this case. Assigning |None| will
391
+ remove any explicit pattern setting.
392
+ """
393
+ return self._pattFill.prst
394
+
395
+ @pattern.setter
396
+ def pattern(self, pattern_type):
397
+ self._pattFill.prst = pattern_type
398
+
399
+ @property
400
+ def type(self):
401
+ return MSO_FILL.PATTERNED
402
+
403
+
404
+ class _SolidFill(_Fill):
405
+ """Provides access to fill properties such as color for solid fills."""
406
+
407
+ def __init__(self, solidFill):
408
+ super(_SolidFill, self).__init__()
409
+ self._solidFill = solidFill
410
+
411
+ @lazyproperty
412
+ def fore_color(self):
413
+ """Return |ColorFormat| object controlling fill color."""
414
+ return ColorFormat.from_colorchoice_parent(self._solidFill)
415
+
416
+ @property
417
+ def type(self):
418
+ return MSO_FILL.SOLID
419
+
420
+
421
+ class _GradientStops(Sequence):
422
+ """Collection of |GradientStop| objects defining gradient colors.
423
+
424
+ A gradient must have a minimum of two stops, but can have as many more
425
+ than that as required to achieve the desired effect (three is perhaps
426
+ most common). Stops are sequenced in the order they are transitioned
427
+ through.
428
+ """
429
+
430
+ def __init__(self, gsLst):
431
+ self._gsLst = gsLst
432
+
433
+ def __getitem__(self, idx):
434
+ return _GradientStop(self._gsLst[idx])
435
+
436
+ def __len__(self):
437
+ return len(self._gsLst)
438
+
439
+
440
+ class _GradientStop(ElementProxy):
441
+ """A single gradient stop.
442
+
443
+ A gradient stop defines a color and a position.
444
+ """
445
+
446
+ def __init__(self, gs):
447
+ super(_GradientStop, self).__init__(gs)
448
+ self._gs = gs
449
+
450
+ @lazyproperty
451
+ def color(self):
452
+ """Return |ColorFormat| object controlling stop color."""
453
+ return ColorFormat.from_colorchoice_parent(self._gs)
454
+
455
+ @property
456
+ def position(self):
457
+ """Location of stop in gradient path as float between 0.0 and 1.0.
458
+
459
+ The value represents a percentage, where 0.0 (0%) represents the
460
+ start of the path and 1.0 (100%) represents the end of the path. For
461
+ a linear gradient, these would represent opposing extents of the
462
+ filled area.
463
+ """
464
+ return self._gs.pos
465
+
466
+ @position.setter
467
+ def position(self, value):
468
+ self._gs.pos = float(value)
pptx/dml/line.py ADDED
@@ -0,0 +1,100 @@
1
+ """DrawingML objects related to line formatting."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pptx.dml.fill import FillFormat
6
+ from pptx.enum.dml import MSO_FILL
7
+ from pptx.util import Emu, lazyproperty
8
+
9
+
10
+ class LineFormat(object):
11
+ """Provides access to line properties such as color, style, and width.
12
+
13
+ A LineFormat object is typically accessed via the ``.line`` property of
14
+ a shape such as |Shape| or |Picture|.
15
+ """
16
+
17
+ def __init__(self, parent):
18
+ super(LineFormat, self).__init__()
19
+ self._parent = parent
20
+
21
+ @lazyproperty
22
+ def color(self):
23
+ """
24
+ The |ColorFormat| instance that provides access to the color settings
25
+ for this line. Essentially a shortcut for ``line.fill.fore_color``.
26
+ As a side-effect, accessing this property causes the line fill type
27
+ to be set to ``MSO_FILL.SOLID``. If this sounds risky for your use
28
+ case, use ``line.fill.type`` to non-destructively discover the
29
+ existing fill type.
30
+ """
31
+ if self.fill.type != MSO_FILL.SOLID:
32
+ self.fill.solid()
33
+ return self.fill.fore_color
34
+
35
+ @property
36
+ def dash_style(self):
37
+ """Return value indicating line style.
38
+
39
+ Returns a member of :ref:`MsoLineDashStyle` indicating line style, or
40
+ |None| if no explicit value has been set. When no explicit value has
41
+ been set, the line dash style is inherited from the style hierarchy.
42
+
43
+ Assigning |None| removes any existing explicitly-defined dash style.
44
+ """
45
+ ln = self._ln
46
+ if ln is None:
47
+ return None
48
+ return ln.prstDash_val
49
+
50
+ @dash_style.setter
51
+ def dash_style(self, dash_style):
52
+ if dash_style is None:
53
+ ln = self._ln
54
+ if ln is None:
55
+ return
56
+ ln._remove_prstDash()
57
+ ln._remove_custDash()
58
+ return
59
+ ln = self._get_or_add_ln()
60
+ ln.prstDash_val = dash_style
61
+
62
+ @lazyproperty
63
+ def fill(self):
64
+ """
65
+ |FillFormat| instance for this line, providing access to fill
66
+ properties such as foreground color.
67
+ """
68
+ ln = self._get_or_add_ln()
69
+ return FillFormat.from_fill_parent(ln)
70
+
71
+ @property
72
+ def width(self):
73
+ """
74
+ The width of the line expressed as an integer number of :ref:`English
75
+ Metric Units <EMU>`. The returned value is an instance of |Length|,
76
+ a value class having properties such as `.inches`, `.cm`, and `.pt`
77
+ for converting the value into convenient units.
78
+ """
79
+ ln = self._ln
80
+ if ln is None:
81
+ return Emu(0)
82
+ return ln.w
83
+
84
+ @width.setter
85
+ def width(self, emu):
86
+ if emu is None:
87
+ emu = 0
88
+ ln = self._get_or_add_ln()
89
+ ln.w = emu
90
+
91
+ def _get_or_add_ln(self):
92
+ """
93
+ Return the ``<a:ln>`` element containing the line format properties
94
+ in the XML.
95
+ """
96
+ return self._parent.get_or_add_ln()
97
+
98
+ @property
99
+ def _ln(self):
100
+ return self._parent.ln
pptx/enum/__init__.py ADDED
File without changes
pptx/enum/action.py ADDED
@@ -0,0 +1,71 @@
1
+ """Enumerations that describe click-action settings."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pptx.enum.base import BaseEnum
6
+
7
+
8
+ class PP_ACTION_TYPE(BaseEnum):
9
+ """
10
+ Specifies the type of a mouse action (click or hover action).
11
+
12
+ Alias: ``PP_ACTION``
13
+
14
+ Example::
15
+
16
+ from pptx.enum.action import PP_ACTION
17
+
18
+ assert shape.click_action.action == PP_ACTION.HYPERLINK
19
+
20
+ MS API name: `PpActionType`
21
+
22
+ https://msdn.microsoft.com/EN-US/library/office/ff744895.aspx
23
+ """
24
+
25
+ END_SHOW = (6, "Slide show ends.")
26
+ """Slide show ends."""
27
+
28
+ FIRST_SLIDE = (3, "Returns to the first slide.")
29
+ """Returns to the first slide."""
30
+
31
+ HYPERLINK = (7, "Hyperlink.")
32
+ """Hyperlink."""
33
+
34
+ LAST_SLIDE = (4, "Moves to the last slide.")
35
+ """Moves to the last slide."""
36
+
37
+ LAST_SLIDE_VIEWED = (5, "Moves to the last slide viewed.")
38
+ """Moves to the last slide viewed."""
39
+
40
+ NAMED_SLIDE = (101, "Moves to slide specified by slide number.")
41
+ """Moves to slide specified by slide number."""
42
+
43
+ NAMED_SLIDE_SHOW = (10, "Runs the slideshow.")
44
+ """Runs the slideshow."""
45
+
46
+ NEXT_SLIDE = (1, "Moves to the next slide.")
47
+ """Moves to the next slide."""
48
+
49
+ NONE = (0, "No action is performed.")
50
+ """No action is performed."""
51
+
52
+ OPEN_FILE = (102, "Opens the specified file.")
53
+ """Opens the specified file."""
54
+
55
+ OLE_VERB = (11, "OLE Verb.")
56
+ """OLE Verb."""
57
+
58
+ PLAY = (12, "Begins the slideshow.")
59
+ """Begins the slideshow."""
60
+
61
+ PREVIOUS_SLIDE = (2, "Moves to the previous slide.")
62
+ """Moves to the previous slide."""
63
+
64
+ RUN_MACRO = (8, "Runs a macro.")
65
+ """Runs a macro."""
66
+
67
+ RUN_PROGRAM = (9, "Runs a program.")
68
+ """Runs a program."""
69
+
70
+
71
+ PP_ACTION = PP_ACTION_TYPE