author  rgbecker 
Tue, 15 Nov 2011 10:21:04 +0000  
changeset 3551  dc4aedd55fea 
parent 3529  96c3c28f6cb3 
child 3561  20c19cc4e6e4 
permissions  rwxrxrx 
2332  1 
#Copyright ReportLab Europe Ltd. 20002004 
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 
4 
__version__=''' $Id$ ''' 

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 
3518
3f201e3d0432
tables.py: fix bug when splitting across rowspans
rgbecker
parents:
3515
diff
changeset

24 
from reportlab.lib.utils import fp_str, annotateException, IdentStr 
3521  25 
from reportlab.lib.abag import ABag as CellFrame 
2754  26 
from reportlab.pdfbase.pdfmetrics import stringWidth 
3521  27 
from reportlab.platypus.doctemplate import Indenter 
28 
from reportlab.platypus.flowables import LIIndenter 

6  29 

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

1699  32 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

55 
for name in dir(self): 
2730  56 
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

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

58 

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

60 
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

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

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

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

64 
# 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

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

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

69 
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

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

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

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

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

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

75 

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

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

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

78 
def __repr__(self): 
3203  79 
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

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

81 
return self._cmds 
338  82 

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

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

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

88 
1) absolute values go through unchanged 

89 
2) percentages are used as weights for unconsumed space 

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

91 
set equally with unclaimed space 

