author  robin <robin@reportlab.com> 
Tue, 07 Mar 2017 10:00:34 +0000  
changeset 4330  617ffa6bbdc8 
parent 4266  b6902985cf64 
child 4343  386f7e1bf9c7 
permissions  rwxrxrx 
4330  1 
#Copyright ReportLab Europe Ltd. 20002017 
494  2 
#see license.txt for license details 
2332  3 
#history http://www.reportlab.co.uk/cgibin/viewcvs.cgi/public/reportlab/trunk/reportlab/platypus/tables.py 
4252  4 
__version__='3.3.0' 
2190  5 

16  6 
__doc__=""" 
6  7 
Tables are created by passing the constructor a tuple of column widths, a tuple of row heights and the data in 
8 
row order. Drawing of the table can be controlled by using a TableStyle instance. This allows control of the 

9 
color and weight of the lines (if any), and the font, alignment and padding of the text. 

268  10 

327  11 
None values in the sequence of row heights or column widths, mean that the corresponding rows 
12 
or columns should be automatically sized. 

13 

14 
All the cell values should be convertible to strings; embedded newline '\\n' characters 

15 
cause the value to wrap (ie are like a traditional linefeed). 

16 

268  17 
See the test output from running this module as a script for a discussion of the method for constructing 
18 
tables and table styles. 

6  19 
""" 
3551
dc4aedd55fea
tables.py: add import of Spacer bug fix contributed by Felix Labrecque <felixl@densi.com>
rgbecker
parents:
3529
diff
changeset

20 
from reportlab.platypus.flowables import Flowable, Preformatted, Spacer 
1207
49a514d10cb0
make tables one point off not bomb mysteriously in paid production installations.
aaron_watters
parents:
1169
diff
changeset

21 
from reportlab import rl_config 
3368
afa025c34493
reportlab: new base font mechanism more fully applied
rgbecker
parents:
3326
diff
changeset

22 
from reportlab.lib.styles import PropertySet, ParagraphStyle, _baseFontName 
168
02bac1346c69
Tables changed to use reportlab.lib.colors instead of
andy_robinson
parents:
129
diff
changeset

23 
from reportlab.lib import colors 
3996  24 
from reportlab.lib.utils import annotateException, IdentStr, flatten, isStr, asNative, strTypes 
3781  25 
from reportlab.lib.rl_accel import fp_str 
3521  26 
from reportlab.lib.abag import ABag as CellFrame 
2754  27 
from reportlab.pdfbase.pdfmetrics import stringWidth 
3521  28 
from reportlab.platypus.doctemplate import Indenter 
29 
from reportlab.platypus.flowables import LIIndenter 

6  30 

2469  31 
LINECAPS={None: None, 'butt':0,'round':1,'projecting':2,'squared':2} 
32 
LINEJOINS={None: None, 'miter':0, 'mitre':0, 'round':1,'bevel':2} 

1699  33 

