1 #copyright ReportLab Inc. 2000 |
1 #copyright ReportLab Inc. 2000 |
2 #see license.txt for license details |
2 #see license.txt for license details |
3 #history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/reportlab/platypus/tables.py?cvsroot=reportlab |
3 #history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/reportlab/platypus/tables.py?cvsroot=reportlab |
4 #$Header: /tmp/reportlab/reportlab/platypus/tables.py,v 1.49 2002/01/17 14:21:29 rgbecker Exp $ |
4 #$Header: /tmp/reportlab/reportlab/platypus/tables.py,v 1.50 2002/01/18 12:21:13 rgbecker Exp $ |
5 __version__=''' $Id: tables.py,v 1.49 2002/01/17 14:21:29 rgbecker Exp $ ''' |
5 __version__=''' $Id: tables.py,v 1.50 2002/01/18 12:21:13 rgbecker Exp $ ''' |
6 __doc__=""" |
6 __doc__=""" |
7 Tables are created by passing the constructor a tuple of column widths, a tuple of row heights and the data in |
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 |
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. |
9 color and weight of the lines (if any), and the font, alignment and padding of the text. |
10 |
10 |
99 _SeqTypes = (TupleType, ListType) |
99 _SeqTypes = (TupleType, ListType) |
100 |
100 |
101 def _rowLen(x): |
101 def _rowLen(x): |
102 return type(x) not in _SeqTypes and 1 or len(x) |
102 return type(x) not in _SeqTypes and 1 or len(x) |
103 |
103 |
104 def _listCellGeom(V,w,s,W=None,H=None): |
|
105 aW = w-s.leftPadding-s.rightPadding |
|
106 t = 0 |
|
107 w = 0 |
|
108 for v in V: |
|
109 vw, vh = v.wrap(aW, 72000) |
|
110 if W is not None: W.append(vw) |
|
111 if H is not None: H.append(vh) |
|
112 w = max(w,vw) |
|
113 t = t + vh + v.getSpaceBefore()+v.getSpaceAfter() |
|
114 return w, t - V[0].getSpaceBefore()-V[-1].getSpaceAfter() |
|
115 |
104 |
116 class Table(Flowable): |
105 class Table(Flowable): |
117 def __init__(self, data, colWidths=None, rowHeights=None, style=None, |
106 def __init__(self, data, colWidths=None, rowHeights=None, style=None, |
118 repeatRows=0, repeatCols=0, splitByRow=1): |
107 repeatRows=0, repeatCols=0, splitByRow=1): |
119 #print "colWidths", colWidths |
108 #print "colWidths", colWidths |
205 else: |
194 else: |
206 vx = '...' |
195 vx = '...' |
207 |
196 |
208 return "<%s at %d %d rows x %s cols>%s" % (self.__class__.__name__, id(self), nr, nc, vx) |
197 return "<%s at %d %d rows x %s cols>%s" % (self.__class__.__name__, id(self), nr, nc, vx) |
209 |
198 |
|
199 def _listCellGeom(self, V,w,s,W=None,H=None): |
|
200 aW = w-s.leftPadding-s.rightPadding |
|
201 t = 0 |
|
202 w = 0 |
|
203 canv = self.canv |
|
204 for v in V: |
|
205 vw, vh = v.wrapOn(canv,aW, 72000) |
|
206 if W is not None: W.append(vw) |
|
207 if H is not None: H.append(vh) |
|
208 w = max(w,vw) |
|
209 t = t + vh + v.getSpaceBefore()+v.getSpaceAfter() |
|
210 return w, t - V[0].getSpaceBefore()-V[-1].getSpaceAfter() |
|
211 |
210 def _calc(self): |
212 def _calc(self): |
211 if hasattr(self,'_width'): return |
213 if hasattr(self,'_width'): return |
212 |
214 |
213 H = self._argH |
215 H = self._argH |
214 W = self._argW |
216 W = self._argW |
229 t = type(v) |
231 t = type(v) |
230 if t in _SeqTypes or isinstance(v,Flowable): |
232 if t in _SeqTypes or isinstance(v,Flowable): |
231 if not t in _SeqTypes: v = (v,) |
233 if not t in _SeqTypes: v = (v,) |
232 if w is None: |
234 if w is None: |
233 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)) |
235 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)) |
234 dW,t = _listCellGeom(v,w,s) |
236 dW,t = self._listCellGeom(v,w,s) |
235 #print "leftpadding, rightpadding", s.leftPadding, s.rightPadding |
237 #print "leftpadding, rightpadding", s.leftPadding, s.rightPadding |
236 dW = dW + s.leftPadding + s.rightPadding |
238 dW = dW + s.leftPadding + s.rightPadding |
237 if not rl_config.allowTableBoundsErrors and dW>w: |
239 if not rl_config.allowTableBoundsErrors and dW>w: |
238 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)) |
240 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)) |
239 else: |
241 else: |
541 if n in _SeqTypes or isinstance(cellval,Flowable): |
543 if n in _SeqTypes or isinstance(cellval,Flowable): |
542 if not n in _SeqTypes: cellval = (cellval,) |
544 if not n in _SeqTypes: cellval = (cellval,) |
543 # we assume it's a list of Flowables |
545 # we assume it's a list of Flowables |
544 W = [] |
546 W = [] |
545 H = [] |
547 H = [] |
546 w, h = _listCellGeom(cellval,colwidth,cellstyle,W=W, H=H) |
548 w, h = self._listCellGeom(cellval,colwidth,cellstyle,W=W, H=H) |
547 if valign=='TOP': |
549 if valign=='TOP': |
548 y = rowpos + rowheight - cellstyle.topPadding |
550 y = rowpos + rowheight - cellstyle.topPadding |
549 elif valign=='BOTTOM': |
551 elif valign=='BOTTOM': |
550 y = rowpos+cellstyle.bottomPadding + h |
552 y = rowpos+cellstyle.bottomPadding + h |
551 else: |
553 else: |