Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/openpyxl/styles/fills.py: 57%
133 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1from __future__ import division
2# Copyright (c) 2010-2022 openpyxl
4from openpyxl.descriptors import (
5 Float,
6 Set,
7 Alias,
8 NoneSet,
9 Sequence,
10 Integer,
11 MinMax,
12)
13from openpyxl.descriptors.serialisable import Serialisable
14from openpyxl.compat import safe_string
16from .colors import ColorDescriptor, Color
18from openpyxl.xml.functions import Element, localname
19from openpyxl.xml.constants import SHEET_MAIN_NS
22FILL_NONE = 'none'
23FILL_SOLID = 'solid'
24FILL_PATTERN_DARKDOWN = 'darkDown'
25FILL_PATTERN_DARKGRAY = 'darkGray'
26FILL_PATTERN_DARKGRID = 'darkGrid'
27FILL_PATTERN_DARKHORIZONTAL = 'darkHorizontal'
28FILL_PATTERN_DARKTRELLIS = 'darkTrellis'
29FILL_PATTERN_DARKUP = 'darkUp'
30FILL_PATTERN_DARKVERTICAL = 'darkVertical'
31FILL_PATTERN_GRAY0625 = 'gray0625'
32FILL_PATTERN_GRAY125 = 'gray125'
33FILL_PATTERN_LIGHTDOWN = 'lightDown'
34FILL_PATTERN_LIGHTGRAY = 'lightGray'
35FILL_PATTERN_LIGHTGRID = 'lightGrid'
36FILL_PATTERN_LIGHTHORIZONTAL = 'lightHorizontal'
37FILL_PATTERN_LIGHTTRELLIS = 'lightTrellis'
38FILL_PATTERN_LIGHTUP = 'lightUp'
39FILL_PATTERN_LIGHTVERTICAL = 'lightVertical'
40FILL_PATTERN_MEDIUMGRAY = 'mediumGray'
42fills = (FILL_SOLID, FILL_PATTERN_DARKDOWN, FILL_PATTERN_DARKGRAY,
43 FILL_PATTERN_DARKGRID, FILL_PATTERN_DARKHORIZONTAL, FILL_PATTERN_DARKTRELLIS,
44 FILL_PATTERN_DARKUP, FILL_PATTERN_DARKVERTICAL, FILL_PATTERN_GRAY0625,
45 FILL_PATTERN_GRAY125, FILL_PATTERN_LIGHTDOWN, FILL_PATTERN_LIGHTGRAY,
46 FILL_PATTERN_LIGHTGRID, FILL_PATTERN_LIGHTHORIZONTAL,
47 FILL_PATTERN_LIGHTTRELLIS, FILL_PATTERN_LIGHTUP, FILL_PATTERN_LIGHTVERTICAL,
48 FILL_PATTERN_MEDIUMGRAY)
51class Fill(Serialisable):
53 """Base class"""
55 tagname = "fill"
57 @classmethod
58 def from_tree(cls, el):
59 children = [c for c in el]
60 if not children: 60 ↛ 61line 60 didn't jump to line 61, because the condition on line 60 was never true
61 return
62 child = children[0]
63 if "patternFill" in child.tag: 63 ↛ 65line 63 didn't jump to line 65, because the condition on line 63 was never false
64 return PatternFill._from_tree(child)
65 return super(Fill, GradientFill).from_tree(child)
68class PatternFill(Fill):
69 """Area fill patterns for use in styles.
70 Caution: if you do not specify a fill_type, other attributes will have
71 no effect !"""
73 tagname = "patternFill"
75 __elements__ = ('fgColor', 'bgColor')
77 patternType = NoneSet(values=fills)
78 fill_type = Alias("patternType")
79 fgColor = ColorDescriptor()
80 start_color = Alias("fgColor")
81 bgColor = ColorDescriptor()
82 end_color = Alias("bgColor")
84 def __init__(self, patternType=None, fgColor=Color(), bgColor=Color(),
85 fill_type=None, start_color=None, end_color=None):
86 if fill_type is not None: 86 ↛ 87line 86 didn't jump to line 87, because the condition on line 86 was never true
87 patternType = fill_type
88 self.patternType = patternType
89 if start_color is not None: 89 ↛ 90line 89 didn't jump to line 90, because the condition on line 89 was never true
90 fgColor = start_color
91 self.fgColor = fgColor
92 if end_color is not None: 92 ↛ 93line 92 didn't jump to line 93, because the condition on line 92 was never true
93 bgColor = end_color
94 self.bgColor = bgColor
96 @classmethod
97 def _from_tree(cls, el):
98 attrib = dict(el.attrib)
99 for child in el:
100 desc = localname(child)
101 attrib[desc] = Color.from_tree(child)
102 return cls(**attrib)
105 def to_tree(self, tagname=None, idx=None):
106 parent = Element("fill")
107 el = Element(self.tagname)
108 if self.patternType is not None:
109 el.set('patternType', self.patternType)
110 for c in self.__elements__:
111 value = getattr(self, c)
112 if value != Color():
113 el.append(value.to_tree(c))
114 parent.append(el)
115 return parent
118DEFAULT_EMPTY_FILL = PatternFill()
119DEFAULT_GRAY_FILL = PatternFill(patternType='gray125')
122class Stop(Serialisable):
124 tagname = "stop"
126 position = MinMax(min=0, max=1)
127 color = ColorDescriptor()
129 def __init__(self, color, position):
130 self.position = position
131 self.color = color
134def _assign_position(values):
135 """
136 Automatically assign positions if a list of colours is provided.
138 It is not permitted to mix colours and stops
139 """
140 n_values = len(values)
141 n_stops = sum(isinstance(value, Stop) for value in values)
143 if n_stops == 0:
144 interval = 1
145 if n_values > 2:
146 interval = 1 / (n_values - 1)
147 values = [Stop(value, i * interval)
148 for i, value in enumerate(values)]
150 elif n_stops < n_values:
151 raise ValueError('Cannot interpret mix of Stops and Colors in GradientFill')
153 pos = set()
154 for stop in values:
155 if stop.position in pos:
156 raise ValueError("Duplicate position {0}".format(stop.position))
157 pos.add(stop.position)
159 return values
162class StopList(Sequence):
164 expected_type = Stop
166 def __set__(self, obj, values):
167 values = _assign_position(values)
168 super(StopList, self).__set__(obj, values)
171class GradientFill(Fill):
172 """Fill areas with gradient
174 Two types of gradient fill are supported:
176 - A type='linear' gradient interpolates colours between
177 a set of specified Stops, across the length of an area.
178 The gradient is left-to-right by default, but this
179 orientation can be modified with the degree
180 attribute. A list of Colors can be provided instead
181 and they will be positioned with equal distance between them.
183 - A type='path' gradient applies a linear gradient from each
184 edge of the area. Attributes top, right, bottom, left specify
185 the extent of fill from the respective borders. Thus top="0.2"
186 will fill the top 20% of the cell.
188 """
190 tagname = "gradientFill"
192 type = Set(values=('linear', 'path'))
193 fill_type = Alias("type")
194 degree = Float()
195 left = Float()
196 right = Float()
197 top = Float()
198 bottom = Float()
199 stop = StopList()
202 def __init__(self, type="linear", degree=0, left=0, right=0, top=0,
203 bottom=0, stop=()):
204 self.degree = degree
205 self.left = left
206 self.right = right
207 self.top = top
208 self.bottom = bottom
209 self.stop = stop
210 self.type = type
213 def __iter__(self):
214 for attr in self.__attrs__:
215 value = getattr(self, attr)
216 if value:
217 yield attr, safe_string(value)
220 def to_tree(self, tagname=None, namespace=None, idx=None):
221 parent = Element("fill")
222 el = super(GradientFill, self).to_tree()
223 parent.append(el)
224 return parent