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
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
"""Placeholder-related objects.
|
|
2
|
+
|
|
3
|
+
Specific to shapes having a `p:ph` element. A placeholder has distinct behaviors
|
|
4
|
+
depending on whether it appears on a slide, layout, or master. Hence there is a
|
|
5
|
+
non-trivial class inheritance structure.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from typing import TYPE_CHECKING
|
|
11
|
+
|
|
12
|
+
from pptx2.enum.shapes import MSO_SHAPE_TYPE, PP_PLACEHOLDER
|
|
13
|
+
from pptx2.oxml.shapes.graphfrm import CT_GraphicalObjectFrame
|
|
14
|
+
from pptx2.oxml.shapes.picture import CT_Picture
|
|
15
|
+
from pptx2.shapes.autoshape import Shape
|
|
16
|
+
from pptx2.shapes.graphfrm import GraphicFrame
|
|
17
|
+
from pptx2.shapes.picture import Picture
|
|
18
|
+
from pptx2.util import Emu
|
|
19
|
+
|
|
20
|
+
if TYPE_CHECKING:
|
|
21
|
+
from pptx2.oxml.shapes.autoshape import CT_Shape
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class _InheritsDimensions(object):
|
|
25
|
+
"""
|
|
26
|
+
Mixin class that provides inherited dimension behavior. Specifically,
|
|
27
|
+
left, top, width, and height report the value from the layout placeholder
|
|
28
|
+
where they would have otherwise reported |None|. This behavior is
|
|
29
|
+
distinctive to placeholders. :meth:`_base_placeholder` must be overridden
|
|
30
|
+
by all subclasses to provide lookup of the appropriate base placeholder
|
|
31
|
+
to inherit from.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
@property
|
|
35
|
+
def height(self):
|
|
36
|
+
"""
|
|
37
|
+
The effective height of this placeholder shape; its directly-applied
|
|
38
|
+
height if it has one, otherwise the height of its parent layout
|
|
39
|
+
placeholder.
|
|
40
|
+
"""
|
|
41
|
+
return self._effective_value("height")
|
|
42
|
+
|
|
43
|
+
@height.setter
|
|
44
|
+
def height(self, value):
|
|
45
|
+
# ``cy`` shares its parent element with the sibling dimension, so
|
|
46
|
+
# writing it materialises that sibling too -- at zero unless the
|
|
47
|
+
# inherited value is pinned down first. See ``_freeze_sibling``.
|
|
48
|
+
self._freeze_sibling("height")
|
|
49
|
+
self._element.cy = value
|
|
50
|
+
|
|
51
|
+
@property
|
|
52
|
+
def left(self):
|
|
53
|
+
"""
|
|
54
|
+
The effective left of this placeholder shape; its directly-applied
|
|
55
|
+
left if it has one, otherwise the left of its parent layout
|
|
56
|
+
placeholder.
|
|
57
|
+
"""
|
|
58
|
+
return self._effective_value("left")
|
|
59
|
+
|
|
60
|
+
@left.setter
|
|
61
|
+
def left(self, value):
|
|
62
|
+
# ``x`` shares its parent element with the sibling dimension, so
|
|
63
|
+
# writing it materialises that sibling too -- at zero unless the
|
|
64
|
+
# inherited value is pinned down first. See ``_freeze_sibling``.
|
|
65
|
+
self._freeze_sibling("left")
|
|
66
|
+
self._element.x = value
|
|
67
|
+
|
|
68
|
+
@property
|
|
69
|
+
def shape_type(self):
|
|
70
|
+
"""
|
|
71
|
+
Member of :ref:`MsoShapeType` specifying the type of this shape.
|
|
72
|
+
Unconditionally ``MSO_SHAPE_TYPE.PLACEHOLDER`` in this case.
|
|
73
|
+
Read-only.
|
|
74
|
+
"""
|
|
75
|
+
return MSO_SHAPE_TYPE.PLACEHOLDER
|
|
76
|
+
|
|
77
|
+
@property
|
|
78
|
+
def top(self):
|
|
79
|
+
"""
|
|
80
|
+
The effective top of this placeholder shape; its directly-applied
|
|
81
|
+
top if it has one, otherwise the top of its parent layout
|
|
82
|
+
placeholder.
|
|
83
|
+
"""
|
|
84
|
+
return self._effective_value("top")
|
|
85
|
+
|
|
86
|
+
@top.setter
|
|
87
|
+
def top(self, value):
|
|
88
|
+
# ``y`` shares its parent element with the sibling dimension, so
|
|
89
|
+
# writing it materialises that sibling too -- at zero unless the
|
|
90
|
+
# inherited value is pinned down first. See ``_freeze_sibling``.
|
|
91
|
+
self._freeze_sibling("top")
|
|
92
|
+
self._element.y = value
|
|
93
|
+
|
|
94
|
+
@property
|
|
95
|
+
def width(self):
|
|
96
|
+
"""
|
|
97
|
+
The effective width of this placeholder shape; its directly-applied
|
|
98
|
+
width if it has one, otherwise the width of its parent layout
|
|
99
|
+
placeholder.
|
|
100
|
+
"""
|
|
101
|
+
return self._effective_value("width")
|
|
102
|
+
|
|
103
|
+
@width.setter
|
|
104
|
+
def width(self, value):
|
|
105
|
+
# ``cx`` shares its parent element with the sibling dimension, so
|
|
106
|
+
# writing it materialises that sibling too -- at zero unless the
|
|
107
|
+
# inherited value is pinned down first. See ``_freeze_sibling``.
|
|
108
|
+
self._freeze_sibling("width")
|
|
109
|
+
self._element.cx = value
|
|
110
|
+
|
|
111
|
+
#: The dimension each setter must pin down before writing, because the
|
|
112
|
+
#: two share one XML element: ``left``/``top`` live in ``<a:off>`` and
|
|
113
|
+
#: ``width``/``height`` in ``<a:ext>``.
|
|
114
|
+
_SIBLING_DIMENSION = {
|
|
115
|
+
"left": "top",
|
|
116
|
+
"top": "left",
|
|
117
|
+
"width": "height",
|
|
118
|
+
"height": "width",
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
_ELEMENT_ATTR = {"left": "x", "top": "y", "width": "cx", "height": "cy"}
|
|
122
|
+
|
|
123
|
+
def _freeze_sibling(self, attr_name):
|
|
124
|
+
"""Write the inherited sibling of *attr_name* before it is clobbered.
|
|
125
|
+
|
|
126
|
+
A placeholder with no directly-applied geometry has neither
|
|
127
|
+
``<a:off>`` nor ``<a:ext>``; both dimensions come from the layout.
|
|
128
|
+
Setting just one of them creates the shared element, and the
|
|
129
|
+
dimension the caller did *not* set is written as ``0`` -- so
|
|
130
|
+
``body.width = Inches(4)`` used to silently collapse the height to
|
|
131
|
+
nothing and make the shape invisible, with no warning.
|
|
132
|
+
|
|
133
|
+
Copying the currently-inherited sibling across first makes a
|
|
134
|
+
single-dimension assignment mean what it reads as: change this one,
|
|
135
|
+
leave the other where the layout put it. A sibling that is already
|
|
136
|
+
directly applied is left alone, and so is a placeholder that
|
|
137
|
+
inherits nothing.
|
|
138
|
+
"""
|
|
139
|
+
sibling = self._SIBLING_DIMENSION[attr_name]
|
|
140
|
+
directly_applied = getattr(super(_InheritsDimensions, self), sibling)
|
|
141
|
+
if directly_applied is not None:
|
|
142
|
+
return
|
|
143
|
+
try:
|
|
144
|
+
inherited = self._inherited_value(sibling)
|
|
145
|
+
except Exception:
|
|
146
|
+
# Resolving the base placeholder needs a slide part and a
|
|
147
|
+
# layout to walk up to. A placeholder built outside that
|
|
148
|
+
# graph has nothing to inherit, and this is a best-effort
|
|
149
|
+
# improvement -- it must never turn an assignment that used
|
|
150
|
+
# to work into one that raises.
|
|
151
|
+
return
|
|
152
|
+
if inherited is None:
|
|
153
|
+
return
|
|
154
|
+
setattr(self._element, self._ELEMENT_ATTR[sibling], inherited)
|
|
155
|
+
|
|
156
|
+
@property
|
|
157
|
+
def _base_placeholder(self):
|
|
158
|
+
"""
|
|
159
|
+
Return the layout or master placeholder shape this placeholder
|
|
160
|
+
inherits from. Not to be confused with an instance of
|
|
161
|
+
|BasePlaceholder| (necessarily).
|
|
162
|
+
"""
|
|
163
|
+
raise NotImplementedError("Must be implemented by all subclasses.")
|
|
164
|
+
|
|
165
|
+
def _effective_value(self, attr_name):
|
|
166
|
+
"""
|
|
167
|
+
The effective value of *attr_name* on this placeholder shape; its
|
|
168
|
+
directly-applied value if it has one, otherwise the value on the
|
|
169
|
+
layout placeholder it inherits from.
|
|
170
|
+
"""
|
|
171
|
+
directly_applied_value = getattr(super(_InheritsDimensions, self), attr_name)
|
|
172
|
+
if directly_applied_value is not None:
|
|
173
|
+
return directly_applied_value
|
|
174
|
+
return self._inherited_value(attr_name)
|
|
175
|
+
|
|
176
|
+
def _inherited_value(self, attr_name):
|
|
177
|
+
"""
|
|
178
|
+
Return the attribute value, e.g. 'width' of the base placeholder this
|
|
179
|
+
placeholder inherits from.
|
|
180
|
+
"""
|
|
181
|
+
base_placeholder = self._base_placeholder
|
|
182
|
+
if base_placeholder is None:
|
|
183
|
+
return None
|
|
184
|
+
inherited_value = getattr(base_placeholder, attr_name)
|
|
185
|
+
return inherited_value
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
class _BaseSlidePlaceholder(_InheritsDimensions, Shape):
|
|
189
|
+
"""Base class for placeholders on slides.
|
|
190
|
+
|
|
191
|
+
Provides common behaviors such as inherited dimensions.
|
|
192
|
+
"""
|
|
193
|
+
|
|
194
|
+
@property
|
|
195
|
+
def is_placeholder(self):
|
|
196
|
+
"""
|
|
197
|
+
Boolean indicating whether this shape is a placeholder.
|
|
198
|
+
Unconditionally |True| in this case.
|
|
199
|
+
"""
|
|
200
|
+
return True
|
|
201
|
+
|
|
202
|
+
@property
|
|
203
|
+
def shape_type(self):
|
|
204
|
+
"""
|
|
205
|
+
Member of :ref:`MsoShapeType` specifying the type of this shape.
|
|
206
|
+
Unconditionally ``MSO_SHAPE_TYPE.PLACEHOLDER`` in this case.
|
|
207
|
+
Read-only.
|
|
208
|
+
"""
|
|
209
|
+
return MSO_SHAPE_TYPE.PLACEHOLDER
|
|
210
|
+
|
|
211
|
+
@property
|
|
212
|
+
def _base_placeholder(self):
|
|
213
|
+
"""
|
|
214
|
+
Return the layout placeholder this slide placeholder inherits from.
|
|
215
|
+
Not to be confused with an instance of |BasePlaceholder|
|
|
216
|
+
(necessarily).
|
|
217
|
+
"""
|
|
218
|
+
layout, idx = self.part.slide_layout, self._element.ph_idx
|
|
219
|
+
return layout.placeholders.get(idx=idx)
|
|
220
|
+
|
|
221
|
+
def _replace_placeholder_with(self, element):
|
|
222
|
+
"""
|
|
223
|
+
Substitute *element* for this placeholder element in the shapetree.
|
|
224
|
+
This placeholder's `._element` attribute is set to |None| and its
|
|
225
|
+
original element is free for garbage collection. Any attribute access
|
|
226
|
+
(including a method call) on this placeholder after this call raises
|
|
227
|
+
|AttributeError|.
|
|
228
|
+
"""
|
|
229
|
+
element._nvXxPr.nvPr._insert_ph(self._element.ph)
|
|
230
|
+
self._element.addprevious(element)
|
|
231
|
+
self._element.getparent().remove(self._element)
|
|
232
|
+
self._element = None
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
class BasePlaceholder(Shape):
|
|
236
|
+
"""
|
|
237
|
+
NOTE: This class is deprecated and will be removed from a future release
|
|
238
|
+
along with the properties *idx*, *orient*, *ph_type*, and *sz*. The *idx*
|
|
239
|
+
property will be available via the .placeholder_format property. The
|
|
240
|
+
others will be accessed directly from the oxml layer as they are only
|
|
241
|
+
used for internal purposes.
|
|
242
|
+
|
|
243
|
+
Base class for placeholder subclasses that differentiate the varying
|
|
244
|
+
behaviors of placeholders on a master, layout, and slide.
|
|
245
|
+
"""
|
|
246
|
+
|
|
247
|
+
@property
|
|
248
|
+
def idx(self):
|
|
249
|
+
"""
|
|
250
|
+
Integer placeholder 'idx' attribute, e.g. 0
|
|
251
|
+
"""
|
|
252
|
+
return self._sp.ph_idx
|
|
253
|
+
|
|
254
|
+
@property
|
|
255
|
+
def orient(self):
|
|
256
|
+
"""
|
|
257
|
+
Placeholder orientation, e.g. ST_Direction.HORZ
|
|
258
|
+
"""
|
|
259
|
+
return self._sp.ph_orient
|
|
260
|
+
|
|
261
|
+
@property
|
|
262
|
+
def ph_type(self):
|
|
263
|
+
"""
|
|
264
|
+
Placeholder type, e.g. PP_PLACEHOLDER.CENTER_TITLE
|
|
265
|
+
"""
|
|
266
|
+
return self._sp.ph_type
|
|
267
|
+
|
|
268
|
+
@property
|
|
269
|
+
def sz(self):
|
|
270
|
+
"""
|
|
271
|
+
Placeholder 'sz' attribute, e.g. ST_PlaceholderSize.FULL
|
|
272
|
+
"""
|
|
273
|
+
return self._sp.ph_sz
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
class LayoutPlaceholder(_InheritsDimensions, Shape):
|
|
277
|
+
"""Placeholder shape on a slide layout.
|
|
278
|
+
|
|
279
|
+
Provides differentiated behavior for slide layout placeholders, in particular, inheriting
|
|
280
|
+
shape properties from the master placeholder having the same type, when a matching one exists.
|
|
281
|
+
"""
|
|
282
|
+
|
|
283
|
+
element: CT_Shape # pyright: ignore[reportIncompatibleMethodOverride]
|
|
284
|
+
|
|
285
|
+
@property
|
|
286
|
+
def _base_placeholder(self):
|
|
287
|
+
"""
|
|
288
|
+
Return the master placeholder this layout placeholder inherits from.
|
|
289
|
+
"""
|
|
290
|
+
base_ph_type = {
|
|
291
|
+
PP_PLACEHOLDER.BODY: PP_PLACEHOLDER.BODY,
|
|
292
|
+
PP_PLACEHOLDER.CHART: PP_PLACEHOLDER.BODY,
|
|
293
|
+
PP_PLACEHOLDER.BITMAP: PP_PLACEHOLDER.BODY,
|
|
294
|
+
PP_PLACEHOLDER.CENTER_TITLE: PP_PLACEHOLDER.TITLE,
|
|
295
|
+
PP_PLACEHOLDER.ORG_CHART: PP_PLACEHOLDER.BODY,
|
|
296
|
+
PP_PLACEHOLDER.DATE: PP_PLACEHOLDER.DATE,
|
|
297
|
+
PP_PLACEHOLDER.FOOTER: PP_PLACEHOLDER.FOOTER,
|
|
298
|
+
PP_PLACEHOLDER.MEDIA_CLIP: PP_PLACEHOLDER.BODY,
|
|
299
|
+
PP_PLACEHOLDER.OBJECT: PP_PLACEHOLDER.BODY,
|
|
300
|
+
PP_PLACEHOLDER.PICTURE: PP_PLACEHOLDER.BODY,
|
|
301
|
+
PP_PLACEHOLDER.SLIDE_NUMBER: PP_PLACEHOLDER.SLIDE_NUMBER,
|
|
302
|
+
PP_PLACEHOLDER.SUBTITLE: PP_PLACEHOLDER.BODY,
|
|
303
|
+
PP_PLACEHOLDER.TABLE: PP_PLACEHOLDER.BODY,
|
|
304
|
+
PP_PLACEHOLDER.TITLE: PP_PLACEHOLDER.TITLE,
|
|
305
|
+
}[self._element.ph_type]
|
|
306
|
+
slide_master = self.part.slide_master
|
|
307
|
+
return slide_master.placeholders.get(base_ph_type, None)
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
class MasterPlaceholder(BasePlaceholder):
|
|
311
|
+
"""Placeholder shape on a slide master."""
|
|
312
|
+
|
|
313
|
+
element: CT_Shape # pyright: ignore[reportIncompatibleMethodOverride]
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
class NotesSlidePlaceholder(_InheritsDimensions, Shape):
|
|
317
|
+
"""
|
|
318
|
+
Placeholder shape on a notes slide. Inherits shape properties from the
|
|
319
|
+
placeholder on the notes master that has the same type (e.g. 'body').
|
|
320
|
+
"""
|
|
321
|
+
|
|
322
|
+
@property
|
|
323
|
+
def _base_placeholder(self):
|
|
324
|
+
"""
|
|
325
|
+
Return the notes master placeholder this notes slide placeholder
|
|
326
|
+
inherits from, or |None| if no placeholder of the matching type is
|
|
327
|
+
present.
|
|
328
|
+
"""
|
|
329
|
+
notes_master = self.part.notes_master
|
|
330
|
+
ph_type = self.element.ph_type
|
|
331
|
+
return notes_master.placeholders.get(ph_type=ph_type)
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
class SlidePlaceholder(_BaseSlidePlaceholder):
|
|
335
|
+
"""
|
|
336
|
+
Placeholder shape on a slide. Inherits shape properties from its
|
|
337
|
+
corresponding slide layout placeholder.
|
|
338
|
+
"""
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
class ChartPlaceholder(_BaseSlidePlaceholder):
|
|
342
|
+
"""Placeholder shape that can only accept a chart."""
|
|
343
|
+
|
|
344
|
+
def insert_chart(self, chart_type, chart_data):
|
|
345
|
+
"""
|
|
346
|
+
Return a |PlaceholderGraphicFrame| object containing a new chart of
|
|
347
|
+
*chart_type* depicting *chart_data* and having the same position and
|
|
348
|
+
size as this placeholder. *chart_type* is one of the
|
|
349
|
+
:ref:`XlChartType` enumeration values. *chart_data* is a |ChartData|
|
|
350
|
+
object populated with the categories and series values for the chart.
|
|
351
|
+
Note that the new |Chart| object is not returned directly. The chart
|
|
352
|
+
object may be accessed using the
|
|
353
|
+
:attr:`~.PlaceholderGraphicFrame.chart` property of the returned
|
|
354
|
+
|PlaceholderGraphicFrame| object.
|
|
355
|
+
"""
|
|
356
|
+
rId = self.part.add_chart_part(chart_type, chart_data)
|
|
357
|
+
graphicFrame = self._new_chart_graphicFrame(
|
|
358
|
+
rId, self.left, self.top, self.width, self.height
|
|
359
|
+
)
|
|
360
|
+
self._replace_placeholder_with(graphicFrame)
|
|
361
|
+
return PlaceholderGraphicFrame(graphicFrame, self._parent)
|
|
362
|
+
|
|
363
|
+
def _new_chart_graphicFrame(self, rId, x, y, cx, cy):
|
|
364
|
+
"""
|
|
365
|
+
Return a newly created `p:graphicFrame` element having the specified
|
|
366
|
+
position and size and containing the chart identified by *rId*.
|
|
367
|
+
"""
|
|
368
|
+
id_, name = self.shape_id, self.name
|
|
369
|
+
return CT_GraphicalObjectFrame.new_chart_graphicFrame(id_, name, rId, x, y, cx, cy)
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
class PicturePlaceholder(_BaseSlidePlaceholder):
|
|
373
|
+
"""Placeholder shape that can only accept a picture."""
|
|
374
|
+
|
|
375
|
+
def insert_picture(self, image_file):
|
|
376
|
+
"""Return a |PlaceholderPicture| object depicting the image in `image_file`.
|
|
377
|
+
|
|
378
|
+
`image_file` may be either a path (string) or a file-like object. The image is
|
|
379
|
+
cropped to fill the entire space of the placeholder. A |PlaceholderPicture|
|
|
380
|
+
object has all the properties and methods of a |Picture| shape except that the
|
|
381
|
+
value of its :attr:`~._BaseSlidePlaceholder.shape_type` property is
|
|
382
|
+
`MSO_SHAPE_TYPE.PLACEHOLDER` instead of `MSO_SHAPE_TYPE.PICTURE`.
|
|
383
|
+
"""
|
|
384
|
+
pic = self._new_placeholder_pic(image_file)
|
|
385
|
+
self._replace_placeholder_with(pic)
|
|
386
|
+
return PlaceholderPicture(pic, self._parent)
|
|
387
|
+
|
|
388
|
+
def _new_placeholder_pic(self, image_file):
|
|
389
|
+
"""
|
|
390
|
+
Return a new `p:pic` element depicting the image in *image_file*,
|
|
391
|
+
suitable for use as a placeholder. In particular this means not
|
|
392
|
+
having an `a:xfrm` element, allowing its extents to be inherited from
|
|
393
|
+
its layout placeholder.
|
|
394
|
+
"""
|
|
395
|
+
rId, desc, image_size = self._get_or_add_image(image_file)
|
|
396
|
+
shape_id, name = self.shape_id, self.name
|
|
397
|
+
pic = CT_Picture.new_ph_pic(shape_id, name, desc, rId)
|
|
398
|
+
pic.crop_to_fit(image_size, (self.width, self.height))
|
|
399
|
+
return pic
|
|
400
|
+
|
|
401
|
+
def _get_or_add_image(self, image_file):
|
|
402
|
+
"""
|
|
403
|
+
Return an (rId, description, image_size) 3-tuple identifying the
|
|
404
|
+
related image part containing *image_file* and describing the image.
|
|
405
|
+
"""
|
|
406
|
+
image_part, rId = self.part.get_or_add_image_part(image_file)
|
|
407
|
+
desc, image_size = image_part.desc, image_part._px_size
|
|
408
|
+
return rId, desc, image_size
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
class PlaceholderGraphicFrame(GraphicFrame):
|
|
412
|
+
"""
|
|
413
|
+
Placeholder shape populated with a table, chart, or smart art.
|
|
414
|
+
"""
|
|
415
|
+
|
|
416
|
+
@property
|
|
417
|
+
def is_placeholder(self):
|
|
418
|
+
"""
|
|
419
|
+
Boolean indicating whether this shape is a placeholder.
|
|
420
|
+
Unconditionally |True| in this case.
|
|
421
|
+
"""
|
|
422
|
+
return True
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
class PlaceholderPicture(_InheritsDimensions, Picture):
|
|
426
|
+
"""
|
|
427
|
+
Placeholder shape populated with a picture.
|
|
428
|
+
"""
|
|
429
|
+
|
|
430
|
+
@property
|
|
431
|
+
def _base_placeholder(self):
|
|
432
|
+
"""
|
|
433
|
+
Return the layout placeholder this picture placeholder inherits from.
|
|
434
|
+
"""
|
|
435
|
+
layout, idx = self.part.slide_layout, self._element.ph_idx
|
|
436
|
+
return layout.placeholders.get(idx=idx)
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
class TablePlaceholder(_BaseSlidePlaceholder):
|
|
440
|
+
"""Placeholder shape that can only accept a table."""
|
|
441
|
+
|
|
442
|
+
def insert_table(self, rows, cols):
|
|
443
|
+
"""Return |PlaceholderGraphicFrame| object containing a `rows` by `cols` table.
|
|
444
|
+
|
|
445
|
+
The position and width of the table are those of the placeholder and its height
|
|
446
|
+
is proportional to the number of rows. A |PlaceholderGraphicFrame| object has
|
|
447
|
+
all the properties and methods of a |GraphicFrame| shape except that the value
|
|
448
|
+
of its :attr:`~._BaseSlidePlaceholder.shape_type` property is unconditionally
|
|
449
|
+
`MSO_SHAPE_TYPE.PLACEHOLDER`. Note that the return value is not the new table
|
|
450
|
+
but rather *contains* the new table. The table can be accessed using the
|
|
451
|
+
:attr:`~.PlaceholderGraphicFrame.table` property of the returned
|
|
452
|
+
|PlaceholderGraphicFrame| object.
|
|
453
|
+
"""
|
|
454
|
+
graphicFrame = self._new_placeholder_table(rows, cols)
|
|
455
|
+
self._replace_placeholder_with(graphicFrame)
|
|
456
|
+
return PlaceholderGraphicFrame(graphicFrame, self._parent)
|
|
457
|
+
|
|
458
|
+
def _new_placeholder_table(self, rows, cols):
|
|
459
|
+
"""
|
|
460
|
+
Return a newly added `p:graphicFrame` element containing an empty
|
|
461
|
+
table with *rows* rows and *cols* columns, positioned at the location
|
|
462
|
+
of this placeholder and having its same width. The table's height is
|
|
463
|
+
determined by the number of rows.
|
|
464
|
+
"""
|
|
465
|
+
shape_id, name, height = self.shape_id, self.name, Emu(rows * 370840)
|
|
466
|
+
return CT_GraphicalObjectFrame.new_table_graphicFrame(
|
|
467
|
+
shape_id, name, rows, cols, self.left, self.top, self.width, height
|
|
468
|
+
)
|