Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/openpyxl/comments/shape_writer.py: 25%

51 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2023-07-17 14:22 -0600

1# Copyright (c) 2010-2022 openpyxl 

2 

3from openpyxl.xml.functions import ( 

4 Element, 

5 SubElement, 

6 tostring, 

7 fromstring, 

8) 

9 

10from openpyxl.utils import ( 

11 column_index_from_string, 

12 coordinate_to_tuple, 

13) 

14 

15vmlns = "urn:schemas-microsoft-com:vml" 

16officens = "urn:schemas-microsoft-com:office:office" 

17excelns = "urn:schemas-microsoft-com:office:excel" 

18 

19 

20class ShapeWriter(object): 

21 """ 

22 Create VML for comments 

23 """ 

24 

25 vml = None 

26 vml_path = None 

27 

28 

29 def __init__(self, comments): 

30 self.comments = comments 

31 

32 

33 def add_comment_shapetype(self, root): 

34 shape_layout = SubElement(root, "{%s}shapelayout" % officens, 

35 {"{%s}ext" % vmlns: "edit"}) 

36 SubElement(shape_layout, 

37 "{%s}idmap" % officens, 

38 {"{%s}ext" % vmlns: "edit", "data": "1"}) 

39 shape_type = SubElement(root, 

40 "{%s}shapetype" % vmlns, 

41 {"id": "_x0000_t202", 

42 "coordsize": "21600,21600", 

43 "{%s}spt" % officens: "202", 

44 "path": "m,l,21600r21600,l21600,xe"}) 

45 SubElement(shape_type, "{%s}stroke" % vmlns, {"joinstyle": "miter"}) 

46 SubElement(shape_type, 

47 "{%s}path" % vmlns, 

48 {"gradientshapeok": "t", 

49 "{%s}connecttype" % officens: "rect"}) 

50 

51 

52 def add_comment_shape(self, root, idx, coord, height, width): 

53 row, col = coordinate_to_tuple(coord) 

54 row -= 1 

55 col -= 1 

56 shape = _shape_factory(row, col, height, width) 

57 

58 shape.set('id', "_x0000_s%04d" % idx) 

59 root.append(shape) 

60 

61 

62 def write(self, root): 

63 

64 if not hasattr(root, "findall"): 

65 root = Element("xml") 

66 

67 # Remove any existing comment shapes 

68 comments = root.findall("{%s}shape[@type='#_x0000_t202']" % vmlns) 

69 for c in comments: 

70 root.remove(c) 

71 

72 # check whether comments shape type already exists 

73 shape_types = root.find("{%s}shapetype[@id='_x0000_t202']" % vmlns) 

74 if not shape_types: 

75 self.add_comment_shapetype(root) 

76 

77 for idx, (coord, comment) in enumerate(self.comments, 1026): 

78 self.add_comment_shape(root, idx, coord, comment.height, comment.width) 

79 

80 return tostring(root) 

81 

82 

83def _shape_factory(row, column, height, width): 

84 style = ("position:absolute; " 

85 "margin-left:59.25pt;" 

86 "margin-top:1.5pt;" 

87 "width:{width}px;" 

88 "height:{height}px;" 

89 "z-index:1;" 

90 "visibility:hidden").format(height=height, 

91 width=width) 

92 attrs = { 

93 "type": "#_x0000_t202", 

94 "style": style, 

95 "fillcolor": "#ffffe1", 

96 "{%s}insetmode" % officens: "auto" 

97 } 

98 shape = Element("{%s}shape" % vmlns, attrs) 

99 

100 SubElement(shape, "{%s}fill" % vmlns, 

101 {"color2": "#ffffe1"}) 

102 SubElement(shape, "{%s}shadow" % vmlns, 

103 {"color": "black", "obscured": "t"}) 

104 SubElement(shape, "{%s}path" % vmlns, 

105 {"{%s}connecttype" % officens: "none"}) 

106 textbox = SubElement(shape, "{%s}textbox" % vmlns, 

107 {"style": "mso-direction-alt:auto"}) 

108 SubElement(textbox, "div", {"style": "text-align:left"}) 

109 client_data = SubElement(shape, "{%s}ClientData" % excelns, 

110 {"ObjectType": "Note"}) 

111 SubElement(client_data, "{%s}MoveWithCells" % excelns) 

112 SubElement(client_data, "{%s}SizeWithCells" % excelns) 

113 SubElement(client_data, "{%s}AutoFill" % excelns).text = "False" 

114 SubElement(client_data, "{%s}Row" % excelns).text = str(row) 

115 SubElement(client_data, "{%s}Column" % excelns).text = str(column) 

116 return shape