about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/openpyxl/comments/shape_writer.py
diff options
context:
space:
mode:
Diffstat (limited to '.venv/lib/python3.12/site-packages/openpyxl/comments/shape_writer.py')
-rw-r--r--.venv/lib/python3.12/site-packages/openpyxl/comments/shape_writer.py112
1 files changed, 112 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/openpyxl/comments/shape_writer.py b/.venv/lib/python3.12/site-packages/openpyxl/comments/shape_writer.py
new file mode 100644
index 00000000..cebfbc3d
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/openpyxl/comments/shape_writer.py
@@ -0,0 +1,112 @@
+# Copyright (c) 2010-2024 openpyxl
+
+from openpyxl.xml.functions import (
+    Element,
+    SubElement,
+    tostring,
+)
+
+from openpyxl.utils import coordinate_to_tuple
+
+vmlns = "urn:schemas-microsoft-com:vml"
+officens = "urn:schemas-microsoft-com:office:office"
+excelns = "urn:schemas-microsoft-com:office:excel"
+
+
+class ShapeWriter:
+    """
+    Create VML for comments
+    """
+
+    vml = None
+    vml_path = None
+
+
+    def __init__(self, comments):
+        self.comments = comments
+
+
+    def add_comment_shapetype(self, root):
+        shape_layout = SubElement(root, "{%s}shapelayout" % officens,
+                                  {"{%s}ext" % vmlns: "edit"})
+        SubElement(shape_layout,
+                   "{%s}idmap" % officens,
+                   {"{%s}ext" % vmlns: "edit", "data": "1"})
+        shape_type = SubElement(root,
+                                "{%s}shapetype" % vmlns,
+                                {"id": "_x0000_t202",
+                                 "coordsize": "21600,21600",
+                                 "{%s}spt" % officens: "202",
+                                 "path": "m,l,21600r21600,l21600,xe"})
+        SubElement(shape_type, "{%s}stroke" % vmlns, {"joinstyle": "miter"})
+        SubElement(shape_type,
+                   "{%s}path" % vmlns,
+                   {"gradientshapeok": "t",
+                    "{%s}connecttype" % officens: "rect"})
+
+
+    def add_comment_shape(self, root, idx, coord, height, width):
+        row, col = coordinate_to_tuple(coord)
+        row -= 1
+        col -= 1
+        shape = _shape_factory(row, col, height, width)
+
+        shape.set('id', "_x0000_s%04d" % idx)
+        root.append(shape)
+
+
+    def write(self, root):
+
+        if not hasattr(root, "findall"):
+            root = Element("xml")
+
+        # Remove any existing comment shapes
+        comments = root.findall("{%s}shape[@type='#_x0000_t202']" % vmlns)
+        for c in comments:
+            root.remove(c)
+
+        # check whether comments shape type already exists
+        shape_types = root.find("{%s}shapetype[@id='_x0000_t202']" % vmlns)
+        if shape_types is None:
+            self.add_comment_shapetype(root)
+
+        for idx, (coord, comment) in enumerate(self.comments, 1026):
+            self.add_comment_shape(root, idx, coord, comment.height, comment.width)
+
+        return tostring(root)
+
+
+def _shape_factory(row, column, height, width):
+    style = ("position:absolute; "
+             "margin-left:59.25pt;"
+             "margin-top:1.5pt;"
+             "width:{width}px;"
+             "height:{height}px;"
+             "z-index:1;"
+             "visibility:hidden").format(height=height,
+                                         width=width)
+    attrs = {
+        "type": "#_x0000_t202",
+        "style": style,
+        "fillcolor": "#ffffe1",
+        "{%s}insetmode" % officens: "auto"
+    }
+    shape = Element("{%s}shape" % vmlns, attrs)
+
+    SubElement(shape, "{%s}fill" % vmlns,
+               {"color2": "#ffffe1"})
+    SubElement(shape, "{%s}shadow" % vmlns,
+               {"color": "black", "obscured": "t"})
+    SubElement(shape, "{%s}path" % vmlns,
+               {"{%s}connecttype" % officens: "none"})
+    textbox = SubElement(shape, "{%s}textbox" % vmlns,
+                         {"style": "mso-direction-alt:auto"})
+    SubElement(textbox, "div", {"style": "text-align:left"})
+    client_data = SubElement(shape, "{%s}ClientData" % excelns,
+                             {"ObjectType": "Note"})
+    SubElement(client_data, "{%s}MoveWithCells" % excelns)
+    SubElement(client_data, "{%s}SizeWithCells" % excelns)
+    SubElement(client_data, "{%s}AutoFill" % excelns).text = "False"
+    SubElement(client_data, "{%s}Row" % excelns).text = str(row)
+    SubElement(client_data, "{%s}Column" % excelns).text = str(column)
+    return shape