about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/pptx/oxml/shapes/autoshape.py
diff options
context:
space:
mode:
authorS. Solomon Darnell2025-03-28 21:52:21 -0500
committerS. Solomon Darnell2025-03-28 21:52:21 -0500
commit4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch)
treeee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/pptx/oxml/shapes/autoshape.py
parentcc961e04ba734dd72309fb548a2f97d67d578813 (diff)
downloadgn-ai-master.tar.gz
two version of R2R are here HEAD master
Diffstat (limited to '.venv/lib/python3.12/site-packages/pptx/oxml/shapes/autoshape.py')
-rw-r--r--.venv/lib/python3.12/site-packages/pptx/oxml/shapes/autoshape.py455
1 files changed, 455 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/pptx/oxml/shapes/autoshape.py b/.venv/lib/python3.12/site-packages/pptx/oxml/shapes/autoshape.py
new file mode 100644
index 00000000..5d78f624
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/pptx/oxml/shapes/autoshape.py
@@ -0,0 +1,455 @@
+# pyright: reportPrivateUsage=false
+
+"""lxml custom element classes for shape-related XML elements."""
+
+from __future__ import annotations
+
+from typing import TYPE_CHECKING, Callable, cast
+
+from pptx.enum.shapes import MSO_AUTO_SHAPE_TYPE, PP_PLACEHOLDER
+from pptx.oxml import parse_xml
+from pptx.oxml.ns import nsdecls
+from pptx.oxml.shapes.shared import BaseShapeElement
+from pptx.oxml.simpletypes import (
+    ST_Coordinate,
+    ST_PositiveCoordinate,
+    XsdBoolean,
+    XsdString,
+)
+from pptx.oxml.text import CT_TextBody
+from pptx.oxml.xmlchemy import (
+    BaseOxmlElement,
+    OneAndOnlyOne,
+    OptionalAttribute,
+    RequiredAttribute,
+    ZeroOrMore,
+    ZeroOrOne,
+)
+
+if TYPE_CHECKING:
+    from pptx.oxml.shapes.shared import (
+        CT_ApplicationNonVisualDrawingProps,
+        CT_NonVisualDrawingProps,
+        CT_ShapeProperties,
+    )
+    from pptx.util import Length
+
+
+class CT_AdjPoint2D(BaseOxmlElement):
+    """`a:pt` custom element class."""
+
+    x: Length = RequiredAttribute("x", ST_Coordinate)  # pyright: ignore[reportAssignmentType]
+    y: Length = RequiredAttribute("y", ST_Coordinate)  # pyright: ignore[reportAssignmentType]
+
+
+class CT_CustomGeometry2D(BaseOxmlElement):
+    """`a:custGeom` custom element class."""
+
+    get_or_add_pathLst: Callable[[], CT_Path2DList]
+
+    _tag_seq = ("a:avLst", "a:gdLst", "a:ahLst", "a:cxnLst", "a:rect", "a:pathLst")
+    pathLst: CT_Path2DList | None = ZeroOrOne(  # pyright: ignore[reportAssignmentType]
+        "a:pathLst", successors=_tag_seq[6:]
+    )
+
+
+class CT_GeomGuide(BaseOxmlElement):
+    """`a:gd` custom element class.
+
+    Defines a "guide", corresponding to a yellow diamond-shaped handle on an autoshape.
+    """
+
+    name: str = RequiredAttribute("name", XsdString)  # pyright: ignore[reportAssignmentType]
+    fmla: str = RequiredAttribute("fmla", XsdString)  # pyright: ignore[reportAssignmentType]
+
+
+class CT_GeomGuideList(BaseOxmlElement):
+    """`a:avLst` custom element class."""
+
+    _add_gd: Callable[[], CT_GeomGuide]
+
+    gd_lst: list[CT_GeomGuide]
+
+    gd = ZeroOrMore("a:gd")
+
+
+class CT_NonVisualDrawingShapeProps(BaseShapeElement):
+    """`p:cNvSpPr` custom element class."""
+
+    spLocks = ZeroOrOne("a:spLocks")
+    txBox: bool | None = OptionalAttribute(  # pyright: ignore[reportAssignmentType]
+        "txBox", XsdBoolean
+    )
+
+
+class CT_Path2D(BaseOxmlElement):
+    """`a:path` custom element class."""
+
+    _add_close: Callable[[], CT_Path2DClose]
+    _add_lnTo: Callable[[], CT_Path2DLineTo]
+    _add_moveTo: Callable[[], CT_Path2DMoveTo]
+
+    close = ZeroOrMore("a:close", successors=())
+    lnTo = ZeroOrMore("a:lnTo", successors=())
+    moveTo = ZeroOrMore("a:moveTo", successors=())
+    w: Length | None = OptionalAttribute(  # pyright: ignore[reportAssignmentType]
+        "w", ST_PositiveCoordinate
+    )
+    h: Length | None = OptionalAttribute(  # pyright: ignore[reportAssignmentType]
+        "h", ST_PositiveCoordinate
+    )
+
+    def add_close(self) -> CT_Path2DClose:
+        """Return a newly created `a:close` element.
+
+        The new `a:close` element is appended to this `a:path` element.
+        """
+        return self._add_close()
+
+    def add_lnTo(self, x: Length, y: Length) -> CT_Path2DLineTo:
+        """Return a newly created `a:lnTo` subtree with end point *(x, y)*.
+
+        The new `a:lnTo` element is appended to this `a:path` element.
+        """
+        lnTo = self._add_lnTo()
+        pt = lnTo._add_pt()
+        pt.x, pt.y = x, y
+        return lnTo
+
+    def add_moveTo(self, x: Length, y: Length):
+        """Return a newly created `a:moveTo` subtree with point `(x, y)`.
+
+        The new `a:moveTo` element is appended to this `a:path` element.
+        """
+        moveTo = self._add_moveTo()
+        pt = moveTo._add_pt()
+        pt.x, pt.y = x, y
+        return moveTo
+
+
+class CT_Path2DClose(BaseOxmlElement):
+    """`a:close` custom element class."""
+
+
+class CT_Path2DLineTo(BaseOxmlElement):
+    """`a:lnTo` custom element class."""
+
+    _add_pt: Callable[[], CT_AdjPoint2D]
+
+    pt = ZeroOrOne("a:pt", successors=())
+
+
+class CT_Path2DList(BaseOxmlElement):
+    """`a:pathLst` custom element class."""
+
+    _add_path: Callable[[], CT_Path2D]
+
+    path = ZeroOrMore("a:path", successors=())
+
+    def add_path(self, w: Length, h: Length):
+        """Return a newly created `a:path` child element."""
+        path = self._add_path()
+        path.w, path.h = w, h
+        return path
+
+
+class CT_Path2DMoveTo(BaseOxmlElement):
+    """`a:moveTo` custom element class."""
+
+    _add_pt: Callable[[], CT_AdjPoint2D]
+
+    pt = ZeroOrOne("a:pt", successors=())
+
+
+class CT_PresetGeometry2D(BaseOxmlElement):
+    """`a:prstGeom` custom element class."""
+
+    _add_avLst: Callable[[], CT_GeomGuideList]
+    _remove_avLst: Callable[[], None]
+
+    avLst: CT_GeomGuideList | None = ZeroOrOne("a:avLst")  # pyright: ignore[reportAssignmentType]
+    prst: MSO_AUTO_SHAPE_TYPE = RequiredAttribute(  # pyright: ignore[reportAssignmentType]
+        "prst", MSO_AUTO_SHAPE_TYPE
+    )
+
+    @property
+    def gd_lst(self) -> list[CT_GeomGuide]:
+        """Sequence of `a:gd` element children of `a:avLst`. Empty if none are present."""
+        avLst = self.avLst
+        if avLst is None:
+            return []
+        return avLst.gd_lst
+
+    def rewrite_guides(self, guides: list[tuple[str, int]]):
+        """Replace any `a:gd` element children of `a:avLst` with ones forme from `guides`."""
+        self._remove_avLst()
+        avLst = self._add_avLst()
+        for name, val in guides:
+            gd = avLst._add_gd()
+            gd.name = name
+            gd.fmla = "val %d" % val
+
+
+class CT_Shape(BaseShapeElement):
+    """`p:sp` custom element class."""
+
+    get_or_add_txBody: Callable[[], CT_TextBody]
+
+    nvSpPr: CT_ShapeNonVisual = OneAndOnlyOne("p:nvSpPr")  # pyright: ignore[reportAssignmentType]
+    spPr: CT_ShapeProperties = OneAndOnlyOne("p:spPr")  # pyright: ignore[reportAssignmentType]
+    txBody: CT_TextBody | None = ZeroOrOne("p:txBody", successors=("p:extLst",))  # pyright: ignore
+
+    def add_path(self, w: Length, h: Length) -> CT_Path2D:
+        custGeom = self.spPr.custGeom
+        if custGeom is None:
+            raise ValueError("shape must be freeform")
+        pathLst = custGeom.get_or_add_pathLst()
+        return pathLst.add_path(w=w, h=h)
+
+    def get_or_add_ln(self):
+        """Return the `a:ln` grandchild element, newly added if not present."""
+        return self.spPr.get_or_add_ln()
+
+    @property
+    def has_custom_geometry(self):
+        """True if this shape has custom geometry, i.e. is a freeform shape.
+
+        A shape has custom geometry if it has a `p:spPr/a:custGeom`
+        descendant (instead of `p:spPr/a:prstGeom`).
+        """
+        return self.spPr.custGeom is not None
+
+    @property
+    def is_autoshape(self):
+        """True if this shape is an auto shape.
+
+        A shape is an auto shape if it has a `a:prstGeom` element and does not have a txBox="1"
+        attribute on cNvSpPr.
+        """
+        prstGeom = self.prstGeom
+        if prstGeom is None:
+            return False
+        return self.nvSpPr.cNvSpPr.txBox is not True
+
+    @property
+    def is_textbox(self):
+        """True if this shape is a text box.
+
+        A shape is a text box if it has a `txBox` attribute on cNvSpPr that resolves to |True|.
+        The default when the txBox attribute is missing is |False|.
+        """
+        return self.nvSpPr.cNvSpPr.txBox is True
+
+    @property
+    def ln(self):
+        """`a:ln` grand-child element or |None| if not present."""
+        return self.spPr.ln
+
+    @staticmethod
+    def new_autoshape_sp(
+        id_: int, name: str, prst: str, left: int, top: int, width: int, height: int
+    ) -> CT_Shape:
+        """Return a new `p:sp` element tree configured as a base auto shape."""
+        xml = (
+            "<p:sp %s>\n"
+            "  <p:nvSpPr>\n"
+            '    <p:cNvPr id="%s" name="%s"/>\n'
+            "    <p:cNvSpPr/>\n"
+            "    <p:nvPr/>\n"
+            "  </p:nvSpPr>\n"
+            "  <p:spPr>\n"
+            "    <a:xfrm>\n"
+            '      <a:off x="%s" y="%s"/>\n'
+            '      <a:ext cx="%s" cy="%s"/>\n'
+            "    </a:xfrm>\n"
+            '    <a:prstGeom prst="%s">\n'
+            "      <a:avLst/>\n"
+            "    </a:prstGeom>\n"
+            "  </p:spPr>\n"
+            "  <p:style>\n"
+            '    <a:lnRef idx="1">\n'
+            '      <a:schemeClr val="accent1"/>\n'
+            "    </a:lnRef>\n"
+            '    <a:fillRef idx="3">\n'
+            '      <a:schemeClr val="accent1"/>\n'
+            "    </a:fillRef>\n"
+            '    <a:effectRef idx="2">\n'
+            '      <a:schemeClr val="accent1"/>\n'
+            "    </a:effectRef>\n"
+            '    <a:fontRef idx="minor">\n'
+            '      <a:schemeClr val="lt1"/>\n'
+            "    </a:fontRef>\n"
+            "  </p:style>\n"
+            "  <p:txBody>\n"
+            '    <a:bodyPr rtlCol="0" anchor="ctr"/>\n'
+            "    <a:lstStyle/>\n"
+            "    <a:p>\n"
+            '      <a:pPr algn="ctr"/>\n'
+            "    </a:p>\n"
+            "  </p:txBody>\n"
+            "</p:sp>" % (nsdecls("a", "p"), "%d", "%s", "%d", "%d", "%d", "%d", "%s")
+        ) % (id_, name, left, top, width, height, prst)
+        return cast(CT_Shape, parse_xml(xml))
+
+    @staticmethod
+    def new_freeform_sp(shape_id: int, name: str, x: int, y: int, cx: int, cy: int):
+        """Return new `p:sp` element tree configured as freeform shape.
+
+        The returned shape has a `a:custGeom` subtree but no paths in its
+        path list.
+        """
+        xml = (
+            "<p:sp %s>\n"
+            "  <p:nvSpPr>\n"
+            '    <p:cNvPr id="%s" name="%s"/>\n'
+            "    <p:cNvSpPr/>\n"
+            "    <p:nvPr/>\n"
+            "  </p:nvSpPr>\n"
+            "  <p:spPr>\n"
+            "    <a:xfrm>\n"
+            '      <a:off x="%s" y="%s"/>\n'
+            '      <a:ext cx="%s" cy="%s"/>\n'
+            "    </a:xfrm>\n"
+            "    <a:custGeom>\n"
+            "      <a:avLst/>\n"
+            "      <a:gdLst/>\n"
+            "      <a:ahLst/>\n"
+            "      <a:cxnLst/>\n"
+            '      <a:rect l="l" t="t" r="r" b="b"/>\n'
+            "      <a:pathLst/>\n"
+            "    </a:custGeom>\n"
+            "  </p:spPr>\n"
+            "  <p:style>\n"
+            '    <a:lnRef idx="1">\n'
+            '      <a:schemeClr val="accent1"/>\n'
+            "    </a:lnRef>\n"
+            '    <a:fillRef idx="3">\n'
+            '      <a:schemeClr val="accent1"/>\n'
+            "    </a:fillRef>\n"
+            '    <a:effectRef idx="2">\n'
+            '      <a:schemeClr val="accent1"/>\n'
+            "    </a:effectRef>\n"
+            '    <a:fontRef idx="minor">\n'
+            '      <a:schemeClr val="lt1"/>\n'
+            "    </a:fontRef>\n"
+            "  </p:style>\n"
+            "  <p:txBody>\n"
+            '    <a:bodyPr rtlCol="0" anchor="ctr"/>\n'
+            "    <a:lstStyle/>\n"
+            "    <a:p>\n"
+            '      <a:pPr algn="ctr"/>\n'
+            "    </a:p>\n"
+            "  </p:txBody>\n"
+            "</p:sp>" % (nsdecls("a", "p"), "%d", "%s", "%d", "%d", "%d", "%d")
+        ) % (shape_id, name, x, y, cx, cy)
+        return cast(CT_Shape, parse_xml(xml))
+
+    @staticmethod
+    def new_placeholder_sp(
+        id_: int, name: str, ph_type: PP_PLACEHOLDER, orient: str, sz, idx
+    ) -> CT_Shape:
+        """Return a new `p:sp` element tree configured as a placeholder shape."""
+        sp = cast(
+            CT_Shape,
+            parse_xml(
+                f"<p:sp {nsdecls('a', 'p')}>\n"
+                f"  <p:nvSpPr>\n"
+                f'    <p:cNvPr id="{id_}" name="{name}"/>\n'
+                f"    <p:cNvSpPr>\n"
+                f'      <a:spLocks noGrp="1"/>\n'
+                f"    </p:cNvSpPr>\n"
+                f"    <p:nvPr/>\n"
+                f"  </p:nvSpPr>\n"
+                f"  <p:spPr/>\n"
+                f"</p:sp>"
+            ),
+        )
+
+        ph = sp.nvSpPr.nvPr.get_or_add_ph()
+        ph.type = ph_type
+        ph.idx = idx
+        ph.orient = orient
+        ph.sz = sz
+
+        placeholder_types_that_have_a_text_frame = (
+            PP_PLACEHOLDER.TITLE,
+            PP_PLACEHOLDER.CENTER_TITLE,
+            PP_PLACEHOLDER.SUBTITLE,
+            PP_PLACEHOLDER.BODY,
+            PP_PLACEHOLDER.OBJECT,
+        )
+
+        if ph_type in placeholder_types_that_have_a_text_frame:
+            sp.append(CT_TextBody.new())
+
+        return sp
+
+    @staticmethod
+    def new_textbox_sp(id_, name, left, top, width, height):
+        """Return a new `p:sp` element tree configured as a base textbox shape."""
+        tmpl = CT_Shape._textbox_sp_tmpl()
+        xml = tmpl % (id_, name, left, top, width, height)
+        sp = parse_xml(xml)
+        return sp
+
+    @property
+    def prst(self):
+        """Value of `prst` attribute of `a:prstGeom` element or |None| if not present."""
+        prstGeom = self.prstGeom
+        if prstGeom is None:
+            return None
+        return prstGeom.prst
+
+    @property
+    def prstGeom(self) -> CT_PresetGeometry2D:
+        """Reference to `a:prstGeom` child element.
+
+        |None| if this shape doesn't have one, for example, if it's a placeholder shape.
+        """
+        return self.spPr.prstGeom
+
+    def _new_txBody(self):
+        return CT_TextBody.new_p_txBody()
+
+    @staticmethod
+    def _textbox_sp_tmpl():
+        return (
+            "<p:sp %s>\n"
+            "  <p:nvSpPr>\n"
+            '    <p:cNvPr id="%s" name="%s"/>\n'
+            '    <p:cNvSpPr txBox="1"/>\n'
+            "    <p:nvPr/>\n"
+            "  </p:nvSpPr>\n"
+            "  <p:spPr>\n"
+            "    <a:xfrm>\n"
+            '      <a:off x="%s" y="%s"/>\n'
+            '      <a:ext cx="%s" cy="%s"/>\n'
+            "    </a:xfrm>\n"
+            '    <a:prstGeom prst="rect">\n'
+            "      <a:avLst/>\n"
+            "    </a:prstGeom>\n"
+            "    <a:noFill/>\n"
+            "  </p:spPr>\n"
+            "  <p:txBody>\n"
+            '    <a:bodyPr wrap="none">\n'
+            "      <a:spAutoFit/>\n"
+            "    </a:bodyPr>\n"
+            "    <a:lstStyle/>\n"
+            "    <a:p/>\n"
+            "  </p:txBody>\n"
+            "</p:sp>" % (nsdecls("a", "p"), "%d", "%s", "%d", "%d", "%d", "%d")
+        )
+
+
+class CT_ShapeNonVisual(BaseShapeElement):
+    """`p:nvSpPr` custom element class."""
+
+    cNvPr: CT_NonVisualDrawingProps = OneAndOnlyOne(  # pyright: ignore[reportAssignmentType]
+        "p:cNvPr"
+    )
+    cNvSpPr: CT_NonVisualDrawingShapeProps = OneAndOnlyOne(  # pyright: ignore[reportAssignmentType]
+        "p:cNvSpPr"
+    )
+    nvPr: CT_ApplicationNonVisualDrawingProps = (  # pyright: ignore[reportAssignmentType]
+        OneAndOnlyOne("p:nvPr")
+    )