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.
- pptx2/__init__.py +152 -0
- pptx2/_color.py +75 -0
- pptx2/_slide_importer.py +597 -0
- pptx2/_svg.py +155 -0
- pptx2/_template_applier.py +292 -0
- pptx2/_textstyle.py +187 -0
- pptx2/accessibility.py +365 -0
- pptx2/action.py +270 -0
- pptx2/animation.py +2237 -0
- pptx2/api.py +49 -0
- pptx2/audit.py +258 -0
- pptx2/chart/__init__.py +0 -0
- pptx2/chart/analytics.py +381 -0
- pptx2/chart/axis.py +543 -0
- pptx2/chart/category.py +200 -0
- pptx2/chart/chart.py +670 -0
- pptx2/chart/data.py +864 -0
- pptx2/chart/datalabel.py +406 -0
- pptx2/chart/legend.py +86 -0
- pptx2/chart/marker.py +70 -0
- pptx2/chart/palettes.py +129 -0
- pptx2/chart/plot.py +462 -0
- pptx2/chart/point.py +101 -0
- pptx2/chart/quick_layouts.py +325 -0
- pptx2/chart/series.py +334 -0
- pptx2/chart/xlsx.py +272 -0
- pptx2/chart/xmlwriter.py +1845 -0
- pptx2/compose/__init__.py +28 -0
- pptx2/compose/from_spec.py +1094 -0
- pptx2/design/__init__.py +8 -0
- pptx2/design/components.py +607 -0
- pptx2/design/figures.py +389 -0
- pptx2/design/layout.py +370 -0
- pptx2/design/recipes.py +1967 -0
- pptx2/design/style.py +209 -0
- pptx2/design/tokens.py +915 -0
- pptx2/diagrams.py +754 -0
- pptx2/dml/__init__.py +0 -0
- pptx2/dml/chtfmt.py +40 -0
- pptx2/dml/color.py +496 -0
- pptx2/dml/effect.py +909 -0
- pptx2/dml/fill.py +691 -0
- pptx2/dml/line.py +287 -0
- pptx2/dml/picture.py +212 -0
- pptx2/dml/three_d.py +381 -0
- pptx2/enum/__init__.py +0 -0
- pptx2/enum/action.py +71 -0
- pptx2/enum/animation.py +31 -0
- pptx2/enum/base.py +218 -0
- pptx2/enum/chart.py +574 -0
- pptx2/enum/dml.py +740 -0
- pptx2/enum/lang.py +685 -0
- pptx2/enum/presentation.py +133 -0
- pptx2/enum/shapes.py +1029 -0
- pptx2/enum/text.py +230 -0
- pptx2/exc.py +42 -0
- pptx2/formats.py +139 -0
- pptx2/geometry.py +420 -0
- pptx2/inherit.py +109 -0
- pptx2/lint.py +2256 -0
- pptx2/math.py +177 -0
- pptx2/media.py +197 -0
- pptx2/opc/__init__.py +0 -0
- pptx2/opc/constants.py +332 -0
- pptx2/opc/oxml.py +188 -0
- pptx2/opc/package.py +762 -0
- pptx2/opc/packuri.py +109 -0
- pptx2/opc/serialized.py +296 -0
- pptx2/opc/shared.py +20 -0
- pptx2/opc/spec.py +45 -0
- pptx2/oxml/__init__.py +555 -0
- pptx2/oxml/action.py +53 -0
- pptx2/oxml/chart/__init__.py +0 -0
- pptx2/oxml/chart/axis.py +337 -0
- pptx2/oxml/chart/chart.py +481 -0
- pptx2/oxml/chart/datalabel.py +253 -0
- pptx2/oxml/chart/legend.py +72 -0
- pptx2/oxml/chart/marker.py +61 -0
- pptx2/oxml/chart/plot.py +365 -0
- pptx2/oxml/chart/series.py +425 -0
- pptx2/oxml/chart/shared.py +220 -0
- pptx2/oxml/coreprops.py +288 -0
- pptx2/oxml/dml/__init__.py +0 -0
- pptx2/oxml/dml/color.py +135 -0
- pptx2/oxml/dml/effect.py +213 -0
- pptx2/oxml/dml/fill.py +316 -0
- pptx2/oxml/dml/line.py +12 -0
- pptx2/oxml/dml/three_d.py +110 -0
- pptx2/oxml/ns.py +135 -0
- pptx2/oxml/presentation.py +313 -0
- pptx2/oxml/shapes/__init__.py +19 -0
- pptx2/oxml/shapes/autoshape.py +467 -0
- pptx2/oxml/shapes/connector.py +107 -0
- pptx2/oxml/shapes/graphfrm.py +347 -0
- pptx2/oxml/shapes/groupshape.py +329 -0
- pptx2/oxml/shapes/picture.py +270 -0
- pptx2/oxml/shapes/shared.py +577 -0
- pptx2/oxml/simpletypes.py +1027 -0
- pptx2/oxml/slide.py +563 -0
- pptx2/oxml/table.py +650 -0
- pptx2/oxml/text.py +815 -0
- pptx2/oxml/theme.py +36 -0
- pptx2/oxml/xmlchemy.py +717 -0
- pptx2/package.py +222 -0
- pptx2/parts/__init__.py +0 -0
- pptx2/parts/chart.py +95 -0
- pptx2/parts/coreprops.py +167 -0
- pptx2/parts/diagram.py +37 -0
- pptx2/parts/embeddedpackage.py +93 -0
- pptx2/parts/image.py +275 -0
- pptx2/parts/media.py +37 -0
- pptx2/parts/presentation.py +136 -0
- pptx2/parts/slide.py +371 -0
- pptx2/presentation.py +408 -0
- pptx2/py.typed +0 -0
- pptx2/render.py +586 -0
- pptx2/section.py +272 -0
- pptx2/shapes/__init__.py +26 -0
- pptx2/shapes/autoshape.py +442 -0
- pptx2/shapes/base.py +1078 -0
- pptx2/shapes/connector.py +297 -0
- pptx2/shapes/freeform.py +337 -0
- pptx2/shapes/graphfrm.py +316 -0
- pptx2/shapes/group.py +264 -0
- pptx2/shapes/picture.py +422 -0
- pptx2/shapes/placeholder.py +468 -0
- pptx2/shapes/shapetree.py +2027 -0
- pptx2/shared.py +82 -0
- pptx2/skill/SKILL.md +450 -0
- pptx2/skill/__init__.py +78 -0
- pptx2/skill/__main__.py +64 -0
- pptx2/skill/references/animations.md +189 -0
- pptx2/skill/references/basics.md +421 -0
- pptx2/skill/references/charts.md +254 -0
- pptx2/skill/references/compose.md +234 -0
- pptx2/skill/references/design.md +366 -0
- pptx2/skill/references/effects.md +249 -0
- pptx2/skill/references/end-to-end-deck.md +231 -0
- pptx2/skill/references/geometry-and-arrows.md +334 -0
- pptx2/skill/references/lint.md +275 -0
- pptx2/skill/references/math.md +86 -0
- pptx2/skill/references/picture-effects.md +129 -0
- pptx2/skill/references/render.md +151 -0
- pptx2/skill/references/smart-art.md +75 -0
- pptx2/skill/references/space-aware-authoring.md +249 -0
- pptx2/skill/references/tables.md +244 -0
- pptx2/skill/references/theme.md +127 -0
- pptx2/skill/references/three-d.md +109 -0
- pptx2/skill/references/transitions.md +100 -0
- pptx2/slide.py +1244 -0
- pptx2/smart_art.py +220 -0
- pptx2/spec.py +633 -0
- pptx2/table.py +1181 -0
- pptx2/table_styles.py +184 -0
- pptx2/templates/default.pptx +0 -0
- pptx2/templates/docx-icon.emf +0 -0
- pptx2/templates/generic-icon.emf +0 -0
- pptx2/templates/notes.xml +23 -0
- pptx2/templates/notesMaster.xml +352 -0
- pptx2/templates/pptx-icon.emf +0 -0
- pptx2/templates/theme.xml +321 -0
- pptx2/templates/xlsx-icon.emf +0 -0
- pptx2/text/__init__.py +0 -0
- pptx2/text/fonts.py +482 -0
- pptx2/text/layout.py +374 -0
- pptx2/text/text.py +1272 -0
- pptx2/theme.py +721 -0
- pptx2/types.py +36 -0
- pptx2/util.py +263 -0
- python_pptx2-2.13.0.dist-info/METADATA +351 -0
- python_pptx2-2.13.0.dist-info/RECORD +175 -0
- python_pptx2-2.13.0.dist-info/WHEEL +5 -0
- python_pptx2-2.13.0.dist-info/entry_points.txt +3 -0
- python_pptx2-2.13.0.dist-info/licenses/LICENSE +22 -0
- python_pptx2-2.13.0.dist-info/top_level.txt +1 -0
pptx2/dml/three_d.py
ADDED
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
"""3-D shape formatting objects such as |ThreeDFormat|."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING, Callable
|
|
6
|
+
|
|
7
|
+
from pptx2.dml.color import ColorFormat
|
|
8
|
+
from pptx2.enum.dml import BevelPreset, PresetMaterial
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from pptx2.dml.color import RGBColor
|
|
12
|
+
from pptx2.enum.dml import MSO_COLOR_TYPE, MSO_THEME_COLOR
|
|
13
|
+
from pptx2.oxml.dml.three_d import (
|
|
14
|
+
CT_Bevel,
|
|
15
|
+
CT_ContourColor,
|
|
16
|
+
CT_ExtrusionColor,
|
|
17
|
+
CT_Scene3D,
|
|
18
|
+
CT_Shape3D,
|
|
19
|
+
)
|
|
20
|
+
from pptx2.oxml.shapes.shared import CT_ShapeProperties
|
|
21
|
+
from pptx2.util import Length
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class _LazyThreeDColorFormat:
|
|
25
|
+
"""Non-mutating |ColorFormat| proxy for a 3-D colour slot (extrusion or contour).
|
|
26
|
+
|
|
27
|
+
Reads return the appropriate "no color" sentinels when the parent element does not exist.
|
|
28
|
+
Writes lazily create the element hierarchy.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __init__(
|
|
32
|
+
self,
|
|
33
|
+
peek: Callable[[], CT_ExtrusionColor | CT_ContourColor | None],
|
|
34
|
+
ensure: Callable[[], CT_ExtrusionColor | CT_ContourColor],
|
|
35
|
+
):
|
|
36
|
+
self._peek = peek
|
|
37
|
+
self._ensure = ensure
|
|
38
|
+
|
|
39
|
+
@property
|
|
40
|
+
def type(self) -> MSO_COLOR_TYPE | None:
|
|
41
|
+
cf = self._existing_cf()
|
|
42
|
+
return cf.type if cf is not None else None
|
|
43
|
+
|
|
44
|
+
@property
|
|
45
|
+
def rgb(self) -> RGBColor | None:
|
|
46
|
+
cf = self._existing_cf()
|
|
47
|
+
return cf.rgb if cf is not None else None
|
|
48
|
+
|
|
49
|
+
@rgb.setter
|
|
50
|
+
def rgb(self, value: RGBColor) -> None:
|
|
51
|
+
self._ensure_cf().rgb = value
|
|
52
|
+
|
|
53
|
+
@property
|
|
54
|
+
def theme_color(self) -> MSO_THEME_COLOR:
|
|
55
|
+
from pptx2.enum.dml import MSO_THEME_COLOR
|
|
56
|
+
|
|
57
|
+
cf = self._existing_cf()
|
|
58
|
+
return cf.theme_color if cf is not None else MSO_THEME_COLOR.NOT_THEME_COLOR
|
|
59
|
+
|
|
60
|
+
@theme_color.setter
|
|
61
|
+
def theme_color(self, value: MSO_THEME_COLOR) -> None:
|
|
62
|
+
self._ensure_cf().theme_color = value
|
|
63
|
+
|
|
64
|
+
def _existing_cf(self) -> ColorFormat | None:
|
|
65
|
+
el = self._peek()
|
|
66
|
+
return None if el is None else ColorFormat.from_colorchoice_parent(el)
|
|
67
|
+
|
|
68
|
+
def _ensure_cf(self) -> ColorFormat:
|
|
69
|
+
return ColorFormat.from_colorchoice_parent(self._ensure())
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class _BevelFormat:
|
|
73
|
+
"""Provides access to the bevel on one face (top or bottom) of a 3-D shape.
|
|
74
|
+
|
|
75
|
+
All reads are non-mutating: when the bevel element is absent, ``preset`` returns ``None``
|
|
76
|
+
and the dimension properties return ``None``. Writing any property lazily creates the bevel
|
|
77
|
+
element (and its ``<a:sp3d>`` parent if required).
|
|
78
|
+
"""
|
|
79
|
+
|
|
80
|
+
def __init__(
|
|
81
|
+
self,
|
|
82
|
+
peek: Callable[[], CT_Bevel | None],
|
|
83
|
+
ensure: Callable[[], CT_Bevel],
|
|
84
|
+
remove: Callable[[], None],
|
|
85
|
+
) -> None:
|
|
86
|
+
self._peek = peek
|
|
87
|
+
self._ensure = ensure
|
|
88
|
+
self._remove = remove
|
|
89
|
+
|
|
90
|
+
@property
|
|
91
|
+
def preset(self) -> BevelPreset | None:
|
|
92
|
+
"""Bevel preset (|BevelPreset| member), or ``None`` if not explicitly set."""
|
|
93
|
+
bevel = self._peek()
|
|
94
|
+
return None if bevel is None else bevel.prst
|
|
95
|
+
|
|
96
|
+
@preset.setter
|
|
97
|
+
def preset(self, value: BevelPreset | None) -> None:
|
|
98
|
+
if value is None:
|
|
99
|
+
# -- unset the preset attribute; keep any bevel dimensions in place.
|
|
100
|
+
bevel = self._peek()
|
|
101
|
+
if bevel is not None:
|
|
102
|
+
bevel.prst = None # type: ignore[assignment]
|
|
103
|
+
elif value is BevelPreset.NONE or value == BevelPreset.NONE.value:
|
|
104
|
+
# -- ``BevelPreset.NONE`` means "no bevel". Its ``xml_value`` is the
|
|
105
|
+
# -- token ``"none"``, which the OOXML ``ST_BevelPresetType``
|
|
106
|
+
# -- enumeration does not allow — writing it makes PowerPoint report
|
|
107
|
+
# -- the file as broken. Remove the whole ``<a:bevelT>``/``<a:bevelB>``
|
|
108
|
+
# -- element instead, which is the schema-valid way to say "no bevel".
|
|
109
|
+
# -- Match both the singleton and its raw ``.value`` (an int, e.g.
|
|
110
|
+
# -- deserialized from JSON/config) — the downstream attribute writer
|
|
111
|
+
# -- would otherwise coerce that int back into the invalid token.
|
|
112
|
+
self._remove()
|
|
113
|
+
else:
|
|
114
|
+
self._ensure().prst = value # type: ignore[assignment]
|
|
115
|
+
|
|
116
|
+
@property
|
|
117
|
+
def width(self) -> Length | None:
|
|
118
|
+
"""Bevel width in EMU, or ``None`` if not explicitly set."""
|
|
119
|
+
bevel = self._peek()
|
|
120
|
+
return None if bevel is None else bevel.w
|
|
121
|
+
|
|
122
|
+
@width.setter
|
|
123
|
+
def width(self, value: Length | None) -> None:
|
|
124
|
+
if value is None:
|
|
125
|
+
bevel = self._peek()
|
|
126
|
+
if bevel is not None:
|
|
127
|
+
bevel.w = None # type: ignore[assignment]
|
|
128
|
+
else:
|
|
129
|
+
self._ensure().w = value # type: ignore[assignment]
|
|
130
|
+
|
|
131
|
+
@property
|
|
132
|
+
def height(self) -> Length | None:
|
|
133
|
+
"""Bevel height in EMU, or ``None`` if not explicitly set."""
|
|
134
|
+
bevel = self._peek()
|
|
135
|
+
return None if bevel is None else bevel.h
|
|
136
|
+
|
|
137
|
+
@height.setter
|
|
138
|
+
def height(self, value: Length | None) -> None:
|
|
139
|
+
if value is None:
|
|
140
|
+
bevel = self._peek()
|
|
141
|
+
if bevel is not None:
|
|
142
|
+
bevel.h = None # type: ignore[assignment]
|
|
143
|
+
else:
|
|
144
|
+
self._ensure().h = value # type: ignore[assignment]
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
class ThreeDFormat:
|
|
148
|
+
"""Provides access to 3-D formatting properties on a shape.
|
|
149
|
+
|
|
150
|
+
All property reads are non-mutating: when no 3-D elements are present in the XML the
|
|
151
|
+
properties return ``None``. Writing any property lazily creates the required
|
|
152
|
+
``<a:scene3d>`` and/or ``<a:sp3d>`` elements.
|
|
153
|
+
|
|
154
|
+
Obtain an instance from :attr:`pptx2.shapes.base.BaseShape.three_d`.
|
|
155
|
+
|
|
156
|
+
Example::
|
|
157
|
+
|
|
158
|
+
from pptx2.enum.dml import BevelPreset, PresetMaterial
|
|
159
|
+
from pptx2.util import Pt
|
|
160
|
+
|
|
161
|
+
shape.three_d.bevel_top.preset = BevelPreset.CIRCLE
|
|
162
|
+
shape.three_d.bevel_top.width = Pt(4)
|
|
163
|
+
shape.three_d.extrusion_height = Pt(6)
|
|
164
|
+
shape.three_d.preset_material = PresetMaterial.MATTE
|
|
165
|
+
"""
|
|
166
|
+
|
|
167
|
+
def __init__(self, spPr: CT_ShapeProperties) -> None:
|
|
168
|
+
self._element = spPr
|
|
169
|
+
|
|
170
|
+
# ------------------------------------------------------------------
|
|
171
|
+
# Top bevel
|
|
172
|
+
# ------------------------------------------------------------------
|
|
173
|
+
|
|
174
|
+
@property
|
|
175
|
+
def bevel_top(self) -> _BevelFormat:
|
|
176
|
+
"""``_BevelFormat`` providing access to the top-face bevel.
|
|
177
|
+
|
|
178
|
+
Always returned (non-mutating reads return ``None`` when no bevel is set).
|
|
179
|
+
"""
|
|
180
|
+
return _BevelFormat(
|
|
181
|
+
peek=self._peek_bevelT,
|
|
182
|
+
ensure=self._get_or_add_bevelT,
|
|
183
|
+
remove=self._remove_bevelT,
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
# ------------------------------------------------------------------
|
|
187
|
+
# Bottom bevel
|
|
188
|
+
# ------------------------------------------------------------------
|
|
189
|
+
|
|
190
|
+
@property
|
|
191
|
+
def bevel_bottom(self) -> _BevelFormat:
|
|
192
|
+
"""``_BevelFormat`` providing access to the bottom-face bevel.
|
|
193
|
+
|
|
194
|
+
Always returned (non-mutating reads return ``None`` when no bevel is set).
|
|
195
|
+
"""
|
|
196
|
+
return _BevelFormat(
|
|
197
|
+
peek=self._peek_bevelB,
|
|
198
|
+
ensure=self._get_or_add_bevelB,
|
|
199
|
+
remove=self._remove_bevelB,
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
# ------------------------------------------------------------------
|
|
203
|
+
# Extrusion
|
|
204
|
+
# ------------------------------------------------------------------
|
|
205
|
+
|
|
206
|
+
@property
|
|
207
|
+
def extrusion_height(self) -> Length | None:
|
|
208
|
+
"""Extrusion depth in EMU, or ``None`` if not explicitly set."""
|
|
209
|
+
sp3d = self._sp3d
|
|
210
|
+
return None if sp3d is None else sp3d.extrusionH
|
|
211
|
+
|
|
212
|
+
@extrusion_height.setter
|
|
213
|
+
def extrusion_height(self, value: Length | None) -> None:
|
|
214
|
+
if value is None:
|
|
215
|
+
sp3d = self._sp3d
|
|
216
|
+
if sp3d is not None:
|
|
217
|
+
sp3d.extrusionH = None # type: ignore[assignment]
|
|
218
|
+
else:
|
|
219
|
+
self._get_or_add_sp3d().extrusionH = value # type: ignore[assignment]
|
|
220
|
+
|
|
221
|
+
@property
|
|
222
|
+
def extrusion_color(self) -> _LazyThreeDColorFormat:
|
|
223
|
+
"""Non-mutating color accessor for the extrusion color.
|
|
224
|
+
|
|
225
|
+
Reading any sub-property on a shape with no 3-D extrusion color returns the appropriate
|
|
226
|
+
"no color" sentinel without touching the XML. Writing creates the hierarchy lazily.
|
|
227
|
+
"""
|
|
228
|
+
return _LazyThreeDColorFormat(
|
|
229
|
+
peek=self._peek_extrusionClr,
|
|
230
|
+
ensure=self._get_or_add_extrusionClr,
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
@extrusion_color.setter
|
|
234
|
+
def extrusion_color(self, value: RGBColor) -> None:
|
|
235
|
+
# Convenience setter so ``three_d.extrusion_color = RGBColor(...)`` works
|
|
236
|
+
# in addition to ``three_d.extrusion_color.rgb = RGBColor(...)``.
|
|
237
|
+
self.extrusion_color.rgb = value
|
|
238
|
+
|
|
239
|
+
# ------------------------------------------------------------------
|
|
240
|
+
# Contour
|
|
241
|
+
# ------------------------------------------------------------------
|
|
242
|
+
|
|
243
|
+
@property
|
|
244
|
+
def contour_width(self) -> Length | None:
|
|
245
|
+
"""Contour (edge) width in EMU, or ``None`` if not explicitly set."""
|
|
246
|
+
sp3d = self._sp3d
|
|
247
|
+
return None if sp3d is None else sp3d.contourW
|
|
248
|
+
|
|
249
|
+
@contour_width.setter
|
|
250
|
+
def contour_width(self, value: Length | None) -> None:
|
|
251
|
+
if value is None:
|
|
252
|
+
sp3d = self._sp3d
|
|
253
|
+
if sp3d is not None:
|
|
254
|
+
sp3d.contourW = None # type: ignore[assignment]
|
|
255
|
+
else:
|
|
256
|
+
self._get_or_add_sp3d().contourW = value # type: ignore[assignment]
|
|
257
|
+
|
|
258
|
+
@property
|
|
259
|
+
def contour_color(self) -> _LazyThreeDColorFormat:
|
|
260
|
+
"""Non-mutating color accessor for the contour (edge) color.
|
|
261
|
+
|
|
262
|
+
Reading any sub-property on a shape with no contour color returns the appropriate
|
|
263
|
+
"no color" sentinel without touching the XML. Writing creates the hierarchy lazily.
|
|
264
|
+
"""
|
|
265
|
+
return _LazyThreeDColorFormat(
|
|
266
|
+
peek=self._peek_contourClr,
|
|
267
|
+
ensure=self._get_or_add_contourClr,
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
@contour_color.setter
|
|
271
|
+
def contour_color(self, value: RGBColor) -> None:
|
|
272
|
+
# Convenience setter so ``three_d.contour_color = RGBColor(...)`` works
|
|
273
|
+
# in addition to ``three_d.contour_color.rgb = RGBColor(...)``.
|
|
274
|
+
self.contour_color.rgb = value
|
|
275
|
+
|
|
276
|
+
# ------------------------------------------------------------------
|
|
277
|
+
# Preset material
|
|
278
|
+
# ------------------------------------------------------------------
|
|
279
|
+
|
|
280
|
+
@property
|
|
281
|
+
def preset_material(self) -> PresetMaterial | None:
|
|
282
|
+
"""Surface material preset (|PresetMaterial| member), or ``None`` if not set."""
|
|
283
|
+
sp3d = self._sp3d
|
|
284
|
+
return None if sp3d is None else sp3d.prstMaterial
|
|
285
|
+
|
|
286
|
+
@preset_material.setter
|
|
287
|
+
def preset_material(self, value: PresetMaterial | None) -> None:
|
|
288
|
+
if (
|
|
289
|
+
value is None
|
|
290
|
+
or value is PresetMaterial.NONE
|
|
291
|
+
or value == PresetMaterial.NONE.value
|
|
292
|
+
):
|
|
293
|
+
# -- ``PresetMaterial.NONE`` means "no explicit material". Its
|
|
294
|
+
# -- ``xml_value`` is the token ``"none"``, which the OOXML
|
|
295
|
+
# -- ``ST_PresetMaterialType`` enumeration does not allow — writing
|
|
296
|
+
# -- it makes PowerPoint report the file as broken. Clear the
|
|
297
|
+
# -- attribute instead (the schema-valid way to leave it unset);
|
|
298
|
+
# -- use ``PresetMaterial.FLAT`` for an explicit flat surface.
|
|
299
|
+
# -- Match both the singleton and its raw ``.value`` (an int, e.g.
|
|
300
|
+
# -- deserialized from JSON/config) — the downstream attribute writer
|
|
301
|
+
# -- would otherwise coerce that int back into the invalid token.
|
|
302
|
+
sp3d = self._sp3d
|
|
303
|
+
if sp3d is not None:
|
|
304
|
+
sp3d.prstMaterial = None # type: ignore[assignment]
|
|
305
|
+
else:
|
|
306
|
+
self._get_or_add_sp3d().prstMaterial = value # type: ignore[assignment]
|
|
307
|
+
|
|
308
|
+
# ------------------------------------------------------------------
|
|
309
|
+
# Internals
|
|
310
|
+
# ------------------------------------------------------------------
|
|
311
|
+
|
|
312
|
+
@property
|
|
313
|
+
def _sp3d(self) -> CT_Shape3D | None:
|
|
314
|
+
return self._element.sp3d
|
|
315
|
+
|
|
316
|
+
def _get_or_add_sp3d(self) -> CT_Shape3D:
|
|
317
|
+
"""Return the ``<a:sp3d>`` element, creating scene3d + sp3d pair if absent."""
|
|
318
|
+
sp3d = self._element.sp3d
|
|
319
|
+
if sp3d is None:
|
|
320
|
+
# scene3d must precede sp3d; ensure both are present. PowerPoint
|
|
321
|
+
# flags a deck as corrupt when a slide-level <a:scene3d> is empty
|
|
322
|
+
# while a sibling <a:sp3d> is present, so populate the scene with
|
|
323
|
+
# the same defaults PowerPoint / LibreOffice write themselves.
|
|
324
|
+
scene3d = self._element.get_or_add_scene3d()
|
|
325
|
+
self._init_scene3d_defaults(scene3d)
|
|
326
|
+
sp3d = self._element.get_or_add_sp3d()
|
|
327
|
+
return sp3d
|
|
328
|
+
|
|
329
|
+
@staticmethod
|
|
330
|
+
def _init_scene3d_defaults(scene3d: CT_Scene3D) -> None:
|
|
331
|
+
"""Populate a freshly-created ``<a:scene3d>`` with default scene children.
|
|
332
|
+
|
|
333
|
+
Adds ``<a:camera prst="orthographicFront"/>`` and
|
|
334
|
+
``<a:lightRig rig="threePt" dir="t"/>`` when they are absent. Both are
|
|
335
|
+
required by the OOXML schema; an empty ``<a:scene3d>`` causes Microsoft
|
|
336
|
+
PowerPoint to report the file as broken / unrepairable.
|
|
337
|
+
"""
|
|
338
|
+
if scene3d.camera is None:
|
|
339
|
+
scene3d.get_or_add_camera().prst = "orthographicFront"
|
|
340
|
+
if scene3d.lightRig is None:
|
|
341
|
+
light_rig = scene3d.get_or_add_lightRig()
|
|
342
|
+
light_rig.rig = "threePt"
|
|
343
|
+
light_rig.dir = "t"
|
|
344
|
+
|
|
345
|
+
def _peek_bevelT(self) -> CT_Bevel | None:
|
|
346
|
+
sp3d = self._sp3d
|
|
347
|
+
return None if sp3d is None else sp3d.bevelT
|
|
348
|
+
|
|
349
|
+
def _get_or_add_bevelT(self) -> CT_Bevel:
|
|
350
|
+
return self._get_or_add_sp3d().get_or_add_bevelT()
|
|
351
|
+
|
|
352
|
+
def _peek_bevelB(self) -> CT_Bevel | None:
|
|
353
|
+
sp3d = self._sp3d
|
|
354
|
+
return None if sp3d is None else sp3d.bevelB
|
|
355
|
+
|
|
356
|
+
def _get_or_add_bevelB(self) -> CT_Bevel:
|
|
357
|
+
return self._get_or_add_sp3d().get_or_add_bevelB()
|
|
358
|
+
|
|
359
|
+
def _remove_bevelT(self) -> None:
|
|
360
|
+
sp3d = self._sp3d
|
|
361
|
+
if sp3d is not None:
|
|
362
|
+
sp3d._remove_bevelT()
|
|
363
|
+
|
|
364
|
+
def _remove_bevelB(self) -> None:
|
|
365
|
+
sp3d = self._sp3d
|
|
366
|
+
if sp3d is not None:
|
|
367
|
+
sp3d._remove_bevelB()
|
|
368
|
+
|
|
369
|
+
def _peek_extrusionClr(self) -> CT_ExtrusionColor | None:
|
|
370
|
+
sp3d = self._sp3d
|
|
371
|
+
return None if sp3d is None else sp3d.extrusionClr
|
|
372
|
+
|
|
373
|
+
def _get_or_add_extrusionClr(self) -> CT_ExtrusionColor:
|
|
374
|
+
return self._get_or_add_sp3d().get_or_add_extrusionClr()
|
|
375
|
+
|
|
376
|
+
def _peek_contourClr(self) -> CT_ContourColor | None:
|
|
377
|
+
sp3d = self._sp3d
|
|
378
|
+
return None if sp3d is None else sp3d.contourClr
|
|
379
|
+
|
|
380
|
+
def _get_or_add_contourClr(self) -> CT_ContourColor:
|
|
381
|
+
return self._get_or_add_sp3d().get_or_add_contourClr()
|
pptx2/enum/__init__.py
ADDED
|
File without changes
|
pptx2/enum/action.py
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""Enumerations that describe click-action settings."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pptx2.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 pptx2.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
|
pptx2/enum/animation.py
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""Enumerations for animation-related objects."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pptx2.enum.base import BaseEnum
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class PP_ANIM_TRIGGER(BaseEnum):
|
|
9
|
+
"""Controls when an animation effect starts relative to the previous event.
|
|
10
|
+
|
|
11
|
+
Example::
|
|
12
|
+
|
|
13
|
+
from pptx2.animation import Entrance, Trigger
|
|
14
|
+
|
|
15
|
+
Entrance.fade(slide, shape, trigger=Trigger.ON_CLICK)
|
|
16
|
+
Entrance.fade(slide, shape, trigger=Trigger.WITH_PREVIOUS)
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
ON_CLICK = (1, "Effect starts on the next mouse click.")
|
|
20
|
+
"""Effect starts on the next mouse click."""
|
|
21
|
+
|
|
22
|
+
WITH_PREVIOUS = (2, "Effect starts at the same time as the preceding effect.")
|
|
23
|
+
"""Effect starts at the same time as the preceding effect."""
|
|
24
|
+
|
|
25
|
+
AFTER_PREVIOUS = (3, "Effect starts immediately after the preceding effect finishes.")
|
|
26
|
+
"""Effect starts immediately after the preceding effect finishes."""
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
#: Convenience alias – ``Trigger.ON_CLICK`` reads more naturally than
|
|
30
|
+
#: ``PP_ANIM_TRIGGER.ON_CLICK`` in application code.
|
|
31
|
+
Trigger = PP_ANIM_TRIGGER
|