92 
otherwise * weights are assigned as None''' 

93 
R = [] 

94 
r = R.append 

95 
I = [] 

96 
i = I.append 

97 
J = [] 

98 
j = J.append 

99 
s = avail 

100 
w = n = 0. 

101 
for v in V: 

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

102 
if isinstance(v,basestring): 
2271  103 
v = v.strip() 
104 
if not v: 

105 
v = None 

106 
n += 1 

107 
elif v.endswith('%'): 

108 
v = float(v[:1]) 

109 
w += v 

110 
i(len(R)) 

111 
elif v=='*': 

112 
j(len(R)) 

113 
else: 

114 
v = float(v) 

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

118 
else: 

119 
s = v 

120 
r(v) 

121 
s = max(0.,s) 

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

123 
for i in I: 

124 
R[i] *= f 

125 
s = R[i] 

126 
s = max(0.,s) 

127 
m = len(J) 

128 
if m: 

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

130 
for j in J: 

131 
R[j] = v 

132 
return R 

356  133 

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

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

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

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

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

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

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

140 
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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

155 

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

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

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

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

159 
for idx in xrange(count): 
81be267fa92c
tables.py: extend span line blocking to multi lines
rgbecker
parents:
2412
diff
changeset

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

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

162 

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

165 
try: 

166 
return map[value] 

167 
except KeyError: 

168 
try: 

169 
ivalue = int(value) 

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

171 
except: 

172 
pass 

173 
raise ValueError('Bad %s value %s in %s'%(name,value,str(cmd))) 

174 

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

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

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

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

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

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

180 

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

181 
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

182 
#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

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

184 
if not lim: lim = len(V0) #in longtables the row calcs may be truncated 
2879
0ba5481218bd
tables.py: slightly better spanned row height calcs
rgbecker
parents:
2878
diff
changeset

185 
for (x0,x1),v in spanCons.iteritems(): 
3462
c9a0ccee737d
tables.py: make more robust for LongTable & spans
rgbecker
parents:
3442
diff
changeset

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

187 
x1 += 1 
c9a0ccee737d
tables.py: make more robust for LongTable & spans
rgbecker
parents:
3442
diff
changeset

188 
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

189 
if t>=vFUZZ: continue #already good enough 
3462
c9a0ccee737d
tables.py: make more robust for LongTable & spans
rgbecker
parents:
3442
diff
changeset

190 
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

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

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

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

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

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

196 
for x,v in M.iteritems(): 
0ba5481218bd
tables.py: slightly better spanned row height calcs
rgbecker
parents:
2878
diff
changeset

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

198 

3521  199 
class _ExpandedCellTuple(tuple): 
200 
pass 

201 

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

203 
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

204 
repeatRows=0, repeatCols=0, splitByRow=1, emptyTableAction=None, ident=None, 
3325
64eb1b787d02
tables.py: apply optimization contributed by Tomasz Swiderski
rgbecker
parents:
3240
diff
changeset

205 
hAlign=None,vAlign=None, normalizedData=0, cellStyles=None): 
2467
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

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

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

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

209 
if not isinstance(data,(tuple,list)): 
2915  210 
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

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

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

214 
_seqRH = isinstance(rowHeights,(tuple,list)) 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

215 
if nrows: self._ncols = ncols = max(map(_rowLen,data)) 
2401  216 
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

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

218 
if not emptyTableAction: emptyTableAction = rl_config.emptyTableAction 
3462
c9a0ccee737d
tables.py: make more robust for LongTable & spans
rgbecker
parents:
3442
diff
changeset

219 
self._longTableOptimize = getattr(self,'_longTableOptimize',rl_config.longTableOptimize) 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

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

221 
if emptyTableAction=='error': 
2915  222 
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

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

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

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

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

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

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

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

230 
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

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

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

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

234 
else: 
2915  235 
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

236 
return 
1533  237 

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

238 
# 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

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

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

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

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

246 
n = len(colWidths) 

247 
if n<ncols: 

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

249 
else: 

250 
colWidths = colWidths[:ncols] 

251 
else: 

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

2401  253 
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

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

258 
if n!=ncols: 

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

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

261 
else: 

262 
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

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

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

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

266 
cellrows = [] 
64eb1b787d02
tables.py: apply optimization contributed by Tomasz Swiderski
rgbecker
parents:
3240
diff
changeset

267 
for i in xrange(nrows): 
64eb1b787d02
tables.py: apply optimization contributed by Tomasz Swiderski
rgbecker
parents:
3240
diff
changeset

268 
cellcols = [] 
64eb1b787d02
tables.py: apply optimization contributed by Tomasz Swiderski
rgbecker
parents:
3240
diff
changeset

269 
for j in xrange(ncols): 
3326  270 
cellcols.append(CellStyle(repr((i,j)))) 
3325
64eb1b787d02
tables.py: apply optimization contributed by Tomasz Swiderski
rgbecker
parents:
3240
diff
changeset

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

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

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

274 
self._cellStyles = cellStyles 
350  275 

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

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

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

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

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

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

282 
self.splitByRow = splitByRow 
6  283 

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

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

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

286 

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

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

288 
"incomplete, but better than nothing" 
2389  289 
r = getattr(self,'_rowHeights','[unknown]') 
290 
c = getattr(self,'_colWidths','[unknown]') 

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

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

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

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

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

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

298 
"""Takes a block of input data (list of lists etc.) and 
2590  299 
 coerces unicode strings to nonunicode UTF8 
300 
 coerces nulls to '' 

2754  301 
 
302 

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

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

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

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

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

307 
elif isinstance(stuff,unicode): 
2589
1af821ded9f1
added japanese splitting test, and table preprocessor to convert unicode>utf8
andy
parents:
2582
diff
changeset

308 
return stuff.encode('utf8') 
1af821ded9f1
added japanese splitting test, and table preprocessor to convert unicode>utf8
andy
parents:
2582
diff
changeset

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

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

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

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

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

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

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

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

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

318 

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

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

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

321 
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

322 
vx = None 
1989  323 
nr = getattr(self,'_nrows','unknown') 
324 
nc = getattr(self,'_ncols','unknown') 

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

325 
cv = getattr(self,'_cellvalues',None) 
3523  326 
rh = getattr(self, '_rowHeights', None) 
1989  327 
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

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

329 
for i in xrange(nr): 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

330 
for j in xrange(nc): 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

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

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

333 
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

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

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

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

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

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

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

340 
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

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

342 
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

343 
ix, jx, vx = i, j, v 
3180
349e9644fce8
reportlab: attempt to remove type() checking in favour of isinstance
rgbecker
parents:
3177
diff
changeset

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

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

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

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

350 
else: 

351 
tallest = '' 

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

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

353 
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

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

355 
vx = '...' 
1103  356 

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

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

361 
for c in C: 

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

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

364 
yield d 

365 
else: 

366 
yield c 

367 

3521  368 
def _cellListProcess(self,C,aW,aH): 
369 
if not isinstance(C,_ExpandedCellTuple): 

370 
frame = None 

371 
R = [].append 

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

373 
if isinstance(c,Indenter): 

374 
if not frame: 

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

376 
c.frameAction(frame) 

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

378 
frame = None 

379 
continue 

380 
if frame: 

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

382 
else: 

383 
R(c) 

384 
C = _ExpandedCellTuple(R.__self__) 

385 
return C 

386 

2189  387 
def _listCellGeom(self, V,w,s,W=None,H=None,aH=72000): 
2481  388 
if not V: return 0,0 
2754  389 
aW = w  s.leftPadding  s.rightPadding 
2189  390 
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

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

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

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

395 
for v in V: 
2754  396 
vw, vh = v.wrapOn(canv, aW, aH) 
397 
sb = v.getSpaceBefore() 

398 
sa = v.getSpaceAfter() 

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

399 
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

400 
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

401 
w = max(w,vw) 
2754  402 
t += vh + sa + sb 
403 
if sb0 is None: 

404 
sb0 = sb 

405 
return w, t  sb0  sa 

406 

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

408 
if not V: return 0,0 

409 
t = 0 

410 
w = 0 

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

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

1492  413 

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

2271  417 
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

418 
if None in W: #some column widths are not given 
2289  419 
canv = getattr(self,'canv',None) 
420 
saved = None 

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

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

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

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

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

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

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

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

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

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

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

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

432 
W0 = W[:] 
3203  433 
V = self._cellvalues 
434 
S = self._cellStyles 

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

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

436 
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

437 
w = 0 
3203  438 
for i,Vi in enumerate(V): 
439 
v = Vi[j] 

440 
s = S[i][j] 

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

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

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

443 
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

444 
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

445 
else:#work out size 
1917  446 
t = self._elementWidth(v,s) 
447 
if t is None: 

2915  448 
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

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

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

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

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

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

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

455 
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

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

457 
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

458 

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

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

460 

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

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

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

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

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

465 
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

466 

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

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

469 
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

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

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

472 
self._colpositions.append(width) 
1683  473 

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

474 
self._width = width 
2289  475 
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

476 

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

478 
if isinstance(v,(list,tuple)): 
1917  479 
w = 0 
480 
for e in v: 

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

481 
ew = self._elementWidth(e,s) 
1917  482 
if ew is None: return None 
483 
w = max(w,ew) 

484 
return w 

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

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

486 
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

487 
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

488 
# 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

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

490 
# 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

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

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

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

494 
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

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

496 
pass 
3529  497 
if v is None: 
498 
return 0 

499 
else: 

500 
try: 

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

502 
except: 

503 
return 0 

2754  504 
fontName = s.fontname 
505 
fontSize = s.fontsize 

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

1917  507 

2271  508 
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

509 
H = self._argH 
2271  510 
if not W: W = _calc_pc(self._argW,availWidth) #widths array 
6  511 

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

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

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

514 

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

515 
if None in H: 
2289  516 
canv = getattr(self,'canv',None) 
517 
saved = None 

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

519 
if self._spanCmds: 

520 
rowSpanCells = self._rowSpanCells 

521 
colSpanCells = self._colSpanCells 

522 
spanRanges = self._spanRanges 

523 
colpositions = self._colpositions 

524 
else: 

525 
rowSpanCells = colSpanCells = () 

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

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

527 
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

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

529 
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

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

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

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

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

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

535 
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

536 
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

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

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

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

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

543 
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

544 
else: 
2754  545 
if isinstance(v,(tuple,list,Flowable)): 
546 
if isinstance(v,Flowable): v = (v,) 

3521  547 
v = V[j] = self._cellListProcess(v,w,None) 
2754  548 
if w is None and not self._canGetWidth(v): 
2915  549 
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

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

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

553 
w = max(colpositions[span[2]+1]colpositions[span[0]],w) 
2754  554 
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

555 
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

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

557 
if not rl_config.allowTableBoundsErrors and dW>w: 
2915  558 
from reportlab.platypus.doctemplate import LayoutError 
559 
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

560 
else: 
2754  561 
v = (v is not None and str(v) or '').split("\n") 
562 
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

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

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

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

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

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

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

569 
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

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

571 
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

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

573 
# 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

574 
if longTable: 
04d53e2083bd
Fix for bug 609 (corner case of long table splitting throwed exception).
jonas
parents:
3031
diff
changeset

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

577 
if height > availHeight: 
3518
3f201e3d0432
tables.py: fix bug when splitting across rowspans
rgbecker
parents:
3515
diff
changeset

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

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

580 
msr = max([x[1] for x in spanCons.keys()]) #RS=[endrowspan,.....] 
3f201e3d0432
tables.py: fix bug when splitting across rowspans
rgbecker
parents:
3515
diff
changeset

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

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

583 
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

584 

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

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

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

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

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

589 
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

590 

3203  591 
height = self._height = sum(H[:hmax]) 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

592 
self._rowpositions = [height] # index 0 is actually topline; we skip when processing cells 
2194
6bc71309eb18
Modified version of Henning von Bargen's LongTables optimisation
rgbecker
parents:
2190
diff
changeset

593 
for h in H[:hmax]: 
3462
c9a0ccee737d
tables.py: make more robust for LongTable & spans
rgbecker
parents:
3442
diff
changeset

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

595 
self._rowpositions.append(height) 
3507
5d4f0215bd8f
tables.py: make height error message more informative
rgbecker
parents:
3504
diff
changeset

596 
assert abs(height)<1e8, '!!!!!%s\ninternal height error height=%r hmax=%d Sum(H[:%d])=%r\nH=%r\nrowPositions=%r' % (self.identity(),height,hmax,hmax,self._height,H[:hmax],self._rowpositions) 
2194
6bc71309eb18
Modified version of Henning von Bargen's LongTables optimisation
rgbecker
parents:
2190
diff
changeset

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

598 

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

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

600 
#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

601 

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

602 
#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

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

604 
#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

605 
#this CHANGES the widths array. 
2284  606 
if (None in self._colWidths or '*' in self._colWidths) and self._hasVariWidthElements(): 
2271  607 
W = self._calcPreliminaryWidths(availWidth) #widths 
608 
else: 

609 
W = None 

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

610 

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

611 
# 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

612 
# 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

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

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

615 
self._calcSpanRanges() 
2289  616 
if None in self._argH: 
617 
self._calc_width(availWidth,W=W) 

2190  618 

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

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

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

621 

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

622 
# calculate the full table height 
2271  623 
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

624 

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

625 
# calculate the full table width 
2271  626 
self._calc_width(availWidth,W=W) 
2190  627 

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

631 

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

634 

635 
Usually this is what causes tables to fail to split. Currently 

636 
tables are the only items to have a '_culprit' method. Doctemplate 

637 
checks for it. 

638 
""" 

639 
rh = self._rowHeights 

640 
tallest = max(rh) 

641 
rowNum = rh.index(tallest) 

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

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

644 

645 
return 'tallest cell %0.1f points' % tallest 

646 

647 

648 

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

650 
"""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

651 

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

652 
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

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

654 
if upToRow is None: upToRow = self._nrows 
2812
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

655 
for row in xrange(min(self._nrows, upToRow)): 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

656 
for col in xrange(self._ncols): 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

657 
value = self._cellvalues[row][col] 
1917  658 
if not self._canGetWidth(value): 
2754  659 
return 1 
660 
return 0 

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

661 

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

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

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

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

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

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

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

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

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

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

675 

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

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

677 
"""Fallback algorithm for when main one fails. 
1883  678 

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

679 
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

680 
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

681 
and assign some bestguess values.""" 
2271  682 

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

683 
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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

701 
totalDefined = totalDefined + w 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

702 
if verbose: print 'prelim width calculation. %d columns, %d undefined width, %0.2f units remain' % ( 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

703 
self._ncols, numberUndefined, availWidth  totalDefined) 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

704 

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

705 
#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

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

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

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

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

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

711 
elementWidth = self._elementWidth 
2812
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

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

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

714 
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

715 
siz = 1 
3529  716 
final = 0 
2812
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

717 
for rowNo in xrange(self._nrows): 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

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

719 
style = self._cellStyles[rowNo][colNo] 
3529  720 
pad = style.leftPadding+style.rightPadding 
721 
new = elementWidth(value,style) 

722 
if new: 

723 
new += pad 

724 
else: 

725 
new = pad 

726 
new += style.leftPadding+style.rightPadding 

727 
final = max(final, new) 

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

728 
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

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

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

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

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

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

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

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

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

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

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

739 
if verbose: print 'predefined width: ',given 
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

740 
if verbose: print 'uncomputable width: ',unsizeable 
2467
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

741 
if verbose: print 'computable width: ',sizeable 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

742 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

756 
# 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

757 
# 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

758 
# 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

759 
# 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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

779 
# let's say we have two variable columns. One wanted 
2754  780 
# 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

781 
# minWidth of 66, and the second of 55. We have 71 points 
2754  782 
# 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

783 
# 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

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

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

786 
# 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

787 
# 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

788 
# 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

789 
# 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

790 
# 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

791 
# 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

792 
# 
2754  793 
# Unfortunately, that's too small for the first column. It 
794 
# 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

795 
# 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

796 
# 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

797 
# 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

798 
# 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

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

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

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

804 
# 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

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

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

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

808 
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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

825 
if verbose: print 'new widths are:', W 
5630a2b21a90
tables.py, paragraph.py: Gary Poster's layout improvement patch
rgbecker
parents:
2465
diff
changeset

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

827 
return W 
2190  828 

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

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

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

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

832 
elementWidth = self._elementWidth 
2474  833 
rowNos = xrange(self._nrows) 
834 
values = self._cellvalues 

835 
styles = self._cellStyles 

836 
for colNo in xrange(len(W)): 

837 
w = W[colNo] 

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

838 
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

839 
final = 0 
2474  840 
for rowNo in rowNos: 
841 
value = values[rowNo][colNo] 

842 
style = styles[rowNo][colNo] 

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

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

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

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

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

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

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

849 
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

850 

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

851 
def _calcSpanRanges(self): 
1883  852 
"""Work out rects for tables which do row and column spanning. 
853 

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

854 
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

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

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

859 

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

860 
Any cell not in the key is not part of a spanned region 
1883  861 
""" 
2289  862 
self._spanRanges = spanRanges = {} 
863 
for x in xrange(self._ncols): 

864 
for y in xrange(self._nrows): 

865 
spanRanges[x,y] = (x, y, x, y) 

866 
self._colSpanCells = [] 

867 
self._rowSpanCells = [] 

868 
csa = self._colSpanCells.append 

869 
rsa = self._rowSpanCells.append 

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

872 
x1, y1 = stop 

873 

874 
#normalize 

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

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

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

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

2289  879 
if x0 > x1: x0, x1 = x1, x0 
880 
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

881 

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

883 
if x0!=x1: #column span 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

884 
for y in xrange(y0, y1+1): 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

885 
for x in xrange(x0,x1+1): 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

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

887 
if y0!=y1: #row span 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

888 
for y in xrange(y0, y1+1): 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

889 
for x in xrange(x0,x1+1): 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

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

891 

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

892 
for y in xrange(y0, y1+1): 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

893 
for x in xrange(x0,x1+1): 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

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

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

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

897 

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

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

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

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

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

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

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

905 

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

906 
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

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

908 
self._nosplitRanges = nosplitRanges = {} 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

909 
for x in xrange(self._ncols): 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

910 
for y in xrange(self._nrows): 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

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

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

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

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

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

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

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

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

919 

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

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

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

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

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

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

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

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

927 

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

928 
if x0!=x1 or y0!=y1: 
2289  929 
#column span 
930 
if x0!=x1: 

931 
for y in xrange(y0, y1+1): 

932 
for x in xrange(x0,x1+1): 

933 
csa((x,y)) 

934 
#row span 

935 
if y0!=y1: 

936 
for y in xrange(y0, y1+1): 

937 
for x in xrange(x0,x1+1): 

938 
rsa((x,y)) 

2190  939 

2289  940 
for y in xrange(y0, y1+1): 
941 
for x in xrange(x0,x1+1): 

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

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

944 
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

945 

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

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

947 
"""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

948 

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

949 
Based on self._spanRanges, which is already known, 
2190  950 
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

951 
self._spanRects shows the real coords for drawing: 
3031  952 

953 
(col, row) > (x, y, width, height) 

2190  954 

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

955 
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

956 
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

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

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

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

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

961 
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

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

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

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

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

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

967 
rlim = len(rowpositions)1 
c9a0ccee737d
tables.py: make more robust for LongTable & spans
rgbecker
parents:
3442
diff
changeset

968 
for (coord, value) in self._spanRanges.iteritems(): 
1883  969 
if value is None: 
970 
spanRects[coord] = None 

971 
else: 

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

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

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

975 
if col1col0>0: 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

976 
for _ in xrange(col0+1,col1+1): 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

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

978 
if row1row0>0: 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

979 
for _ in xrange(row0+1,row1+1): 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

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

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

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

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

984 
height = rowpositions[row0]  y 
1883  985 
spanRects[coord] = (x, y, width, height) 
2190  986 

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

987 
for _ in hBlocks, vBlocks: 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

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

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

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

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

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

993 
self._hmax_spanRects = hmax 
2190  994 

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

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

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

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

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

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

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

1001 
setattr(self,k,v) 
2574  1002 
for a in ('spaceBefore','spaceAfter'): 
1003 
if not hasattr(self,a) and hasattr(tblstyle,a): 

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

350  1005 

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

1006 
def _addCommand(self,cmd): 
2393  1007 
if cmd[0] in ('BACKGROUND','ROWBACKGROUNDS','COLBACKGROUNDS'): 
2392  1008 
self._bkgrndcmds.append(cmd) 
1883  1009 
elif cmd[0] == 'SPAN': 
1010 
self._spanCmds.append(cmd) 

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

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

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

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

1014 
elif _isLineCommand(cmd): 
1699  1015 
# 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

1016 
cmd = list(cmd) 
1699  1017 
if len(cmd)<5: raise ValueError('bad line command '+str(cmd)) 
2219
5c1727997169
Multiple lines and decimal alignments now supported
andy_robinson
parents:
2200
diff
changeset

1018 

3203  1019 
#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

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

1021 
cmd.append(1) 
1699  1022 
else: 
2469  1023 
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

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

1025 

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

1026 
#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

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

1028 

3203  1029 
#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

1030 
if len(cmd)<8: cmd.append(1) 
1699  1031 
else: 
2469  1032 
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

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

1034 

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

1035 
#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

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

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

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

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

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

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

1042 
assert lineCount >= 1 
2221  1043 
#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

1044 
#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

1045 
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

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

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

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

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

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

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

1052 

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

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

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

1055 
(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

1056 
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

1057 
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

1058 
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

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

1060 
for i in xrange(sr, er+1): 
3a861a4b4cf5
tables.py: support for NOSPLIT, imroved cell backgrounding
rgbecker
parents:
2754
diff
changeset

1061 
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

1062 
_setCellStyle(self._cellStyles, i, j, op, values) 
326  1063 

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

1064 
def _drawLines(self): 
1699  1065 
ccap, cdash, cjoin = None, None, None 
1066 
self.canv.saveState() 

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

1067 
for op, (sc,sr), (ec,er), weight, color, cap, dash, join, count, space in self._linecmds: 
3180
349e9644fce8
reportlab: attempt to remove type() checking in favour of isinstance
rgbecker
parents:
3177
diff
changeset

1068 
if isinstance(sr,basestring) and sr.startswith('split'): continue 
1677
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 
2414
81be267fa92c
tables.py: extend span line blocking to multi lines
rgbecker
parents:
2412
diff
changeset

1073 
if cap!=None and ccap!=cap: 
1699  1074 
self.canv.setLineCap(cap) 
1075 
ccap = cap 

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

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

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

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

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

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

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

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

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

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

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

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

1088 
self._curcolor = None 
248  1089 

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

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

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

403  1095 

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

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

403  1099 

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

1102 
ec,er = end 

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

1103 
self._drawHLines((sc, sr), (ec, sr), weight, color, count, space) 
5c1727997169
Multiple lines and decimal alignments now supported
andy_robinson
parents:
2200
diff
changeset

1104 
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

1105 
self._drawVLines((sc, sr), (sc, er), weight, color, count, space) 
5c1727997169
Multiple lines and decimal alignments now supported
andy_robinson
parents:
2200
diff
changeset

1106 
self._drawVLines((ec+1, sr), (ec+1, er), weight, color, count, space) 
350  1107 

3326  1108 
def _drawInnerGrid(self, start, end, weight, color, count, space): 
1109 
sc,sr = start 

1110 
ec,er = end 

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

1111 
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

1112 
self._drawVLines((sc+1, sr), (ec, er), weight, color, count, space) 
350  1113 

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

1114 
def _prepLine(self, weight, color): 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1115 
if color != self._curcolor: 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1116 
self.canv.setStrokeColor(color) 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

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

1118 
if weight != self._curweight: 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1119 
self.canv.setLineWidth(weight) 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1120 
self._curweight = weight 
350  1121 

3326  1122 
def _drawHLines(self, start, end, weight, color, count, space): 
1123 
sc,sr = start 

1124 
ec,er = end 

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

1125 
ecp = self._colpositions[sc:ec+2] 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1126 
rp = self._rowpositions[sr:er+1] 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1127 
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

1128 
self._prepLine(weight, color) 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1129 
scp = ecp[0] 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1130 
ecp = ecp[1] 
2412
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

1131 
hBlocks = getattr(self,'_hBlocks',{}) 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

1132 
canvLine = self.canv.line 
2220  1133 
if count == 1: 
2412
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

1134 
for y in rp: 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

1135 
_hLine(canvLine, scp, ecp, y, hBlocks) 
2220  1136 
else: 
2414
81be267fa92c
tables.py: extend span line blocking to multi lines
rgbecker
parents:
2412
diff
changeset

1137 
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

1138 
for y in rp: 
2414
81be267fa92c
tables.py: extend span line blocking to multi lines
rgbecker
parents:
2412
diff
changeset

1139 
_hLine(lf, scp, ecp, y, hBlocks) 
403  1140 

3326  1141 
def _drawHLinesB(self, start, end, weight, color, count, space): 
1142 
sc,sr = start 

1143 
ec,er = end 

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

1144 
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

1145 

3326  1146 
def _drawVLines(self, start, end, weight, color, count, space): 
1147 
sc,sr = start 

1148 
ec,er = end 

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

1149 
erp = self._rowpositions[sr:er+2] 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1150 
cp = self._colpositions[sc:ec+1] 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1151 
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

1152 
self._prepLine(weight, color) 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1153 
srp = erp[0] 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1154 
erp = erp[1] 
2412
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

1155 
vBlocks = getattr(self,'_vBlocks',{}) 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

1156 
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

1157 
if count == 1: 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

1158 
for x in cp: 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

1159 
_hLine(canvLine, erp, srp, x, vBlocks) 
b8bf2e639769
reportlab: table improvments and better documentation
rgbecker
parents:
2401
diff
changeset

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

1161 
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

1162 
for x in cp: 
2414
81be267fa92c
tables.py: extend span line blocking to multi lines
rgbecker
parents:
2412
diff
changeset

1163 
_hLine(lf, erp, srp, x, vBlocks) 
326  1164 

3326  1165 
def _drawVLinesA(self, start, end, weight, color, count, space): 
1166 
sc,sr = start 

1167 
ec,er = end 

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

1168 
self._drawVLines((sc+1, sr), (ec+1, er), weight, color, count, space) 
403  1169 

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

1170 
def wrap(self, availWidth, availHeight): 
1912
c8509682e3e0
Finished off sizing logic to go with row and column
andy_robinson
parents:
1883
diff
changeset

1171 
self._calc(availWidth, availHeight) 
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

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

1173 
return (self._width, self._height) 
1495  1174 

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

1175 
def onSplit(self,T,byRow=1): 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

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

1177 
This method will be called when the Table is split. 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1178 
Special purpose tables can override to do special stuff. 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

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

1180 
pass 
419  1181 

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

1182 
def _cr_0(self,n,cmds): 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1183 
for c in cmds: 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1184 
c = tuple(c) 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

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

1186 
if sr>=n: continue 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1187 
if er>=n: er = n1 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1188 
self._addCommand((c[0],)+((sc, sr), (ec, er))+c[3:]) 
350  1189 

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

1190 
def _cr_1_1(self,n,repeatRows, cmds): 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1191 
for c in cmds: 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1192 
c = tuple(c) 
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1658
diff
changeset

1193 
(sc,sr), (ec,er) = c[1:3] 
2185  1194 
if sr in ('splitfirst','splitlast'): self._addCommand(c) 
1195 
else: 

1196 
if sr>=0 and sr>=repeatRows and sr<n and er>=0 and er<n: continue 