Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/openpyxl/styles/cell_style.py: 60%

111 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 array import array 

4 

5from openpyxl.descriptors.serialisable import Serialisable 

6from openpyxl.descriptors import ( 

7 Typed, 

8 Float, 

9 Bool, 

10 Integer, 

11 Sequence, 

12) 

13from openpyxl.descriptors.excel import ExtensionList 

14from openpyxl.utils.indexed_list import IndexedList 

15 

16 

17from .alignment import Alignment 

18from .protection import Protection 

19 

20 

21class ArrayDescriptor(object): 

22 

23 def __init__(self, key): 

24 self.key = key 

25 

26 def __get__(self, instance, cls): 

27 return instance[self.key] 

28 

29 def __set__(self, instance, value): 

30 instance[self.key] = value 

31 

32 

33class StyleArray(array): 

34 """ 

35 Simplified named tuple with an array 

36 """ 

37 

38 __slots__ = () 

39 tagname = 'xf' 

40 

41 fontId = ArrayDescriptor(0) 

42 fillId = ArrayDescriptor(1) 

43 borderId = ArrayDescriptor(2) 

44 numFmtId = ArrayDescriptor(3) 

45 protectionId = ArrayDescriptor(4) 

46 alignmentId = ArrayDescriptor(5) 

47 pivotButton = ArrayDescriptor(6) 

48 quotePrefix = ArrayDescriptor(7) 

49 xfId = ArrayDescriptor(8) 

50 

51 

52 def __new__(cls, args=[0]*9): 

53 return array.__new__(cls, 'i', args) 

54 

55 

56 def __hash__(self): 

57 return hash(tuple(self)) 

58 

59 

60 def __copy__(self): 

61 return StyleArray((self)) 

62 

63 

64 def __deepcopy__(self, memo): 

65 return StyleArray((self)) 

66 

67 

68class CellStyle(Serialisable): 

69 

70 tagname = "xf" 

71 

72 numFmtId = Integer() 

73 fontId = Integer() 

74 fillId = Integer() 

75 borderId = Integer() 

76 xfId = Integer(allow_none=True) 

77 quotePrefix = Bool(allow_none=True) 

78 pivotButton = Bool(allow_none=True) 

79 applyNumberFormat = Bool(allow_none=True) 

80 applyFont = Bool(allow_none=True) 

81 applyFill = Bool(allow_none=True) 

82 applyBorder = Bool(allow_none=True) 

83 applyAlignment = Bool(allow_none=True) 

84 applyProtection = Bool(allow_none=True) 

85 alignment = Typed(expected_type=Alignment, allow_none=True) 

86 protection = Typed(expected_type=Protection, allow_none=True) 

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

88 

89 __elements__ = ('alignment', 'protection') 

90 __attrs__ = ("numFmtId", "fontId", "fillId", "borderId", 

91 "applyAlignment", "applyProtection", "pivotButton", "quotePrefix", "xfId") 

92 

93 def __init__(self, 

94 numFmtId=0, 

95 fontId=0, 

96 fillId=0, 

97 borderId=0, 

98 xfId=None, 

99 quotePrefix=None, 

100 pivotButton=None, 

101 applyNumberFormat=None, 

102 applyFont=None, 

103 applyFill=None, 

104 applyBorder=None, 

105 applyAlignment=None, 

106 applyProtection=None, 

107 alignment=None, 

108 protection=None, 

109 extLst=None, 

110 ): 

111 self.numFmtId = numFmtId 

112 self.fontId = fontId 

113 self.fillId = fillId 

114 self.borderId = borderId 

115 self.xfId = xfId 

116 self.quotePrefix = quotePrefix 

117 self.pivotButton = pivotButton 

118 self.applyNumberFormat = applyNumberFormat 

119 self.applyFont = applyFont 

120 self.applyFill = applyFill 

121 self.applyBorder = applyBorder 

122 self.alignment = alignment 

123 self.protection = protection 

124 

125 

126 def to_array(self): 

127 """ 

128 Convert to StyleArray 

129 """ 

130 style = StyleArray() 

131 for k in ("fontId", "fillId", "borderId", "numFmtId", "pivotButton", 

132 "quotePrefix", "xfId"): 

133 v = getattr(self, k, 0) 

134 if v is not None: 

135 setattr(style, k, v) 

136 return style 

137 

138 

139 @classmethod 

140 def from_array(cls, style): 

141 """ 

142 Convert from StyleArray 

143 """ 

144 return cls(numFmtId=style.numFmtId, fontId=style.fontId, 

145 fillId=style.fillId, borderId=style.borderId, xfId=style.xfId, 

146 quotePrefix=style.quotePrefix, pivotButton=style.pivotButton,) 

147 

148 

149 @property 

150 def applyProtection(self): 

151 return self.protection is not None or None 

152 

153 

154 @property 

155 def applyAlignment(self): 

156 return self.alignment is not None or None 

157 

158 

159class CellStyleList(Serialisable): 

160 

161 tagname = "cellXfs" 

162 

163 __attrs__ = ("count",) 

164 

165 count = Integer(allow_none=True) 

166 xf = Sequence(expected_type=CellStyle) 

167 alignment = Sequence(expected_type=Alignment) 

168 protection = Sequence(expected_type=Protection) 

169 

170 __elements__ = ('xf',) 

171 

172 def __init__(self, 

173 count=None, 

174 xf=(), 

175 ): 

176 self.xf = xf 

177 

178 

179 @property 

180 def count(self): 

181 return len(self.xf) 

182 

183 

184 def __getitem__(self, idx): 

185 return self.xf[idx] 

186 

187 

188 def _to_array(self): 

189 """ 

190 Extract protection and alignments, convert to style array 

191 """ 

192 self.prots = IndexedList([Protection()]) 

193 self.alignments = IndexedList([Alignment()]) 

194 styles = [] # allow duplicates 

195 for xf in self.xf: 

196 style = xf.to_array() 

197 if xf.alignment is not None: 

198 style.alignmentId = self.alignments.add(xf.alignment) 

199 if xf.protection is not None: 

200 style.protectionId = self.prots.add(xf.protection) 

201 styles.append(style) 

202 return IndexedList(styles)