3504
1d048454e4fe
tables.py: remove unwanted class and revert colors fix :(
rgbecker
parents:
3502
diff
changeset

34 
class CellStyle(PropertySet): 
3368
afa025c34493
reportlab: new base font mechanism more fully applied
rgbecker
parents:
3326
diff
changeset

35 
fontname = _baseFontName 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

36 
fontsize = 10 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

37 
leading = 12 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

38 
leftPadding = 6 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

39 
rightPadding = 6 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

40 
topPadding = 3 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

41 
bottomPadding = 3 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

42 
firstLineIndent = 0 
3504
1d048454e4fe
tables.py: remove unwanted class and revert colors fix :(
rgbecker
parents:
3502
diff
changeset

43 
color = 'black' 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

44 
alignment = 'LEFT' 
3504
1d048454e4fe
tables.py: remove unwanted class and revert colors fix :(
rgbecker
parents:
3502
diff
changeset

45 
background = 'white' 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

46 
valign = "BOTTOM" 
2575  47 
href = None 
48 
destination = None 

1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

49 
def __init__(self, name, parent=None): 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

50 
self.name = name 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

51 
if parent is not None: 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

52 
parent.copy(self) 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

53 
def copy(self, result=None): 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

54 
if result is None: 
3504
1d048454e4fe
tables.py: remove unwanted class and revert colors fix :(
rgbecker
parents:
3502
diff
changeset

55 
result = CellStyle() 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

56 
for name in dir(self): 
2730  57 
setattr(result, name, getattr(self, name)) 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

58 
return result 
730
48a169b27fe4
changed handling of table element styles for better space/time. old code left commented
aaron_watters
parents:
684
diff
changeset

59 

6  60 
class TableStyle: 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

61 
def __init__(self, cmds=None, parent=None, **kw): 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

62 
#handle inheritance from parent first. 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

63 
commands = [] 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

64 
if parent: 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

65 
# copy the parents list at construction time 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

66 
commands = commands + parent.getCommands() 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

67 
self._opts = parent._opts 
2574  68 
for a in ('spaceBefore','spaceAfter'): 
69 
if hasattr(parent,a): 

70 
setattr(self,a,getattr(parent,a)) 

1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

71 
if cmds: 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

72 
commands = commands + list(cmds) 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

73 
self._cmds = commands 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

74 
self._opts={} 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

75 
self._opts.update(kw) 
1435
4d0f57749e18
Added _opts to TableStyle for possible keepWithNext
rgbecker
parents:
1253
diff
changeset

76 

1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

77 
def add(self, *cmd): 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

78 
self._cmds.append(cmd) 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

79 
def __repr__(self): 
3203  80 
return "TableStyle(\n%s\n) # end TableStyle" % " \n".join(map(repr, self._cmds)) 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

81 
def getCommands(self): 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

82 
return self._cmds 
338  83 

356  84 
def _rowLen(x): 
3180
349e9644fce8
reportlab: attempt to remove type() checking in favour of isinstance
rgbecker
parents:
3177
diff
changeset

85 
return not isinstance(x,(tuple,list)) and 1 or len(x) 
419  86 

2271  87 
def _calc_pc(V,avail): 
88 
'''check list V for percentage or * values 

89 
1) absolute values go through unchanged 

90 
2) percentages are used as weights for unconsumed space 

91 
3) if no None values were seen '*' weights are 

92 
set equally with unclaimed space 

93 
otherwise * weights are assigned as None''' 

94 
R = [] 

95 
r = R.append 

96 
I = [] 

97 
i = I.append 

98 
J = [] 

99 
j = J.append 

100 
s = avail 

101 
w = n = 0. 

102 
for v in V: 

4019  103 
if isinstance(v,strTypes): 
104 
v = str(v).strip() 

2271  105 
if not v: 
106 
v = None 

107 
n += 1 

108 
elif v.endswith('%'): 

109 
v = float(v[:1]) 

110 
w += v 

111 
i(len(R)) 

112 
elif v=='*': 

113 
j(len(R)) 

114 
else: 

115 
v = float(v) 

2284  116 
s = v 
2271  117 
elif v is None: 
118 
n += 1 

119 
else: 

120 
s = v 

121 
r(v) 

122 
s = max(0.,s) 

123 
f = s/max(100.,w) 

124 
for i in I: 

125 
R[i] *= f 

126 
s = R[i] 

127 
s = max(0.,s) 

128 
m = len(J) 

129 
if m: 

130 
v = n==0 and s/m or None 

131 
for j in J: 

132 
R[j] = v 

133 
return R 

356  134 

2412
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

135 
def _hLine(canvLine, scp, ecp, y, hBlocks, FUZZ=rl_config._FUZZ): 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

136 
''' 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

137 
Draw horizontal lines; do not draw through regions specified in hBlocks 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

138 
This also serves for vertical lines with a suitable canvLine 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

139 
''' 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

140 
if hBlocks: hBlocks = hBlocks.get(y,None) 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

141 
if not hBlocks or scp>=hBlocks[1][1]FUZZ or ecp<=hBlocks[0][0]+FUZZ: 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

142 
canvLine(scp,y,ecp,y) 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

143 
else: 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

144 
i = 0 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

145 
n = len(hBlocks) 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

146 
while scp<ecpFUZZ and i<n: 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

147 
x0, x1 = hBlocks[i] 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

148 
if x1<=scp+FUZZ or x0>=ecpFUZZ: 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

149 
i += 1 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

150 
continue 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

151 
i0 = max(scp,x0) 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

152 
i1 = min(ecp,x1) 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

153 
if i0>scp: canvLine(scp,y,i0,y) 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

154 
scp = i1 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

155 
if scp<ecpFUZZ: canvLine(scp,y,ecp,y) 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

156 

2414
81be267fa92c
tables.py: extend span line blocking to multi lines
rgbecker
parents:
2412
diff
changeset

157 
def _multiLine(scp,ecp,y,canvLine,ws,count): 
81be267fa92c
tables.py: extend span line blocking to multi lines
rgbecker
parents:
2412
diff
changeset

158 
offset = 0.5*(count1)*ws 
81be267fa92c
tables.py: extend span line blocking to multi lines
rgbecker
parents:
2412
diff
changeset

159 
y += offset 
4140  160 
for idx in xrange(count): 
2414
81be267fa92c
tables.py: extend span line blocking to multi lines
rgbecker
parents:
2412
diff
changeset

161 
canvLine(scp, y, ecp, y) 
81be267fa92c
tables.py: extend span line blocking to multi lines
rgbecker
parents:
2412
diff
changeset

162 
y = ws 
81be267fa92c
tables.py: extend span line blocking to multi lines
rgbecker
parents:
2412
diff
changeset

163 

2469  164 
def _convert2int(value, map, low, high, name, cmd): 
165 
'''private converter tries map(value) low<=int(value)<=high or finally an error''' 

166 
try: 

167 
return map[value] 

168 
except KeyError: 

169 
try: 

170 
ivalue = int(value) 

171 
if low<=ivalue<=high: return ivalue 

172 
except: 

173 
pass 

4025
b2eb4dd254cf
tables.py: fix various command issues when unicode commands are used
robin
parents:
4019
diff
changeset

174 
raise ValueError('Bad %s value %s in %s'%(name,value,ascii(cmd))) 
2469  175 

2472
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

176 
def _endswith(obj,s): 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

177 
try: 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

178 
return obj.endswith(s) 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

179 
except: 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

180 
return 0 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

181 

3462
c9a0ccee737d
tables.py: make more robust for LongTable & spans
rgbecker
parents:
3442
diff
changeset

182 
def spanFixDim(V0,V,spanCons,lim=None,FUZZ=rl_config._FUZZ): 
2879
0ba5481218bd
tables.py: slightly better spanned row height calcs
rgbecker
parents:
2878
diff
changeset

183 
#assign required space to variable rows equally to existing calculated values 
0ba5481218bd
tables.py: slightly better spanned row height calcs
rgbecker
parents:
2878
diff
changeset

184 
M = {} 
3462
c9a0ccee737d
tables.py: make more robust for LongTable & spans
rgbecker
parents:
3442
diff
changeset

185 
if not lim: lim = len(V0) #in longtables the row calcs may be truncated 
3721  186 
for (x0,x1),v in spanCons.items(): 
3462
c9a0ccee737d
tables.py: make more robust for LongTable & spans
rgbecker
parents:
3442
diff
changeset

187 
if x0>=lim: continue 
c9a0ccee737d
tables.py: make more robust for LongTable & spans
rgbecker
parents:
3442
diff
changeset

188 
x1 += 1 
4140  189 
t = sum([V[x]+M.get(x,0) for x in xrange(x0,x1)]) 
2879
0ba5481218bd
tables.py: slightly better spanned row height calcs
rgbecker
parents:
2878
diff
changeset

190 
if t>=vFUZZ: continue #already good enough 
4140  191 
X = [x for x in xrange(x0,x1) if V0[x] is None] #variable candidates 
2879
0ba5481218bd
tables.py: slightly better spanned row height calcs
rgbecker
parents:
2878
diff
changeset

192 
if not X: continue #something wrong here mate 
0ba5481218bd
tables.py: slightly better spanned row height calcs
rgbecker
parents:
2878
diff
changeset

193 
v = t 
0ba5481218bd
tables.py: slightly better spanned row height calcs
rgbecker
parents:
2878
diff
changeset

194 
v /= float(len(X)) 
0ba5481218bd
tables.py: slightly better spanned row height calcs
rgbecker
parents:
2878
diff
changeset

195 
for x in X: 
3432
04c84c2ef968
tables.py: fix for spanFixDim contributed by Tomasz Swiderski contact@tomaszswiderski.com
rgbecker
parents:
3368
diff
changeset

196 
M[x] = M.get(x,0)+v 
3721  197 
for x,v in M.items(): 
2879
0ba5481218bd
tables.py: slightly better spanned row height calcs
rgbecker
parents:
2878
diff
changeset

198 
V[x] += v 
2878
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

199 

3521  200 
class _ExpandedCellTuple(tuple): 
201 
pass 

202 

221  203 
class Table(Flowable): 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

204 
def __init__(self, data, colWidths=None, rowHeights=None, style=None, 
2495
4952531cccfb
tables.py: allow for h/vAlign constructor agruments to be used
rgbecker
parents:
2481
diff
changeset

205 
repeatRows=0, repeatCols=0, splitByRow=1, emptyTableAction=None, ident=None, 
4175
f0bfab1d9277
Table args spaceBefore, spaceAfter & rowSplitRange added, version>3.1.49
robin
parents:
4166
diff
changeset

206 
hAlign=None,vAlign=None, normalizedData=0, cellStyles=None, rowSplitRange=None, 
4266
b6902985cf64
attempt to remove quadratic performance hit when longTableOptimize is set; version>3.3.6
robin
parents:
4264
diff
changeset

207 
spaceBefore=None,spaceAfter=None, longTableOptimize=None): 
2467
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

208 
self.ident = ident 
2495
4952531cccfb
tables.py: allow for h/vAlign constructor agruments to be used
rgbecker
parents:
2481
diff
changeset

209 
self.hAlign = hAlign or 'CENTER' 
4952531cccfb
tables.py: allow for h/vAlign constructor agruments to be used
rgbecker
parents:
2481
diff
changeset

210 
self.vAlign = vAlign or 'MIDDLE' 
3180
349e9644fce8
reportlab: attempt to remove type() checking in favour of isinstance
rgbecker
parents:
3177
diff
changeset

211 
if not isinstance(data,(tuple,list)): 
2915  212 
raise ValueError("%s invalid data type" % self.identity()) 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

213 
self._nrows = nrows = len(data) 
2221  214 
self._cellvalues = [] 
3180
349e9644fce8
reportlab: attempt to remove type() checking in favour of isinstance
rgbecker
parents:
3177
diff
changeset

215 
_seqCW = isinstance(colWidths,(tuple,list)) 
349e9644fce8
reportlab: attempt to remove type() checking in favour of isinstance
rgbecker
parents:
3177
diff
changeset

216 
_seqRH = isinstance(rowHeights,(tuple,list)) 
3721  217 
if nrows: self._ncols = ncols = max(list(map(_rowLen,data))) 
2401  218 
elif colWidths and _seqCW: ncols = len(colWidths) 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

219 
else: ncols = 0 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

220 
if not emptyTableAction: emptyTableAction = rl_config.emptyTableAction 
4266
b6902985cf64
attempt to remove quadratic performance hit when longTableOptimize is set; version>3.3.6
robin
parents:
4264
diff
changeset

221 
self._longTableOptimize = (getattr(self,'_longTableOptimize',rl_config.longTableOptimize) 
b6902985cf64
attempt to remove quadratic performance hit when longTableOptimize is set; version>3.3.6
robin
parents:
4264
diff
changeset

222 
if longTableOptimize is None else longTableOptimize) 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

223 
if not (nrows and ncols): 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

224 
if emptyTableAction=='error': 
2915  225 
raise ValueError("%s must have at least a row and column" % self.identity()) 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

226 
elif emptyTableAction=='indicate': 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

227 
self.__class__ = Preformatted 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

228 
global _emptyTableStyle 
3721  229 
if '_emptyTableStyle' not in list(globals().keys()): 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

230 
_emptyTableStyle = ParagraphStyle('_emptyTableStyle') 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

231 
_emptyTableStyle.textColor = colors.red 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

232 
_emptyTableStyle.backColor = colors.yellow 
2194
6bc71309eb18
Modified version of Henning von Bargen's LongTables optimisation
rgbecker
parents:
2190
diff
changeset

233 
Preformatted.__init__(self,'%s(%d,%d)' % (self.__class__.__name__,nrows,ncols), _emptyTableStyle) 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

234 
elif emptyTableAction=='ignore': 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

235 
self.__class__ = Spacer 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

236 
Spacer.__init__(self,0,0) 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

237 
else: 
2915  238 
raise ValueError('%s bad emptyTableAction: "%s"' % (self.identity(),emptyTableAction)) 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

239 
return 
1533  240 

2589
1af821ded9f1
added japanese splitting test, and table preprocessor to convert unicode>utf8
andy
parents:
2582
diff
changeset

241 
# we need a cleanup pass to ensure data is strings  nonunicode and nonnull 
3325
64eb1b787d02
tables.py: apply optimization contributed by Tomasz Swiderski
rgbecker
parents:
3240
diff
changeset

242 
if normalizedData: 
64eb1b787d02
tables.py: apply optimization contributed by Tomasz Swiderski
rgbecker
parents:
3240
diff
changeset

243 
self._cellvalues = data 
64eb1b787d02
tables.py: apply optimization contributed by Tomasz Swiderski
rgbecker
parents:
3240
diff
changeset

244 
else: 
64eb1b787d02
tables.py: apply optimization contributed by Tomasz Swiderski
rgbecker
parents:
3240
diff
changeset

245 
self._cellvalues = data = self.normalizeData(data) 
2401  246 
if not _seqCW: colWidths = ncols*[colWidths] 
2938  247 
elif len(colWidths)!=ncols: 
248 
if rl_config.allowShortTableRows and isinstance(colWidths,list): 

249 
n = len(colWidths) 

250 
if n<ncols: 

251 
colWidths[n:] = (ncolsn)*[colWidths[1]] 

252 
else: 

253 
colWidths = colWidths[:ncols] 

254 
else: 

255 
raise ValueError("%s data error  %d columns in data but %d in column widths" % (self.identity(),ncols, len(colWidths))) 

2401  256 
if not _seqRH: rowHeights = nrows*[rowHeights] 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

257 
elif len(rowHeights) != nrows: 
2915  258 
raise ValueError("%s data error  %d rows in data but %d in row heights" % (self.identity(),nrows, len(rowHeights))) 
2938  259 
for i,d in enumerate(data): 
260 
n = len(d) 

261 
if n!=ncols: 

262 
if rl_config.allowShortTableRows and isinstance(d,list): 

263 
d[n:] = (ncolsn)*[''] 

264 
else: 

265 
raise ValueError("%s expected %d not %d columns in row %d!" % (self.identity(),ncols,n,i)) 

1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

266 
self._rowHeights = self._argH = rowHeights 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

267 
self._colWidths = self._argW = colWidths 
3325
64eb1b787d02
tables.py: apply optimization contributed by Tomasz Swiderski
rgbecker
parents:
3240
diff
changeset

268 
if cellStyles is None: 
64eb1b787d02
tables.py: apply optimization contributed by Tomasz Swiderski
rgbecker
parents:
3240
diff
changeset

269 
cellrows = [] 
4140  270 
for i in xrange(nrows): 
3325
64eb1b787d02
tables.py: apply optimization contributed by Tomasz Swiderski
rgbecker
parents:
3240
diff
changeset

271 
cellcols = [] 
4140  272 
for j in xrange(ncols): 
3326  273 
cellcols.append(CellStyle(repr((i,j)))) 
3325
64eb1b787d02
tables.py: apply optimization contributed by Tomasz Swiderski
rgbecker
parents:
3240
diff
changeset

274 
cellrows.append(cellcols) 
64eb1b787d02
tables.py: apply optimization contributed by Tomasz Swiderski
rgbecker
parents:
3240
diff
changeset

275 
self._cellStyles = cellrows 
64eb1b787d02
tables.py: apply optimization contributed by Tomasz Swiderski
rgbecker
parents:
3240
diff
changeset

276 
else: 
64eb1b787d02
tables.py: apply optimization contributed by Tomasz Swiderski
rgbecker
parents:
3240
diff
changeset

277 
self._cellStyles = cellStyles 
350  278 

1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

279 
self._bkgrndcmds = [] 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

280 
self._linecmds = [] 
1883  281 
self._spanCmds = [] 
2812
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

282 
self._nosplitCmds = [] 
4194
9ecdf084933c
allow Table.repeatRows to be a list/tuple; version>3.1.59
robin
parents:
4192
diff
changeset

283 
# NB repeatRows can be a list or tuple eg (1,) reapesat only the second row of a table 
9ecdf084933c
allow Table.repeatRows to be a list/tuple; version>3.1.59
robin
parents:
4192
diff
changeset

284 
# or an integer eg 2 to repeat both rows 0 & 1 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

285 
self.repeatRows = repeatRows 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

286 
self.repeatCols = repeatCols 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

287 
self.splitByRow = splitByRow 
6  288 

1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

289 
if style: 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

290 
self.setStyle(style) 
3442
04096d41cb18
tables.py: changed the default colors for cell styles to be strings
rgbecker
parents:
3432
diff
changeset

291 

4175
f0bfab1d9277
Table args spaceBefore, spaceAfter & rowSplitRange added, version>3.1.49
robin
parents:
4166
diff
changeset

292 
self._rowSplitRange = rowSplitRange 
f0bfab1d9277
Table args spaceBefore, spaceAfter & rowSplitRange added, version>3.1.49
robin
parents:
4166
diff
changeset

293 
if spaceBefore is not None: 
f0bfab1d9277
Table args spaceBefore, spaceAfter & rowSplitRange added, version>3.1.49
robin
parents:
4166
diff
changeset

294 
self.spaceBefore = spaceBefore 
f0bfab1d9277
Table args spaceBefore, spaceAfter & rowSplitRange added, version>3.1.49
robin
parents:
4166
diff
changeset

295 
if spaceAfter is not None: 
f0bfab1d9277
Table args spaceBefore, spaceAfter & rowSplitRange added, version>3.1.49
robin
parents:
4166
diff
changeset

296 
self.spaceAfter = spaceAfter 
f0bfab1d9277
Table args spaceBefore, spaceAfter & rowSplitRange added, version>3.1.49
robin
parents:
4166
diff
changeset

297 

1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

298 
def __repr__(self): 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

299 
"incomplete, but better than nothing" 
2389  300 
r = getattr(self,'_rowHeights','[unknown]') 
301 
c = getattr(self,'_colWidths','[unknown]') 

302 
cv = getattr(self,'_cellvalues','[unknown]') 

3203  303 
import pprint 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

304 
cv = pprint.pformat(cv) 
3203  305 
cv = cv.replace("\n", "\n ") 
2194
6bc71309eb18
Modified version of Henning von Bargen's LongTables optimisation
rgbecker
parents:
2190
diff
changeset

306 
return "%s(\n rowHeights=%s,\n colWidths=%s,\n%s\n) # end table" % (self.__class__.__name__,r,c,cv) 
342  307 

2589
1af821ded9f1
added japanese splitting test, and table preprocessor to convert unicode>utf8
andy
parents:
2582
diff
changeset

308 
def normalizeData(self, data): 
1af821ded9f1
added japanese splitting test, and table preprocessor to convert unicode>utf8
andy
parents:
2582
diff
changeset

309 
"""Takes a block of input data (list of lists etc.) and 
2590  310 
 coerces unicode strings to nonunicode UTF8 
311 
 coerces nulls to '' 

2754  312 
 
313 

2589
1af821ded9f1
added japanese splitting test, and table preprocessor to convert unicode>utf8
andy
parents:
2582
diff
changeset

314 
""" 
1af821ded9f1
added japanese splitting test, and table preprocessor to convert unicode>utf8
andy
parents:
2582
diff
changeset

315 
def normCell(stuff): 
1af821ded9f1
added japanese splitting test, and table preprocessor to convert unicode>utf8
andy
parents:
2582
diff
changeset

316 
if stuff is None: 
1af821ded9f1
added japanese splitting test, and table preprocessor to convert unicode>utf8
andy
parents:
2582
diff
changeset

317 
return '' 
3889  318 
elif isStr(stuff): 
319 
return asNative(stuff) 

2589
1af821ded9f1
added japanese splitting test, and table preprocessor to convert unicode>utf8
andy
parents:
2582
diff
changeset

320 
else: 
1af821ded9f1
added japanese splitting test, and table preprocessor to convert unicode>utf8
andy
parents:
2582
diff
changeset

321 
return stuff 
1af821ded9f1
added japanese splitting test, and table preprocessor to convert unicode>utf8
andy
parents:
2582
diff
changeset

322 
outData = [] 
1af821ded9f1
added japanese splitting test, and table preprocessor to convert unicode>utf8
andy
parents:
2582
diff
changeset

323 
for row in data: 
1af821ded9f1
added japanese splitting test, and table preprocessor to convert unicode>utf8
andy
parents:
2582
diff
changeset

324 
outRow = [normCell(cell) for cell in row] 
1af821ded9f1
added japanese splitting test, and table preprocessor to convert unicode>utf8
andy
parents:
2582
diff
changeset

325 
outData.append(outRow) 
1af821ded9f1
added japanese splitting test, and table preprocessor to convert unicode>utf8
andy
parents:
2582
diff
changeset

326 
from pprint import pprint as pp 
1af821ded9f1
added japanese splitting test, and table preprocessor to convert unicode>utf8
andy
parents:
2582
diff
changeset

327 
#pp(outData) 
1af821ded9f1
added japanese splitting test, and table preprocessor to convert unicode>utf8
andy
parents:
2582
diff
changeset

328 
return outData 
1af821ded9f1
added japanese splitting test, and table preprocessor to convert unicode>utf8
andy
parents:
2582
diff
changeset

329 

1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

330 
def identity(self, maxLen=30): 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

331 
'''Identify our selves as well as possible''' 
2467
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

332 
if self.ident: return self.ident 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

333 
vx = None 
1989  334 
nr = getattr(self,'_nrows','unknown') 
335 
nc = getattr(self,'_ncols','unknown') 

2299
d757841f2006
Fix proposed by Derik Barclay <dbarclay@givex.com>
rgbecker
parents:
2289
diff
changeset

336 
cv = getattr(self,'_cellvalues',None) 
3523  337 
rh = getattr(self, '_rowHeights', None) 
1989  338 
if cv and 'unknown' not in (nr,nc): 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

339 
b = 0 
4140  340 
for i in xrange(nr): 
341 
for j in xrange(nc): 

1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

342 
v = cv[i][j] 
3180
349e9644fce8
reportlab: attempt to remove type() checking in favour of isinstance
rgbecker
parents:
3177
diff
changeset

343 
if isinstance(v,(list,tuple,Flowable)): 
349e9644fce8
reportlab: attempt to remove type() checking in favour of isinstance
rgbecker
parents:
3177
diff
changeset

344 
if not isinstance(v,(tuple,list)): v = (v,) 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

345 
r = '' 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

346 
for vij in v: 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

347 
r = vij.identity(maxLen) 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

348 
if r and r[4:]!='>...': 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

349 
break 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

350 
if r and r[4:]!='>...': 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

351 
ix, jx, vx, b = i, j, r, 1 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

352 
else: 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

353 
v = v is None and '' or str(v) 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

354 
ix, jx, vx = i, j, v 
4025
b2eb4dd254cf
tables.py: fix various command issues when unicode commands are used
robin
parents:
4019
diff
changeset

355 
b = (vx and isinstance(v,strTypes)) and 1 or 0 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

356 
if maxLen: vx = vx[:maxLen] 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

357 
if b: break 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

358 
if b: break 
3523  359 
if rh: #find tallest row, it's of great interest' 
360 
tallest = '(tallest row %d)' % int(max(rh)) 

361 
else: 

362 
tallest = '' 

1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

363 
if vx: 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

364 
vx = ' with cell(%d,%d) containing\n%s' % (ix,jx,repr(vx)) 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

365 
else: 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

366 
vx = '...' 
1103  367 

3523  368 
return "<%s@0x%8.8X %s rows x %s cols%s>%s" % (self.__class__.__name__, id(self), nr, nc, tallest, vx) 
1103  369 

3510  370 
def _cellListIter(self,C,aW,aH): 
371 
canv = getattr(self,'canv',None) 

372 
for c in C: 

373 
if getattr(c,'__split_only__',None): 

374 
for d in c.splitOn(canv,aW,aH): 

375 
yield d 

376 
else: 

377 
yield c 

378 

3521  379 
def _cellListProcess(self,C,aW,aH): 
380 
if not isinstance(C,_ExpandedCellTuple): 

381 
frame = None 

382 
R = [].append 

383 
for c in self._cellListIter(C,aW,aH): 

384 
if isinstance(c,Indenter): 

385 
if not frame: 

386 
frame = CellFrame(_leftExtraIndent=0,_rightExtraIndent=0) 

387 
c.frameAction(frame) 

388 
if frame._leftExtraIndent<1e8 and frame._rightExtraIndent<1e8: 

389 
frame = None 

390 
continue 

391 
if frame: 

392 
R(LIIndenter(c,leftIndent=frame._leftExtraIndent,rightIndent=frame._rightExtraIndent)) 

393 
else: 

394 
R(c) 

395 
C = _ExpandedCellTuple(R.__self__) 

396 
return C 

397 

2189  398 
def _listCellGeom(self, V,w,s,W=None,H=None,aH=72000): 
2481  399 
if not V: return 0,0 
2754  400 
aW = w  s.leftPadding  s.rightPadding 
2189  401 
aH = aH  s.topPadding  s.bottomPadding 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

402 
t = 0 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

403 
w = 0 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

404 
canv = getattr(self,'canv',None) 
2754  405 
sb0 = None 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

406 
for v in V: 
2754  407 
vw, vh = v.wrapOn(canv, aW, aH) 
408 
sb = v.getSpaceBefore() 

409 
sa = v.getSpaceAfter() 

1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

410 
if W is not None: W.append(vw) 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

411 
if H is not None: H.append(vh) 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

412 
w = max(w,vw) 
2754  413 
t += vh + sa + sb 
414 
if sb0 is None: 

415 
sb0 = sb 

416 
return w, t  sb0  sa 

417 

418 
def _listValueWidth(self,V,aH=72000,aW=72000): 

419 
if not V: return 0,0 

420 
t = 0 

421 
w = 0 

422 
canv = getattr(self,'canv',None) 

423 
return max([v.wrapOn(canv,aW,aH)[0] for v in V]) 

1492  424 

2271  425 
def _calc_width(self,availWidth,W=None): 
2289  426 
if getattr(self,'_width_calculated_once',None): return 
427 
#comments added by Andy to Robin's slightly terse variable names 

2271  428 
if not W: W = _calc_pc(self._argW,availWidth) #widths array 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

429 
if None in W: #some column widths are not given 
2289  430 
canv = getattr(self,'canv',None) 
431 
saved = None 

2878
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

432 
if self._spanCmds: 
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

433 
colSpanCells = self._colSpanCells 
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

434 
spanRanges = self._spanRanges 
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

435 
else: 
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

436 
colSpanCells = () 
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

437 
spanRanges = {} 
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

438 
spanCons = {} 
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

439 
if W is self._argW: 
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

440 
W0 = W 
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

441 
W = W[:] 
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

442 
else: 
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

443 
W0 = W[:] 
3203  444 
V = self._cellvalues 
445 
S = self._cellStyles 

1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

446 
while None in W: 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

447 
j = W.index(None) #find first unspecified column 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

448 
w = 0 
3203  449 
for i,Vi in enumerate(V): 
450 
v = Vi[j] 

451 
s = S[i][j] 

2878
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

452 
ji = j,i 
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

453 
span = spanRanges.get(ji,None) 
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

454 
if ji in colSpanCells and not span: #if the current cell is part of a spanned region, 
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

455 
t = 0.0 #assume a zero size. 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

456 
else:#work out size 
1917  457 
t = self._elementWidth(v,s) 
458 
if t is None: 

2915  459 
raise ValueError("Flowable %s in cell(%d,%d) can't have auto width\n%s" % (v.identity(30),i,j,self.identity(30))) 
2878
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

460 
t += s.leftPadding+s.rightPadding 
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

461 
if span: 
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

462 
c0 = span[0] 
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

463 
c1 = span[2] 
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

464 
if c0!=c1: 
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

465 
x = c0,c1 
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

466 
spanCons[x] = max(spanCons.get(x,t),t) 
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

467 
t = 0 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

468 
if t>w: w = t #record a new maximum 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

469 

1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

470 
W[j] = w 
1596
753865895a6f
Jim Kraai's patch to preserve auto col width on subsequent pages
andy_robinson
parents:
1536
diff
changeset

471 

2878
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

472 
if spanCons: 
3518
3f201e3d0432
tables.py: fix bug when splitting across rowspans
rgbecker
parents:
3515
diff
changeset

473 
try: 
3f201e3d0432
tables.py: fix bug when splitting across rowspans
rgbecker
parents:
3515
diff
changeset

474 
spanFixDim(W0,W,spanCons) 
3f201e3d0432
tables.py: fix bug when splitting across rowspans
rgbecker
parents:
3515
diff
changeset

475 
except: 
3f201e3d0432
tables.py: fix bug when splitting across rowspans
rgbecker
parents:
3515
diff
changeset

476 
annotateException('\nspanning problem in %s\nW0=%r W=%r\nspanCons=%r' % (self.identity(),W0,W,spanCons)) 
2878
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

477 

2277  478 
self._colWidths = W 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

479 
width = 0 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

480 
self._colpositions = [0] #index 1 is right side boundary; we skip when processing cells 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

481 
for w in W: 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

482 
width = width + w 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

483 
self._colpositions.append(width) 
1683  484 

1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

485 
self._width = width 
2289  486 
self._width_calculated_once = 1 
1596
753865895a6f
Jim Kraai's patch to preserve auto col width on subsequent pages
andy_robinson
parents:
1536
diff
changeset

487 

1917  488 
def _elementWidth(self,v,s): 
2878
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

489 
if isinstance(v,(list,tuple)): 
1917  490 
w = 0 
491 
for e in v: 

2467
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

492 
ew = self._elementWidth(e,s) 
1917  493 
if ew is None: return None 
494 
w = max(w,ew) 

495 
return w 

496 
elif isinstance(v,Flowable) and v._fixedWidth: 

3180
349e9644fce8
reportlab: attempt to remove type() checking in favour of isinstance
rgbecker
parents:
3177
diff
changeset

497 
if hasattr(v, 'width') and isinstance(v.width,(int,float)): return v.width 
349e9644fce8
reportlab: attempt to remove type() checking in favour of isinstance
rgbecker
parents:
3177
diff
changeset

498 
if hasattr(v, 'drawWidth') and isinstance(v.drawWidth,(int,float)): return v.drawWidth 
2467
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

499 
# Even if something is fixedWidth, the attribute to check is not 
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

500 
# necessarily consistent (cf. Image.drawWidth). Therefore, we'll 
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

501 
# be extracareful and fall through to this code if necessary. 
2470
74a7b9da41e4
tables.py: fix for case when minWidth fails du eot attribute error
rgbecker
parents:
2469
diff
changeset

502 
if hasattr(v, 'minWidth'): 
74a7b9da41e4
tables.py: fix for case when minWidth fails du eot attribute error
rgbecker
parents:
2469
diff
changeset

503 
try: 
2471
76c745e075b2
tables.py: be evn more robust about width/drawWidth etc
rgbecker
parents:
2470
diff
changeset

504 
w = v.minWidth() # should be all flowables 
3180
349e9644fce8
reportlab: attempt to remove type() checking in favour of isinstance
rgbecker
parents:
3177
diff
changeset

505 
if isinstance(w,(float,int)): return w 
2470
74a7b9da41e4
tables.py: fix for case when minWidth fails du eot attribute error
rgbecker
parents:
2469
diff
changeset

506 
except AttributeError: 
74a7b9da41e4
tables.py: fix for case when minWidth fails du eot attribute error
rgbecker
parents:
2469
diff
changeset

507 
pass 
4258
d3e9de82a5aa
add table cell support for simple background shadings, contributed by Jeffrey Creem jcreem@bitbucket
robin
parents:
4257
diff
changeset

508 
if v is None: 
3529  509 
return 0 
510 
else: 

511 
try: 

512 
v = str(v).split("\n") 

513 
except: 

514 
return 0 

2754  515 
fontName = s.fontname 
516 
fontSize = s.fontsize 

517 
return max([stringWidth(x,fontName,fontSize) for x in v]) 

1917  518 

2271  519 
def _calc_height(self, availHeight, availWidth, H=None, W=None): 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

520 
H = self._argH 
2271  521 
if not W: W = _calc_pc(self._argW,availWidth) #widths array 
6  522 

2194
6bc71309eb18
Modified version of Henning von Bargen's LongTables optimisation
rgbecker
parents:
2190
diff
changeset

523 
hmax = lim = len(H) 
3462
c9a0ccee737d
tables.py: make more robust for LongTable & spans
rgbecker
parents:
3442
diff
changeset

524 
longTable = self._longTableOptimize 
2194
6bc71309eb18
Modified version of Henning von Bargen's LongTables optimisation
rgbecker
parents:
2190
diff
changeset

525 

1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

526 
if None in H: 
2289  527 
canv = getattr(self,'canv',None) 
528 
saved = None 

529 
#get a handy list of any cells which span rows. should be ignored for sizing 

530 
if self._spanCmds: 

531 
rowSpanCells = self._rowSpanCells 

532 
colSpanCells = self._colSpanCells 

533 
spanRanges = self._spanRanges 

534 
colpositions = self._colpositions 

535 
else: 

536 
rowSpanCells = colSpanCells = () 

2878
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

537 
spanRanges = {} 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

538 
if canv: saved = canv._fontname, canv._fontsize, canv._leading 
2878
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

539 
H0 = H 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

540 
H = H[:] #make a copy as we'll change it 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

541 
self._rowHeights = H 
2878
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

542 
spanCons = {} 
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

543 
FUZZ = rl_config._FUZZ 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

544 
while None in H: 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

545 
i = H.index(None) 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

546 
V = self._cellvalues[i] # values for row i 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

547 
S = self._cellStyles[i] # styles for row i 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

548 
h = 0 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

549 
j = 0 
3721  550 
for j,(v, s, w) in enumerate(list(zip(V, S, W))): # value, style, width (lengths must match) 
2289  551 
ji = j,i 
2878
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

552 
span = spanRanges.get(ji,None) 
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

553 
if ji in rowSpanCells and not span: 
2819
0af8d3e7dfc9
tables.py: fix inspired by Yuan Hong's bug report
rgbecker
parents:
2814
diff
changeset

554 
continue # don't count it, it's either occluded or unreliable 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

555 
else: 
2754  556 
if isinstance(v,(tuple,list,Flowable)): 
557 
if isinstance(v,Flowable): v = (v,) 

3561  558 
else: v = flatten(v) 
3521  559 
v = V[j] = self._cellListProcess(v,w,None) 
2754  560 
if w is None and not self._canGetWidth(v): 
2915  561 
raise ValueError("Flowable %s in cell(%d,%d) can't have auto width in\n%s" % (v[0].identity(30),i,j,self.identity(30))) 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

562 
if canv: canv._fontname, canv._fontsize, canv._leading = s.fontname, s.fontsize, s.leading or 1.2*s.fontsize 
2289  563 
if ji in colSpanCells: 
2878
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

564 
if not span: continue 
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

565 
w = max(colpositions[span[2]+1]colpositions[span[0]],w) 
2754  566 
dW,t = self._listCellGeom(v,w or self._listValueWidth(v),s) 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

567 
if canv: canv._fontname, canv._fontsize, canv._leading = saved 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

568 
dW = dW + s.leftPadding + s.rightPadding 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

569 
if not rl_config.allowTableBoundsErrors and dW>w: 
2915  570 
from reportlab.platypus.doctemplate import LayoutError 
571 
raise LayoutError("Flowable %s (%sx%s points) too wide for cell(%d,%d) (%sx* points) in\n%s" % (v[0].identity(30),fp_str(dW),fp_str(t),i,j, fp_str(w), self.identity(30))) 

1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

572 
else: 
2754  573 
v = (v is not None and str(v) or '').split("\n") 
3651
743a52af7e9a
fix attribute spelling bug fix contributed by Matthias Kirst <matt@clondiag.com>
robin
parents:
3617
diff
changeset

574 
t = (s.leading or 1.2*s.fontsize)*len(v) 
2819
0af8d3e7dfc9
tables.py: fix inspired by Yuan Hong's bug report
rgbecker
parents:
2814
diff
changeset

575 
t += s.bottomPadding+s.topPadding 
2878
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

576 
if span: 
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

577 
r0 = span[1] 
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

578 
r1 = span[3] 
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

579 
if r0!=r1: 
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

580 
x = r0,r1 
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

581 
spanCons[x] = max(spanCons.get(x,t),t) 
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

582 
t = 0 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

583 
if t>h: h = t #record a new maximum 
2194
6bc71309eb18
Modified version of Henning von Bargen's LongTables optimisation
rgbecker
parents:
2190
diff
changeset

584 
H[i] = h 
3038
04d53e2083bd
Fix for bug 609 (corner case of long table splitting throwed exception).
jonas
parents:
3031
diff
changeset

585 
# we can stop if we have filled up all available room 
04d53e2083bd
Fix for bug 609 (corner case of long table splitting throwed exception).
jonas
parents:
3031
diff
changeset

586 
if longTable: 
4266
b6902985cf64
attempt to remove quadratic performance hit when longTableOptimize is set; version>3.3.6
robin
parents:
4264
diff
changeset

587 
hmax = i+1 #we computed H[i] so known len == i+1 
b6902985cf64
attempt to remove quadratic performance hit when longTableOptimize is set; version>3.3.6
robin
parents:
4264
diff
changeset

588 
height = sum(H[:hmax]) 
3038
04d53e2083bd
Fix for bug 609 (corner case of long table splitting throwed exception).
jonas
parents:
3031
diff
changeset

589 
if height > availHeight: 
4266
b6902985cf64
attempt to remove quadratic performance hit when longTableOptimize is set; version>3.3.6
robin
parents:
4264
diff
changeset

590 
#we can terminate if all spans are complete in H[:hmax] 
3518
3f201e3d0432
tables.py: fix bug when splitting across rowspans
rgbecker
parents:
3515
diff
changeset

591 
if spanCons: 
4266
b6902985cf64
attempt to remove quadratic performance hit when longTableOptimize is set; version>3.3.6
robin
parents:
4264
diff
changeset

592 
msr = max(x[1] for x in spanCons.keys()) #RS=[endrowspan,.....] 
b6902985cf64
attempt to remove quadratic performance hit when longTableOptimize is set; version>3.3.6
robin
parents:
4264
diff
changeset

593 
if hmax>msr: 
3518
3f201e3d0432
tables.py: fix bug when splitting across rowspans
rgbecker
parents:
3515
diff
changeset

594 
break 
2200
be0cfccc662a
Fixed up tabs and whitespace in all source files
andy_robinson
parents:
2194
diff
changeset

595 
if None not in H: hmax = lim 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

596 

2878
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

597 
if spanCons: 
3518
3f201e3d0432
tables.py: fix bug when splitting across rowspans
rgbecker
parents:
3515
diff
changeset

598 
try: 
4266
b6902985cf64
attempt to remove quadratic performance hit when longTableOptimize is set; version>3.3.6
robin
parents:
4264
diff
changeset

599 
spanFixDim(H0,H,spanCons) 
3518
3f201e3d0432
tables.py: fix bug when splitting across rowspans
rgbecker
parents:
3515
diff
changeset

600 
except: 
3f201e3d0432
tables.py: fix bug when splitting across rowspans
rgbecker
parents:
3515
diff
changeset

601 
annotateException('\nspanning problem in %s hmax=%s lim=%s avail=%s x %s\nH0=%r H=%r\nspanCons=%r' % (self.identity(),hmax,lim,availWidth,availHeight,H0,H,spanCons)) 
2878
a7af19b6f9fb
reportlab: fix cell spanning bug in tables.py (from Volker Haas)
rgbecker
parents:
2819
diff
changeset

602 

4264
295afbf0f4c8
import Table _rowpositions calculation; version>3.3.5
robin
parents:
4258
diff
changeset

603 
#iterate backwards through the heights to get rowpositions in reversed order 
295afbf0f4c8
import Table _rowpositions calculation; version>3.3.5
robin
parents:
4258
diff
changeset

604 
self._rowpositions = j = [] 
295afbf0f4c8
import Table _rowpositions calculation; version>3.3.5
robin
parents:
4258
diff
changeset

605 
height = c = 0 
295afbf0f4c8
import Table _rowpositions calculation; version>3.3.5
robin
parents:
4258
diff
changeset

606 
for i in xrange(hmax1,1,1): 
295afbf0f4c8
import Table _rowpositions calculation; version>3.3.5
robin
parents:
4258
diff
changeset

607 
j.append(height) 
295afbf0f4c8
import Table _rowpositions calculation; version>3.3.5
robin
parents:
4258
diff
changeset

608 
y = H[i]  c 
295afbf0f4c8
import Table _rowpositions calculation; version>3.3.5
robin
parents:
4258
diff
changeset

609 
t = height + y 
295afbf0f4c8
import Table _rowpositions calculation; version>3.3.5
robin
parents:
4258
diff
changeset

610 
c = (t  height)  y 
295afbf0f4c8
import Table _rowpositions calculation; version>3.3.5
robin
parents:
4258
diff
changeset

611 
height = t 
295afbf0f4c8
import Table _rowpositions calculation; version>3.3.5
robin
parents:
4258
diff
changeset

612 
j.append(height) 
295afbf0f4c8
import Table _rowpositions calculation; version>3.3.5
robin
parents:
4258
diff
changeset

613 
self._height = height 
295afbf0f4c8
import Table _rowpositions calculation; version>3.3.5
robin
parents:
4258
diff
changeset

614 
j.reverse() #reverse the reversed list of row positions 
2194
6bc71309eb18
Modified version of Henning von Bargen's LongTables optimisation
rgbecker
parents:
2190
diff
changeset

615 
self._hmax = hmax 
1596
753865895a6f
Jim Kraai's patch to preserve auto col width on subsequent pages
andy_robinson
parents:
1536
diff
changeset

616 

1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

617 
def _calc(self, availWidth, availHeight): 
2194
6bc71309eb18
Modified version of Henning von Bargen's LongTables optimisation
rgbecker
parents:
2190
diff
changeset

618 
#if hasattr(self,'_width'): return 
1596
753865895a6f
Jim Kraai's patch to preserve auto col width on subsequent pages
andy_robinson
parents:
1536
diff
changeset

619 

1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

620 
#in some cases there are unsizable things in 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

621 
#cells. If so, apply a different algorithm 
2467
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

622 
#and assign some withs in a less (thanks to Gary Poster) dumb way. 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

623 
#this CHANGES the widths array. 
2284  624 
if (None in self._colWidths or '*' in self._colWidths) and self._hasVariWidthElements(): 
2271  625 
W = self._calcPreliminaryWidths(availWidth) #widths 
626 
else: 

627 
W = None 

1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

628 

c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

629 
# need to know which cells are part of spanned 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

630 
# ranges, so _calc_height and _calc_width can ignore them 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

631 
# in sizing 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

632 
if self._spanCmds: 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

633 
self._calcSpanRanges() 
2289  634 
if None in self._argH: 
635 
self._calc_width(availWidth,W=W) 

2190  636 

2812
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

637 
if self._nosplitCmds: 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

638 
self._calcNoSplitRanges() 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

639 

1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

640 
# calculate the full table height 
2271  641 
self._calc_height(availHeight,availWidth,W=W) 
1596
753865895a6f
Jim Kraai's patch to preserve auto col width on subsequent pages
andy_robinson
parents:
1536
diff
changeset

642 

1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

643 
# calculate the full table width 
2271  644 
self._calc_width(availWidth,W=W) 
2190  645 

1883  646 
if self._spanCmds: 
2289  647 
#now work out the actual rect for each spanned cell from the underlying grid 
1883  648 
self._calcSpanRects() 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

649 

3523  650 
def _culprit(self): 
651 
"""Return a string describing the tallest element. 

4258
d3e9de82a5aa
add table cell support for simple background shadings, contributed by Jeffrey Creem jcreem@bitbucket
robin
parents:
4257
diff
changeset

652 

3523  653 
Usually this is what causes tables to fail to split. Currently 
654 
tables are the only items to have a '_culprit' method. Doctemplate 

655 
checks for it. 

656 
""" 

657 
rh = self._rowHeights 

658 
tallest = max(rh) 

659 
rowNum = rh.index(tallest) 

660 
#rowNum of limited interest as usually it's a split one 

661 
#and we see row #1. Text might be a nice addition. 

4258
d3e9de82a5aa
add table cell support for simple background shadings, contributed by Jeffrey Creem jcreem@bitbucket
robin
parents:
4257
diff
changeset

662 

3523  663 
return 'tallest cell %0.1f points' % tallest 
4258
d3e9de82a5aa
add table cell support for simple background shadings, contributed by Jeffrey Creem jcreem@bitbucket
robin
parents:
4257
diff
changeset

664 

d3e9de82a5aa
add table cell support for simple background shadings, contributed by Jeffrey Creem jcreem@bitbucket
robin
parents:
4257
diff
changeset

665 

3523  666 

1917  667 
def _hasVariWidthElements(self, upToRow=None): 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

668 
"""Check for flowables in table cells and warn up front. 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

669 

c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

670 
Allow a couple which we know are fixed size such as 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

671 
images and graphics.""" 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

672 
if upToRow is None: upToRow = self._nrows 
4140  673 
for row in xrange(min(self._nrows, upToRow)): 
674 
for col in xrange(self._ncols): 

1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

675 
value = self._cellvalues[row][col] 
1917  676 
if not self._canGetWidth(value): 
2754  677 
return 1 
678 
return 0 

1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

679 

1917  680 
def _canGetWidth(self, thing): 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

681 
"Can we work out the width quickly?" 
3180
349e9644fce8
reportlab: attempt to remove type() checking in favour of isinstance
rgbecker
parents:
3177
diff
changeset

682 
if isinstance(thing,(list, tuple)): 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

683 
for elem in thing: 
1917  684 
if not self._canGetWidth(elem): 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

685 
return 0 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

686 
return 1 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

687 
elif isinstance(thing, Flowable): 
1917  688 
return thing._fixedWidth # must loosen this up 
3203  689 
else: #str, number, None etc. 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

690 
#anything else gets passed to str(...) 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

691 
# so should be sizable 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

692 
return 1 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

693 

c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

694 
def _calcPreliminaryWidths(self, availWidth): 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

695 
"""Fallback algorithm for when main one fails. 
1883  696 

1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

697 
Where exact width info not given but things like 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

698 
paragraphs might be present, do a preliminary scan 
2467
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

699 
and assign some bestguess values.""" 
2271  700 

2467
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

701 
W = list(self._argW) # _calc_pc(self._argW,availWidth) 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

702 
verbose = 0 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

703 
totalDefined = 0.0 
2467
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

704 
percentDefined = 0 
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

705 
percentTotal = 0 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

706 
numberUndefined = 0 
2467
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

707 
numberGreedyUndefined = 0 
2271  708 
for w in W: 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

709 
if w is None: 
2467
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

710 
numberUndefined += 1 
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

711 
elif w == '*': 
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

712 
numberUndefined += 1 
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

713 
numberGreedyUndefined += 1 
2472
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

714 
elif _endswith(w,'%'): 
2467
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

715 
percentDefined += 1 
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

716 
percentTotal += float(w[:1]) 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

717 
else: 
3180
349e9644fce8
reportlab: attempt to remove type() checking in favour of isinstance
rgbecker
parents:
3177
diff
changeset

718 
assert isinstance(w,(int,float)) 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

719 
totalDefined = totalDefined + w 
3721  720 
if verbose: print('prelim width calculation. %d columns, %d undefined width, %0.2f units remain' % ( 
721 
self._ncols, numberUndefined, availWidth  totalDefined)) 

1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

722 

c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

723 
#check columnwise in each None column to see if they are sizable. 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

724 
given = [] 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

725 
sizeable = [] 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

726 
unsizeable = [] 
2467
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

727 
minimums = {} 
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

728 
totalMinimum = 0 
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

729 
elementWidth = self._elementWidth 
4140  730 
for colNo in xrange(self._ncols): 
2467
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

731 
w = W[colNo] 
2472
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

732 
if w is None or w=='*' or _endswith(w,'%'): 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

733 
siz = 1 
3529  734 
final = 0 
4140  735 
for rowNo in xrange(self._nrows): 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

736 
value = self._cellvalues[rowNo][colNo] 
2467
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

737 
style = self._cellStyles[rowNo][colNo] 
4257
967759f7f778
fix bug in tables.py reported by Vytis Banaitis @ bitbucket; version>3.3.2
robin
parents:
4252
diff
changeset

738 
new = elementWidth(value,style) or 0 
3529  739 
new += style.leftPadding+style.rightPadding 
740 
final = max(final, new) 

2467
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

741 
siz = siz and self._canGetWidth(value) # irrelevant now? 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

742 
if siz: 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

743 
sizeable.append(colNo) 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

744 
else: 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

745 
unsizeable.append(colNo) 
2467
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

746 
minimums[colNo] = final 
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

747 
totalMinimum += final 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

748 
else: 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

749 
given.append(colNo) 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

750 
if len(given) == self._ncols: 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

751 
return 
3721  752 
if verbose: print('predefined width: ',given) 
753 
if verbose: print('uncomputable width: ',unsizeable) 

754 
if verbose: print('computable width: ',sizeable) 

1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

755 

2467
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

756 
# how much width is left: 
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

757 
remaining = availWidth  (totalMinimum + totalDefined) 
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

758 
if remaining > 0: 
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

759 
# we have some room left; fill it. 
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

760 
definedPercentage = (totalDefined/availWidth)*100 
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

761 
percentTotal += definedPercentage 
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

762 
if numberUndefined and percentTotal < 100: 
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

763 
undefined = numberGreedyUndefined or numberUndefined 
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

764 
defaultWeight = (100percentTotal)/undefined 
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

765 
percentTotal = 100 
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

766 
defaultDesired = (defaultWeight/percentTotal)*availWidth 
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

767 
else: 
2472
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

768 
defaultWeight = defaultDesired = 1 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

769 
# we now calculate how wide each column wanted to be, and then 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

770 
# proportionately shrink that down to fit the remaining available 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

771 
# space. A column may not shrink less than its minimum width, 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

772 
# however, which makes this a bit more complicated. 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

773 
desiredWidths = [] 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

774 
totalDesired = 0 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

775 
effectiveRemaining = remaining 
3723
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset

776 
for colNo, minimum in minimums.items(): 
2467
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

777 
w = W[colNo] 
2472
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

778 
if _endswith(w,'%'): 
2467
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

779 
desired = (float(w[:1])/percentTotal)*availWidth 
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

780 
elif w == '*': 
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

781 
desired = defaultDesired 
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

782 
else: 
2472
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

783 
desired = not numberGreedyUndefined and defaultDesired or 1 
2467
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

784 
if desired <= minimum: 
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

785 
W[colNo] = minimum 
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

786 
else: 
2472
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

787 
desiredWidths.append( 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

788 
(desiredminimum, minimum, desired, colNo)) 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

789 
totalDesired += desired 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

790 
effectiveRemaining += minimum 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

791 
if desiredWidths: # else we're done 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

792 
# let's say we have two variable columns. One wanted 
2754  793 
# 88 points, and one wanted 264 points. The first has a 
2472
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

794 
# minWidth of 66, and the second of 55. We have 71 points 
2754  795 
# to divide up in addition to the totalMinimum (i.e., 
2472
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

796 
# remaining==71). Our algorithm tries to keep the proportion 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

797 
# of these variable columns. 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

798 
# 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

799 
# To do this, we add up the minimum widths of the variable 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

800 
# columns and the remaining width. That's 192. We add up the 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

801 
# totalDesired width. That's 352. That means we'll try to 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

802 
# shrink the widths by a proportion of 192/352.545454. 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

803 
# That would make the first column 48 points, and the second 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

804 
# 144 pointsadding up to the desired 192. 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

805 
# 
2754  806 
# Unfortunately, that's too small for the first column. It 
807 
# must be 66 points. Therefore, we go ahead and save that 

2472
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

808 
# column width as 88 points. That leaves (19288==) 104 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

809 
# points remaining. The proportion to shrink the remaining 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

810 
# column is (104/264), which, multiplied by the desired 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

811 
# width of 264, is 104: the amount assigned to the remaining 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

812 
# column. 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

813 
proportion = effectiveRemaining/totalDesired 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

814 
# we sort the desired widths by difference between desired and 
2754  815 
# and minimum values, a value called "disappointment" in the 
816 
# code. This means that the columns with a bigger 

817 
# disappointment will have a better chance of getting more of 

2472
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

818 
# the available space. 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

819 
desiredWidths.sort() 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

820 
finalSet = [] 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

821 
for disappointment, minimum, desired, colNo in desiredWidths: 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

822 
adjusted = proportion * desired 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

823 
if adjusted < minimum: 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

824 
W[colNo] = minimum 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

825 
totalDesired = desired 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

826 
effectiveRemaining = minimum 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

827 
if totalDesired: 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

828 
proportion = effectiveRemaining/totalDesired 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

829 
else: 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

830 
finalSet.append((minimum, desired, colNo)) 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

831 
for minimum, desired, colNo in finalSet: 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

832 
adjusted = proportion * desired 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

833 
assert adjusted >= minimum 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

834 
W[colNo] = adjusted 
2467
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

835 
else: 
3723
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset

836 
for colNo, minimum in minimums.items(): 
2467
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

837 
W[colNo] = minimum 
3721  838 
if verbose: print('new widths are:', W) 
2467
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

839 
self._argW = self._colWidths = W 
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

840 
return W 
2190  841 

2472
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

842 
def minWidth(self): 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

843 
W = list(self._argW) 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

844 
width = 0 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

845 
elementWidth = self._elementWidth 
4140  846 
rowNos = xrange(self._nrows) 
2474  847 
values = self._cellvalues 
848 
styles = self._cellStyles 

4140  849 
for colNo in xrange(len(W)): 
2474  850 
w = W[colNo] 
2472
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

851 
if w is None or w=='*' or _endswith(w,'%'): 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

852 
final = 0 
2474  853 
for rowNo in rowNos: 
854 
value = values[rowNo][colNo] 

855 
style = styles[rowNo][colNo] 

2472
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

856 
new = (elementWidth(value,style)+ 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

857 
style.leftPadding+style.rightPadding) 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

858 
final = max(final, new) 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

859 
width += final 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

860 
else: 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

861 
width += float(w) 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

862 
return width # XXX + 1/2*(left and right border widths) 
6795e616cdbe
tables.py: added in Gary Poster's gary@zope.com latest patch
rgbecker
parents:
2471
diff
changeset

863 

1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

864 
def _calcSpanRanges(self): 
1883  865 
"""Work out rects for tables which do row and column spanning. 
866 

1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

867 
This creates some mappings to let the later code determine 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

868 
if a cell is part of a "spanned" range. 
1883  869 
self._spanRanges shows the 'coords' in integers of each 
870 
'cell range', or None if it was clobbered: 

3031  871 
(col, row) > (col0, row0, col1, row1) 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

872 

c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

873 
Any cell not in the key is not part of a spanned region 
1883  874 
""" 
2289  875 
self._spanRanges = spanRanges = {} 
4140  876 
for x in xrange(self._ncols): 
877 
for y in xrange(self._nrows): 

2289  878 
spanRanges[x,y] = (x, y, x, y) 
879 
self._colSpanCells = [] 

880 
self._rowSpanCells = [] 

881 
csa = self._colSpanCells.append 

882 
rsa = self._rowSpanCells.append 

1883  883 
for (cmd, start, stop) in self._spanCmds: 
884 
x0, y0 = start 

885 
x1, y1 = stop 

886 

887 
#normalize 

888 
if x0 < 0: x0 = x0 + self._ncols 

889 
if x1 < 0: x1 = x1 + self._ncols 

890 
if y0 < 0: y0 = y0 + self._nrows 

891 
if y1 < 0: y1 = y1 + self._nrows 

2289  892 
if x0 > x1: x0, x1 = x1, x0 
893 
if y0 > y1: y0, y1 = y1, y0 

1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

894 

2289  895 
if x0!=x1 or y0!=y1: 
2812
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

896 
if x0!=x1: #column span 
4140  897 
for y in xrange(y0, y1+1): 
898 
for x in xrange(x0,x1+1): 

2812
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

899 
csa((x,y)) 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

900 
if y0!=y1: #row span 
4140  901 
for y in xrange(y0, y1+1): 
902 
for x in xrange(x0,x1+1): 

2812
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

903 
rsa((x,y)) 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

904 

4140  905 
for y in xrange(y0, y1+1): 
906 
for x in xrange(x0,x1+1): 

2812
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

907 
spanRanges[x,y] = None 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

908 
# set the main entry 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

909 
spanRanges[x0,y0] = (x0, y0, x1, y1) 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

910 

3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

911 
def _calcNoSplitRanges(self): 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

912 
""" 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

913 
This creates some mappings to let the later code determine 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

914 
if a cell is part of a "nosplit" range. 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

915 
self._nosplitRanges shows the 'coords' in integers of each 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

916 
'cell range', or None if it was clobbered: 
3031  917 
(col, row) > (col0, row0, col1, row1) 
2812
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

918 

3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

919 
Any cell not in the key is not part of a spanned region 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

920 
""" 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

921 
self._nosplitRanges = nosplitRanges = {} 
4140  922 
for x in xrange(self._ncols): 
923 
for y in xrange(self._nrows): 

2812
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

924 
nosplitRanges[x,y] = (x, y, x, y) 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

925 
self._colNoSplitCells = [] 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

926 
self._rowNoSplitCells = [] 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

927 
csa = self._colNoSplitCells.append 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

928 
rsa = self._rowNoSplitCells.append 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

929 
for (cmd, start, stop) in self._nosplitCmds: 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

930 
x0, y0 = start 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

931 
x1, y1 = stop 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

932 

3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

933 
#normalize 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

934 
if x0 < 0: x0 = x0 + self._ncols 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

935 
if x1 < 0: x1 = x1 + self._ncols 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

936 
if y0 < 0: y0 = y0 + self._nrows 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

937 
if y1 < 0: y1 = y1 + self._nrows 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

938 
if x0 > x1: x0, x1 = x1, x0 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

939 
if y0 > y1: y0, y1 = y1, y0 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

940 

3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

941 
if x0!=x1 or y0!=y1: 
2289  942 
#column span 
943 
if x0!=x1: 

4140  944 
for y in xrange(y0, y1+1): 
945 
for x in xrange(x0,x1+1): 

2289  946 
csa((x,y)) 
947 
#row span 

948 
if y0!=y1: 

4140  949 
for y in xrange(y0, y1+1): 
950 
for x in xrange(x0,x1+1): 

2289  951 
rsa((x,y)) 
2190  952 

4140  953 
for y in xrange(y0, y1+1): 
954 
for x in xrange(x0,x1+1): 

2812
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

955 
nosplitRanges[x,y] = None 
2289  956 
# set the main entry 
2812
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

957 
nosplitRanges[x0,y0] = (x0, y0, x1, y1) 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

958 

c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

959 
def _calcSpanRects(self): 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

960 
"""Work out rects for tables which do row and column spanning. 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

961 

c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

962 
Based on self._spanRanges, which is already known, 
2190  963 
and the widths which were given or previously calculated, 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

964 
self._spanRects shows the real coords for drawing: 
4258
d3e9de82a5aa
add table cell support for simple background shadings, contributed by Jeffrey Creem jcreem@bitbucket
robin
parents:
4257
diff
changeset

965 

3031  966 
(col, row) > (x, y, width, height) 
2190  967 

1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

968 
for each cell. Any cell which 'does not exist' as another 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

969 
has spanned over it will get a None entry on the right 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

970 
""" 
3462
c9a0ccee737d
tables.py: make more robust for LongTable & spans
rgbecker
parents:
3442
diff
changeset

971 
spanRects = getattr(self,'_spanRects',{}) 
c9a0ccee737d
tables.py: make more robust for LongTable & spans
rgbecker
parents:
3442
diff
changeset

972 
hmax = getattr(self,'_hmax',None) 
c9a0ccee737d
tables.py: make more robust for LongTable & spans
rgbecker
parents:
3442
diff
changeset

973 
longTable = self._longTableOptimize 
c9a0ccee737d
tables.py: make more robust for LongTable & spans
rgbecker
parents:
3442
diff
changeset

974 
if spanRects and (longTable and hmax==self._hmax_spanRects or not longTable): 
c9a0ccee737d
tables.py: make more robust for LongTable & spans
rgbecker
parents:
3442
diff
changeset

975 
return 
2412
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

976 
colpositions = self._colpositions 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

977 
rowpositions = self._rowpositions 
3462
c9a0ccee737d
tables.py: make more robust for LongTable & spans
rgbecker
parents:
3442
diff
changeset

978 
vBlocks = {} 
c9a0ccee737d
tables.py: make more robust for LongTable & spans
rgbecker
parents:
3442
diff
changeset

979 
hBlocks = {} 
c9a0ccee737d
tables.py: make more robust for LongTable & spans
rgbecker
parents:
3442
diff
changeset

980 
rlim = len(rowpositions)1 
3721  981 
for (coord, value) in self._spanRanges.items(): 
1883  982 
if value is None: 
983 
spanRects[coord] = None 

984 
else: 

3462
c9a0ccee737d
tables.py: make more robust for LongTable & spans
rgbecker
parents:
3442
diff
changeset

985 
col0, row0, col1, row1 = value 
c9a0ccee737d
tables.py: make more robust for LongTable & spans
rgbecker
parents:
3442
diff
changeset

986 
if row1>=rlim: continue 
1883  987 
col,row = coord 
2412
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

988 
if col1col0>0: 
4140  989 
for _ in xrange(col0+1,col1+1): 
2412
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

990 
vBlocks.setdefault(colpositions[_],[]).append((rowpositions[row1+1],rowpositions[row0])) 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

991 
if row1row0>0: 
4140  992 
for _ in xrange(row0+1,row1+1): 
2412
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

993 
hBlocks.setdefault(rowpositions[_],[]).append((colpositions[col0],colpositions[col1+1])) 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

994 
x = colpositions[col0] 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

995 
y = rowpositions[row1+1] 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

996 
width = colpositions[col1+1]  x 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

997 
height = rowpositions[row0]  y 
1883  998 
spanRects[coord] = (x, y, width, height) 
2190  999 

2412
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

1000 
for _ in hBlocks, vBlocks: 
3723
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset

1001 
for value in _.values(): 
2412
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

1002 
value.sort() 
3462
c9a0ccee737d
tables.py: make more robust for LongTable & spans
rgbecker
parents:
3442
diff
changeset

1003 
self._spanRects = spanRects 
c9a0ccee737d
tables.py: make more robust for LongTable & spans
rgbecker
parents:
3442
diff
changeset

1004 
self._vBlocks = vBlocks 
c9a0ccee737d
tables.py: make more robust for LongTable & spans
rgbecker
parents:
3442
diff
changeset

1005 
self._hBlocks = hBlocks 
c9a0ccee737d
tables.py: make more robust for LongTable & spans
rgbecker
parents:
3442
diff
changeset

1006 
self._hmax_spanRects = hmax 
2190  1007 

1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1008 
def setStyle(self, tblstyle): 
3180
349e9644fce8
reportlab: attempt to remove type() checking in favour of isinstance
rgbecker
parents:
3177
diff
changeset

1009 
if not isinstance(tblstyle,TableStyle): 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1010 
tblstyle = TableStyle(tblstyle) 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1011 
for cmd in tblstyle.getCommands(): 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1012 
self._addCommand(cmd) 
3723
99aa837b6703
second stage of port to Python 3.3; working hello world
rptlab
parents:
3721
diff
changeset

1013 
for k,v in tblstyle._opts.items(): 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1014 
setattr(self,k,v) 
2574  1015 
for a in ('spaceBefore','spaceAfter'): 
1016 
if not hasattr(self,a) and hasattr(tblstyle,a): 

1017 
setattr(self,a,getattr(tblstyle,a)) 

350  1018 

1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1019 
def _addCommand(self,cmd): 
2393  1020 
if cmd[0] in ('BACKGROUND','ROWBACKGROUNDS','COLBACKGROUNDS'): 
2392  1021 
self._bkgrndcmds.append(cmd) 
1883  1022 
elif cmd[0] == 'SPAN': 
1023 
self._spanCmds.append(cmd) 

2812
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

1024 
elif cmd[0] == 'NOSPLIT': 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

1025 
# we expect op, start, stop 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

1026 
self._nosplitCmds.append(cmd) 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1027 
elif _isLineCommand(cmd): 
1699  1028 
# we expect op, start, stop, weight, colour, cap, dashes, join 
2523
0473810aff11
platypus: fix up None defaults for table line commands, add HRFlowable dash arg
rgbecker
parents:
2495
diff
changeset

1029 
cmd = list(cmd) 
4025
b2eb4dd254cf
tables.py: fix various command issues when unicode commands are used
robin
parents:
4019
diff
changeset

1030 
if len(cmd)<5: raise ValueError('bad line command '+ascii(cmd)) 
2219
5c1727997169
Multiple lines and decimal alignments now supported
andy_robinson
parents:
2200
diff
changeset

1031 

3203  1032 
#determine line cap value at position 5. This can be str or numeric. 
2219
5c1727997169
Multiple lines and decimal alignments now supported
andy_robinson
parents:
2200
diff
changeset

1033 
if len(cmd)<6: 
2523
0473810aff11
platypus: fix up None defaults for table line commands, add HRFlowable dash arg
rgbecker
parents:
2495
diff
changeset

1034 
cmd.append(1) 
1699  1035 
else: 
2469  1036 
cap = _convert2int(cmd[5], LINECAPS, 0, 2, 'cap', cmd) 
2523
0473810aff11
platypus: fix up None defaults for table line commands, add HRFlowable dash arg
rgbecker
parents:
2495
diff
changeset

1037 
cmd[5] = cap 
2464
09cfec86fa5a
tables.py: fixes to join/cap/dash from Gary Poster
rgbecker
parents:
2463
diff
changeset

1038 

2219
5c1727997169
Multiple lines and decimal alignments now supported
andy_robinson
parents:
2200
diff
changeset

1039 
#dashes at index 6  this is a dash array: 
2523
0473810aff11
platypus: fix up None defaults for table line commands, add HRFlowable dash arg
rgbecker
parents:
2495
diff
changeset

1040 
if len(cmd)<7: cmd.append(None) 
2219
5c1727997169
Multiple lines and decimal alignments now supported
andy_robinson
parents:
2200
diff
changeset

1041 

3203  1042 
#join mode at index 7  can be str or numeric, look up as for caps 
2523
0473810aff11
platypus: fix up None defaults for table line commands, add HRFlowable dash arg
rgbecker
parents:
2495
diff
changeset

1043 
if len(cmd)<8: cmd.append(1) 
1699  1044 
else: 
2469  1045 
join = _convert2int(cmd[7], LINEJOINS, 0, 2, 'join', cmd) 
2523
0473810aff11
platypus: fix up None defaults for table line commands, add HRFlowable dash arg
rgbecker
parents:
2495
diff
changeset

1046 
cmd[7] = join 
2219
5c1727997169
Multiple lines and decimal alignments now supported
andy_robinson
parents:
2200
diff
changeset

1047 

5c1727997169
Multiple lines and decimal alignments now supported
andy_robinson
parents:
2200
diff
changeset

1048 
#linecount at index 8. Default is 1, set to 2 for double line. 
2523
0473810aff11
platypus: fix up None defaults for table line commands, add HRFlowable dash arg
rgbecker
parents:
2495
diff
changeset

1049 
if len(cmd)<9: cmd.append(1) 
2219
5c1727997169
Multiple lines and decimal alignments now supported
andy_robinson
parents:
2200
diff
changeset

1050 
else: 
5c1727997169
Multiple lines and decimal alignments now supported
andy_robinson
parents:
2200
diff
changeset

1051 
lineCount = cmd[8] 
2523
0473810aff11
platypus: fix up None defaults for table line commands, add HRFlowable dash arg
rgbecker
parents:
2495
diff
changeset

1052 
if lineCount is None: 
0473810aff11
platypus: fix up None defaults for table line commands, add HRFlowable dash arg
rgbecker
parents:
2495
diff
changeset

1053 
lineCount = 1 
0473810aff11
platypus: fix up None defaults for table line commands, add HRFlowable dash arg
rgbecker
parents:
2495
diff
changeset

1054 
cmd[8] = lineCount 
0473810aff11
platypus: fix up None defaults for table line commands, add HRFlowable dash arg
rgbecker
parents:
2495
diff
changeset

1055 
assert lineCount >= 1 
2221  1056 
#linespacing at index 9. Not applicable unless 2+ lines, defaults to line 
2219
5c1727997169
Multiple lines and decimal alignments now supported
andy_robinson
parents:
2200
diff
changeset

1057 
#width so you get a visible gap between centres 
2523
0473810aff11
platypus: fix up None defaults for table line commands, add HRFlowable dash arg
rgbecker
parents:
2495
diff
changeset

1058 
if len(cmd)<10: cmd.append(cmd[3]) 
0473810aff11
platypus: fix up None defaults for table line commands, add HRFlowable dash arg
rgbecker
parents:
2495
diff
changeset

1059 
else: 
0473810aff11
platypus: fix up None defaults for table line commands, add HRFlowable dash arg
rgbecker
parents:
2495
diff
changeset

1060 
space = cmd[9] 
0473810aff11
platypus: fix up None defaults for table line commands, add HRFlowable dash arg
rgbecker
parents:
2495
diff
changeset

1061 
if space is None: 
0473810aff11
platypus: fix up None defaults for table line commands, add HRFlowable dash arg
rgbecker
parents:
2495
diff
changeset

1062 
space = cmd[3] 
0473810aff11
platypus: fix up None defaults for table line commands, add HRFlowable dash arg
rgbecker
parents:
2495
diff
changeset

1063 
cmd[9] = space 
2219
5c1727997169
Multiple lines and decimal alignments now supported
andy_robinson
parents:
2200
diff
changeset

1064 
assert len(cmd) == 10 
2414
81be267fa92c
tables.py: extend span line blocking to multi lines
rgbecker
parents:
2412
diff
changeset

1065 

2523
0473810aff11
platypus: fix up None defaults for table line commands, add HRFlowable dash arg
rgbecker
parents:
2495
diff
changeset

1066 
self._linecmds.append(tuple(cmd)) 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1067 
else: 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1068 
(op, (sc, sr), (ec, er)), values = cmd[:3] , cmd[3:] 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1069 
if sc < 0: sc = sc + self._ncols 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1070 
if ec < 0: ec = ec + self._ncols 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1071 
if sr < 0: sr = sr + self._nrows 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1072 
if er < 0: er = er + self._nrows 
4140  1073 
for i in xrange(sr, er+1): 
1074 
for j in xrange(sc, ec+1): 

1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1075 
_setCellStyle(self._cellStyles, i, j, op, values) 
326  1076 

1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1077 
def _drawLines(self): 
1699  1078 
ccap, cdash, cjoin = None, None, None 
1079 
self.canv.saveState() 

2219
5c1727997169
Multiple lines and decimal alignments now supported
andy_robinson
parents:
2200
diff
changeset

1080 
for op, (sc,sr), (ec,er), weight, color, cap, dash, join, count, space in self._linecmds: 
4025
b2eb4dd254cf
tables.py: fix various command issues when unicode commands are used
robin
parents:
4019
diff
changeset

1081 
if isinstance(sr,strTypes) and sr.startswith('split'): continue 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1082 
if sc < 0: sc = sc + self._ncols 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1083 
if ec < 0: ec = ec + self._ncols 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1084 
if sr < 0: sr = sr + self._nrows 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1085 
if er < 0: er = er + self._nrows 
2414
81be267fa92c
tables.py: extend span line blocking to multi lines
rgbecker
parents:
2412
diff
changeset

1086 
if cap!=None and ccap!=cap: 
1699  1087 
self.canv.setLineCap(cap) 
1088 
ccap = cap 

2464
09cfec86fa5a
tables.py: fixes to join/cap/dash from Gary Poster
rgbecker
parents:
2463
diff
changeset

1089 
if dash is None or dash == []: 
09cfec86fa5a
tables.py: fixes to join/cap/dash from Gary Poster
rgbecker
parents:
2463
diff
changeset

1090 
if cdash is not None: 
09cfec86fa5a
tables.py: fixes to join/cap/dash from Gary Poster
rgbecker
parents:
2463
diff
changeset

1091 
self.canv.setDash() 
09cfec86fa5a
tables.py: fixes to join/cap/dash from Gary Poster
rgbecker
parents:
2463
diff
changeset

1092 
cdash = None 
09cfec86fa5a
tables.py: fixes to join/cap/dash from Gary Poster
rgbecker
parents:
2463
diff
changeset

1093 
elif dash != cdash: 
09cfec86fa5a
tables.py: fixes to join/cap/dash from Gary Poster
rgbecker
parents:
2463
diff
changeset

1094 
self.canv.setDash(dash) 
09cfec86fa5a
tables.py: fixes to join/cap/dash from Gary Poster
rgbecker
parents:
2463
diff
changeset

1095 
cdash = dash 
09cfec86fa5a
tables.py: fixes to join/cap/dash from Gary Poster
rgbecker
parents:
2463
diff
changeset

1096 
if join is not None and cjoin!=join: 
09cfec86fa5a
tables.py: fixes to join/cap/dash from Gary Poster
rgbecker
parents:
2463
diff
changeset

1097 
self.canv.setLineJoin(join) 
09cfec86fa5a
tables.py: fixes to join/cap/dash from Gary Poster
rgbecker
parents:
2463
diff
changeset

1098 
cjoin = join 
2219
5c1727997169
Multiple lines and decimal alignments now supported
andy_robinson
parents:
2200
diff
changeset

1099 
getattr(self,_LineOpMap.get(op, '_drawUnknown' ))( (sc, sr), (ec, er), weight, color, count, space) 
1699  1100 
self.canv.restoreState() 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1101 
self._curcolor = None 
248  1102 

3326  1103 
def _drawUnknown(self, start, end, weight, color, count, space): 
2730  1104 
#we are only called from _drawLines which is one level up 
1105 
import sys 

1106 
op = sys._getframe(1).f_locals['op'] 

1107 
raise ValueError("Unknown line command '%s'" % op) 

403  1108 

3326  1109 
def _drawGrid(self, start, end, weight, color, count, space): 
1110 
self._drawBox( start, end, weight, color, count, space) 

1111 
self._drawInnerGrid( start, end, weight, color, count, space) 

403  1112 

3326  1113 
def _drawBox(self, start, end, weight, color, count, space): 
1114 
sc,sr = start 

1115 
ec,er = end 

2219
5c1727997169
Multiple lines and decimal alignments now supported
andy_robinson
parents:
2200
diff
changeset

1116 
self._drawHLines((sc, sr), (ec, sr), weight, color, count, space) 
5c1727997169
Multiple lines and decimal alignments now supported
andy_robinson
parents:
2200
diff
changeset

1117 
self._drawHLines((sc, er+1), (ec, er+1), weight, color, count, space) 
5c1727997169
Multiple lines and decimal alignments now supported
andy_robinson
parents:
2200
diff
changeset

1118 
self._drawVLines((sc, sr), (sc, er), weight, color, count, space) 
5c1727997169
Multiple lines and decimal alignments now supported
andy_robinson
parents:
2200
diff
changeset

1119 
self._drawVLines((ec+1, sr), (ec+1, er), weight, color, count, space) 
350  1120 

3326  1121 
def _drawInnerGrid(self, start, end, weight, color, count, space): 
1122 
sc,sr = start 

1123 
ec,er = end 

2219
5c1727997169
Multiple lines and decimal alignments now supported
andy_robinson
parents:
2200
diff
changeset

1124 
self._drawHLines((sc, sr+1), (ec, er), weight, color, count, space) 
5c1727997169
Multiple lines and decimal alignments now supported
andy_robinson
parents:
2200
diff
changeset

1125 
self._drawVLines((sc+1, sr), (ec, er), weight, color, count, space) 
350  1126 

1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1127 
def _prepLine(self, weight, color): 
4166
23aed7105d93
allow missing values for colour and weight in cell line options
robin
parents:
4140
diff
changeset

1128 
if color and color!=self._curcolor: 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1129 
self.canv.setStrokeColor(color) 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1130 
self._curcolor = color 
4166
23aed7105d93
allow missing values for colour and weight in cell line options
robin
parents:
4140
diff
changeset

1131 
if weight and weight!=self._curweight: 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1132 
self.canv.setLineWidth(weight) 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1133 
self._curweight = weight 
350  1134 

3326  1135 
def _drawHLines(self, start, end, weight, color, count, space): 
1136 
sc,sr = start 

1137 
ec,er = end 

1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1138 
ecp = self._colpositions[sc:ec+2] 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1139 
rp = self._rowpositions[sr:er+1] 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1140 
if len(ecp)<=1 or len(rp)<1: return 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1141 
self._prepLine(weight, color) 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1142 
scp = ecp[0] 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1143 
ecp = ecp[1] 
2412
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

1144 
hBlocks = getattr(self,'_hBlocks',{}) 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

1145 
canvLine = self.canv.line 
2220  1146 
if count == 1: 
2412
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

1147 
for y in rp: 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

1148 
_hLine(canvLine, scp, ecp, y, hBlocks) 
2220  1149 
else: 
2414
81be267fa92c
tables.py: extend span line blocking to multi lines
rgbecker
parents:
2412
diff
changeset

1150 
lf = lambda x0,y0,x1,y1,canvLine=canvLine, ws=weight+space, count=count: _multiLine(x0,x1,y0,canvLine,ws,count) 
2412
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

1151 
for y in rp: 
2414
81be267fa92c
tables.py: extend span line blocking to multi lines
rgbecker
parents:
2412
diff
changeset

1152 
_hLine(lf, scp, ecp, y, hBlocks) 
403  1153 

3326  1154 
def _drawHLinesB(self, start, end, weight, color, count, space): 
1155 
sc,sr = start 

1156 
ec,er = end 

2219
5c1727997169
Multiple lines and decimal alignments now supported
andy_robinson
parents:
2200
diff
changeset

1157 
self._drawHLines((sc, sr+1), (ec, er+1), weight, color, count, space) 
5c1727997169
Multiple lines and decimal alignments now supported
andy_robinson
parents:
2200
diff
changeset

1158 

3326  1159 
def _drawVLines(self, start, end, weight, color, count, space): 
1160 
sc,sr = start 

1161 
ec,er = end 

1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1162 
erp = self._rowpositions[sr:er+2] 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1163 
cp = self._colpositions[sc:ec+1] 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1164 
if len(erp)<=1 or len(cp)<1: return 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1165 
self._prepLine(weight, color) 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1166 
srp = erp[0] 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1167 
erp = erp[1] 
2412
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

1168 
vBlocks = getattr(self,'_vBlocks',{}) 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

1169 
canvLine = lambda y0, x0, y1, x1, _line=self.canv.line: _line(x0,y0,x1,y1) 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

1170 
if count == 1: 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

1171 
for x in cp: 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

1172 
_hLine(canvLine, erp, srp, x, vBlocks) 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

1173 
else: 
2414
81be267fa92c
tables.py: extend span line blocking to multi lines
rgbecker
parents:
2412
diff
changeset

1174 
lf = lambda x0,y0,x1,y1,canvLine=canvLine, ws=weight+space, count=count: _multiLine(x0,x1,y0,canvLine,ws,count) 
2412
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

1175 
for x in cp: 
2414
81be267fa92c
tables.py: extend span line blocking to multi lines
rgbecker
parents:
2412
diff
changeset

1176 
_hLine(lf, erp, srp, x, vBlocks) 
326  1177 

3326  1178 
def _drawVLinesA(self, start, end, weight, color, count, space): 
1179 
sc,sr = start 

1180 
ec,er = end 

2219
5c1727997169
Multiple lines and decimal alignments now supported
andy_robinson
parents:
2200
diff
changeset

1181 
self._drawVLines((sc+1, sr), (ec+1, er), weight, color, count, space) 
403  1182 

1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1183 
def wrap(self, availWidth, availHeight): 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

1184 
self._calc(availWidth, availHeight) 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1185 
self.availWidth = availWidth 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1186 
return (self._width, self._height) 
1495  1187 

1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1188 
def onSplit(self,T,byRow=1): 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1189 
''' 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
