diff options
Diffstat (limited to '.venv/lib/python3.12/site-packages/pptx/shapes/base.py')
-rw-r--r-- | .venv/lib/python3.12/site-packages/pptx/shapes/base.py | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/pptx/shapes/base.py b/.venv/lib/python3.12/site-packages/pptx/shapes/base.py new file mode 100644 index 00000000..75123502 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/pptx/shapes/base.py @@ -0,0 +1,244 @@ +"""Base shape-related objects such as BaseShape.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, cast + +from pptx.action import ActionSetting +from pptx.dml.effect import ShadowFormat +from pptx.shared import ElementProxy +from pptx.util import lazyproperty + +if TYPE_CHECKING: + from pptx.enum.shapes import MSO_SHAPE_TYPE, PP_PLACEHOLDER + from pptx.oxml.shapes import ShapeElement + from pptx.oxml.shapes.shared import CT_Placeholder + from pptx.parts.slide import BaseSlidePart + from pptx.types import ProvidesPart + from pptx.util import Length + + +class BaseShape(object): + """Base class for shape objects. + + Subclasses include |Shape|, |Picture|, and |GraphicFrame|. + """ + + def __init__(self, shape_elm: ShapeElement, parent: ProvidesPart): + super().__init__() + self._element = shape_elm + self._parent = parent + + def __eq__(self, other: object) -> bool: + """|True| if this shape object proxies the same element as *other*. + + Equality for proxy objects is defined as referring to the same XML element, whether or not + they are the same proxy object instance. + """ + if not isinstance(other, BaseShape): + return False + return self._element is other._element + + def __ne__(self, other: object) -> bool: + if not isinstance(other, BaseShape): + return True + return self._element is not other._element + + @lazyproperty + def click_action(self) -> ActionSetting: + """|ActionSetting| instance providing access to click behaviors. + + Click behaviors are hyperlink-like behaviors including jumping to a hyperlink (web page) + or to another slide in the presentation. The click action is that defined on the overall + shape, not a run of text within the shape. An |ActionSetting| object is always returned, + even when no click behavior is defined on the shape. + """ + cNvPr = self._element._nvXxPr.cNvPr # pyright: ignore[reportPrivateUsage] + return ActionSetting(cNvPr, self) + + @property + def element(self) -> ShapeElement: + """`lxml` element for this shape, e.g. a CT_Shape instance. + + Note that manipulating this element improperly can produce an invalid presentation file. + Make sure you know what you're doing if you use this to change the underlying XML. + """ + return self._element + + @property + def has_chart(self) -> bool: + """|True| if this shape is a graphic frame containing a chart object. + + |False| otherwise. When |True|, the chart object can be accessed using the ``.chart`` + property. + """ + # This implementation is unconditionally False, the True version is + # on GraphicFrame subclass. + return False + + @property + def has_table(self) -> bool: + """|True| if this shape is a graphic frame containing a table object. + + |False| otherwise. When |True|, the table object can be accessed using the ``.table`` + property. + """ + # This implementation is unconditionally False, the True version is + # on GraphicFrame subclass. + return False + + @property + def has_text_frame(self) -> bool: + """|True| if this shape can contain text.""" + # overridden on Shape to return True. Only <p:sp> has text frame + return False + + @property + def height(self) -> Length: + """Read/write. Integer distance between top and bottom extents of shape in EMUs.""" + return self._element.cy + + @height.setter + def height(self, value: Length): + self._element.cy = value + + @property + def is_placeholder(self) -> bool: + """True if this shape is a placeholder. + + A shape is a placeholder if it has a <p:ph> element. + """ + return self._element.has_ph_elm + + @property + def left(self) -> Length: + """Integer distance of the left edge of this shape from the left edge of the slide. + + Read/write. Expressed in English Metric Units (EMU) + """ + return self._element.x + + @left.setter + def left(self, value: Length): + self._element.x = value + + @property + def name(self) -> str: + """Name of this shape, e.g. 'Picture 7'.""" + return self._element.shape_name + + @name.setter + def name(self, value: str): + self._element._nvXxPr.cNvPr.name = value # pyright: ignore[reportPrivateUsage] + + @property + def part(self) -> BaseSlidePart: + """The package part containing this shape. + + A |BaseSlidePart| subclass in this case. Access to a slide part should only be required if + you are extending the behavior of |pp| API objects. + """ + return cast("BaseSlidePart", self._parent.part) + + @property + def placeholder_format(self) -> _PlaceholderFormat: + """Provides access to placeholder-specific properties such as placeholder type. + + Raises |ValueError| on access if the shape is not a placeholder. + """ + ph = self._element.ph + if ph is None: + raise ValueError("shape is not a placeholder") + return _PlaceholderFormat(ph) + + @property + def rotation(self) -> float: + """Degrees of clockwise rotation. + + Read/write float. Negative values can be assigned to indicate counter-clockwise rotation, + e.g. assigning -45.0 will change setting to 315.0. + """ + return self._element.rot + + @rotation.setter + def rotation(self, value: float): + self._element.rot = value + + @lazyproperty + def shadow(self) -> ShadowFormat: + """|ShadowFormat| object providing access to shadow for this shape. + + A |ShadowFormat| object is always returned, even when no shadow is + explicitly defined on this shape (i.e. it inherits its shadow + behavior). + """ + return ShadowFormat(self._element.spPr) + + @property + def shape_id(self) -> int: + """Read-only positive integer identifying this shape. + + The id of a shape is unique among all shapes on a slide. + """ + return self._element.shape_id + + @property + def shape_type(self) -> MSO_SHAPE_TYPE: + """A member of MSO_SHAPE_TYPE classifying this shape by type. + + Like ``MSO_SHAPE_TYPE.CHART``. Must be implemented by subclasses. + """ + raise NotImplementedError(f"{type(self).__name__} does not implement `.shape_type`") + + @property + def top(self) -> Length: + """Distance from the top edge of the slide to the top edge of this shape. + + Read/write. Expressed in English Metric Units (EMU) + """ + return self._element.y + + @top.setter + def top(self, value: Length): + self._element.y = value + + @property + def width(self) -> Length: + """Distance between left and right extents of this shape. + + Read/write. Expressed in English Metric Units (EMU). + """ + return self._element.cx + + @width.setter + def width(self, value: Length): + self._element.cx = value + + +class _PlaceholderFormat(ElementProxy): + """Provides properties specific to placeholders, such as the placeholder type. + + Accessed via the :attr:`~.BaseShape.placeholder_format` property of a placeholder shape, + """ + + def __init__(self, element: CT_Placeholder): + super().__init__(element) + self._ph = element + + @property + def element(self) -> CT_Placeholder: + """The `p:ph` element proxied by this object.""" + return self._ph + + @property + def idx(self) -> int: + """Integer placeholder 'idx' attribute.""" + return self._ph.idx + + @property + def type(self) -> PP_PLACEHOLDER: + """Placeholder type. + + A member of the :ref:`PpPlaceholderType` enumeration, e.g. PP_PLACEHOLDER.CHART + """ + return self._ph.type |