Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/openpyxl/comments/comment_sheet.py: 86%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

114 statements  

1# Copyright (c) 2010-2024 openpyxl 

2 

3## Incomplete! 

4from openpyxl.descriptors.serialisable import Serialisable 

5from openpyxl.descriptors import ( 

6 Typed, 

7 Integer, 

8 Set, 

9 String, 

10 Bool, 

11) 

12from openpyxl.descriptors.excel import Guid, ExtensionList 

13from openpyxl.descriptors.sequence import NestedSequence 

14 

15from openpyxl.utils.indexed_list import IndexedList 

16from openpyxl.xml.constants import SHEET_MAIN_NS 

17 

18from openpyxl.cell.text import Text 

19from .author import AuthorList 

20from .comments import Comment 

21from .shape_writer import ShapeWriter 

22 

23 

24class Properties(Serialisable): 

25 

26 locked = Bool(allow_none=True) 

27 defaultSize = Bool(allow_none=True) 

28 _print = Bool(allow_none=True) 

29 disabled = Bool(allow_none=True) 

30 uiObject = Bool(allow_none=True) 

31 autoFill = Bool(allow_none=True) 

32 autoLine = Bool(allow_none=True) 

33 altText = String(allow_none=True) 

34 textHAlign = Set(values=(['left', 'center', 'right', 'justify', 'distributed'])) 

35 textVAlign = Set(values=(['top', 'center', 'bottom', 'justify', 'distributed'])) 

36 lockText = Bool(allow_none=True) 

37 justLastX = Bool(allow_none=True) 

38 autoScale = Bool(allow_none=True) 

39 rowHidden = Bool(allow_none=True) 

40 colHidden = Bool(allow_none=True) 

41 # anchor = Typed(expected_type=ObjectAnchor, ) 

42 

43 __elements__ = ('anchor',) 

44 

45 def __init__(self, 

46 locked=None, 

47 defaultSize=None, 

48 _print=None, 

49 disabled=None, 

50 uiObject=None, 

51 autoFill=None, 

52 autoLine=None, 

53 altText=None, 

54 textHAlign=None, 

55 textVAlign=None, 

56 lockText=None, 

57 justLastX=None, 

58 autoScale=None, 

59 rowHidden=None, 

60 colHidden=None, 

61 anchor=None, 

62 ): 

63 self.locked = locked 

64 self.defaultSize = defaultSize 

65 self._print = _print 

66 self.disabled = disabled 

67 self.uiObject = uiObject 

68 self.autoFill = autoFill 

69 self.autoLine = autoLine 

70 self.altText = altText 

71 self.textHAlign = textHAlign 

72 self.textVAlign = textVAlign 

73 self.lockText = lockText 

74 self.justLastX = justLastX 

75 self.autoScale = autoScale 

76 self.rowHidden = rowHidden 

77 self.colHidden = colHidden 

78 self.anchor = anchor 

79 

80 

81class CommentRecord(Serialisable): 

82 

83 tagname = "comment" 

84 

85 ref = String() 

86 authorId = Integer() 

87 guid = Guid(allow_none=True) 

88 shapeId = Integer(allow_none=True) 

89 text = Typed(expected_type=Text) 

90 commentPr = Typed(expected_type=Properties, allow_none=True) 

91 author = String(allow_none=True) 

92 

93 __elements__ = ('text', 'commentPr') 

94 __attrs__ = ('ref', 'authorId', 'guid', 'shapeId') 

95 

96 def __init__(self, 

97 ref="", 

98 authorId=0, 

99 guid=None, 

100 shapeId=0, 

101 text=None, 

102 commentPr=None, 

103 author=None, 

104 height=79, 

105 width=144 

106 ): 

107 self.ref = ref 

108 self.authorId = authorId 

109 self.guid = guid 

110 self.shapeId = shapeId 

111 if text is None: 

112 text = Text() 

113 self.text = text 

114 self.commentPr = commentPr 

115 self.author = author 

116 self.height = height 

117 self.width = width 

118 

119 

120 @classmethod 

121 def from_cell(cls, cell): 

122 """ 

123 Class method to convert cell comment 

124 """ 

125 comment = cell._comment 

126 ref = cell.coordinate 

127 self = cls(ref=ref, author=comment.author) 

128 self.text.t = comment.content 

129 self.height = comment.height 

130 self.width = comment.width 

131 return self 

132 

133 

134 @property 

135 def content(self): 

136 """ 

137 Remove all inline formatting and stuff 

138 """ 

139 return self.text.content 

140 

141 

142class CommentSheet(Serialisable): 

143 

144 tagname = "comments" 

145 

146 authors = Typed(expected_type=AuthorList) 

147 commentList = NestedSequence(expected_type=CommentRecord, count=0) 

148 extLst = Typed(expected_type=ExtensionList, allow_none=True) 

149 

150 _id = None 

151 _path = "/xl/comments/comment{0}.xml" 

152 mime_type = "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml" 

153 _rel_type = "comments" 

154 _rel_id = None 

155 

156 __elements__ = ('authors', 'commentList') 

157 

158 def __init__(self, 

159 authors=None, 

160 commentList=None, 

161 extLst=None, 

162 ): 

163 self.authors = authors 

164 self.commentList = commentList 

165 

166 

167 def to_tree(self): 

168 tree = super().to_tree() 

169 tree.set("xmlns", SHEET_MAIN_NS) 

170 return tree 

171 

172 

173 @property 

174 def comments(self): 

175 """ 

176 Return a dictionary of comments keyed by coord 

177 """ 

178 authors = self.authors.author 

179 

180 for c in self.commentList: 

181 yield c.ref, Comment(c.content, authors[c.authorId], c.height, c.width) 

182 

183 

184 @classmethod 

185 def from_comments(cls, comments): 

186 """ 

187 Create a comment sheet from a list of comments for a particular worksheet 

188 """ 

189 authors = IndexedList() 

190 

191 # dedupe authors and get indexes 

192 for comment in comments: 

193 comment.authorId = authors.add(comment.author) 

194 

195 return cls(authors=AuthorList(authors), commentList=comments) 

196 

197 

198 def write_shapes(self, vml=None): 

199 """ 

200 Create the VML for comments 

201 """ 

202 sw = ShapeWriter(self.comments) 

203 return sw.write(vml) 

204 

205 

206 @property 

207 def path(self): 

208 """ 

209 Return path within the archive 

210 """ 

211 return self._path.format(self._id)