reportlab/platypus/tables.py
changeset 1596 753865895a6f
parent 1536 e9ae8b060e03
child 1655 917b842757ca
equal deleted inserted replaced
1595:0e0e88f78818 1596:753865895a6f
     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.56 2002/03/18 14:00:45 rgbecker Exp $
     4 #$Header: /tmp/reportlab/reportlab/platypus/tables.py,v 1.57 2002/04/25 19:52:40 andy_robinson Exp $
     5 __version__=''' $Id: tables.py,v 1.56 2002/03/18 14:00:45 rgbecker Exp $ '''
     5 __version__=''' $Id: tables.py,v 1.57 2002/04/25 19:52:40 andy_robinson 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 
   225 			if H is not None: H.append(vh)
   225 			if H is not None: H.append(vh)
   226 			w = max(w,vw)
   226 			w = max(w,vw)
   227 			t = t + vh + v.getSpaceBefore()+v.getSpaceAfter()
   227 			t = t + vh + v.getSpaceBefore()+v.getSpaceAfter()
   228 		return w, t - V[0].getSpaceBefore()-V[-1].getSpaceAfter() 
   228 		return w, t - V[0].getSpaceBefore()-V[-1].getSpaceAfter() 
   229 
   229 
   230 	def _calc(self):
   230 	def _calc_width(self):
   231 		if hasattr(self,'_width'): return
   231 
       
   232 		W = self._argW
       
   233 
       
   234 		canv = getattr(self,'canv',None)
       
   235 		saved = None
       
   236 
       
   237 		if None in W:
       
   238 			W = W[:]
       
   239 			self._colWidths = W
       
   240 			while None in W:
       
   241 				j = W.index(None)
       
   242 				f = lambda x,j=j: operator.getitem(x,j)
       
   243 				V = map(f,self._cellvalues)
       
   244 				S = map(f,self._cellStyles)
       
   245 				w = 0
       
   246 				i = 0
       
   247 				for v, s in map(None, V, S):
       
   248 					i = i + 1
       
   249 					t = type(v)
       
   250 					if t in _SeqTypes or isinstance(v,Flowable):
       
   251 						raise ValueError, "Flowable %s in cell(%d,%d) can't have auto width\n%s" % (v.identity(30),i,j,self.identity(30))
       
   252 					elif t is not StringType: v = v is None and '' or str(v)
       
   253 					v = string.split(v, "\n")
       
   254 					t = s.leftPadding+s.rightPadding + max(map(lambda a, b=s.fontname,
       
   255 								c=s.fontsize,d=pdfmetrics.stringWidth: d(a,b,c), v))
       
   256 					if t>w: w = t	#record a new maximum
       
   257 				W[j] = w
       
   258 
       
   259 		width = 0
       
   260 		self._colpositions = [0]		#index -1 is right side boundary; we skip when processing cells
       
   261 		for w in W:
       
   262 			#print w, width
       
   263 			width = width + w
       
   264 			self._colpositions.append(width)
       
   265 		#print "final width", width
       
   266 		
       
   267 		self._width = width
       
   268 
       
   269 	def _calc_height(self):
   232 
   270 
   233 		H = self._argH
   271 		H = self._argH
   234 		W = self._argW
   272 		W = self._argW
   235 		#print "W is", W
       
   236 
   273 
   237 		canv = getattr(self,'canv',None)
   274 		canv = getattr(self,'canv',None)
   238 		saved = None
   275 		saved = None
       
   276 
   239 		if None in H:
   277 		if None in H:
   240 			if canv: saved = canv._fontname, canv._fontsize, canv._leading
   278 			if canv: saved = canv._fontname, canv._fontsize, canv._leading
   241 			H = H[:]	#make a copy as we'll change it
   279 			H = H[:]	#make a copy as we'll change it
   242 			self._rowHeights = H
   280 			self._rowHeights = H
   243 			while None in H:
   281 			while None in H:
   267 						t = s.leading*len(v)
   305 						t = s.leading*len(v)
   268 					t = t+s.bottomPadding+s.topPadding
   306 					t = t+s.bottomPadding+s.topPadding
   269 					if t>h: h = t	#record a new maximum
   307 					if t>h: h = t	#record a new maximum
   270 				H[i] = h
   308 				H[i] = h
   271 
   309 
   272 		if None in W:
       
   273 			W = W[:]
       
   274 			self._colWidths = W
       
   275 			while None in W:
       
   276 				j = W.index(None)
       
   277 				f = lambda x,j=j: operator.getitem(x,j)
       
   278 				V = map(f,self._cellvalues)
       
   279 				S = map(f,self._cellStyles)
       
   280 				w = 0
       
   281 				i = 0
       
   282 				for v, s in map(None, V, S):
       
   283 					i = i + 1
       
   284 					t = type(v)
       
   285 					if t in _SeqTypes or isinstance(v,Flowable):
       
   286 						raise ValueError, "Flowable %s in cell(%d,%d) can't have auto width\n%s" % (v.identity(30),i,j,self.identity(30))
       
   287 					elif t is not StringType: v = v is None and '' or str(v)
       
   288 					v = string.split(v, "\n")
       
   289 					t = s.leftPadding+s.rightPadding + max(map(lambda a, b=s.fontname,
       
   290 								c=s.fontsize,d=pdfmetrics.stringWidth: d(a,b,c), v))
       
   291 					if t>w: w = t	#record a new maximum
       
   292 				W[j] = w
       
   293 
       
   294 		height = self._height = reduce(operator.add, H, 0)
   310 		height = self._height = reduce(operator.add, H, 0)
   295 		#print "height, H", height, H
   311 		#print "height, H", height, H
   296 		self._rowpositions = [height]	 # index 0 is actually topline; we skip when processing cells
   312 		self._rowpositions = [height]	 # index 0 is actually topline; we skip when processing cells
   297 		for h in H:
   313 		for h in H:
   298 			height = height - h
   314 			height = height - h
   299 			self._rowpositions.append(height)
   315 			self._rowpositions.append(height)
   300 		assert abs(height)<1e-8, 'Internal height error'
   316 		assert abs(height)<1e-8, 'Internal height error'
   301 		width = 0
   317 
   302 		self._colpositions = [0]		#index -1 is right side boundary; we skip when processing cells
   318 	def _calc(self):
   303 		for w in W:
   319 		if hasattr(self,'_width'): return
   304 			#print w, width
   320 
   305 			width = width + w
   321 		# calculate the full table height
   306 			self._colpositions.append(width)
   322 		self._calc_height()
   307 		#print "final width", width
   323 
   308 		
   324 		# if the width has already been calculated, don't calculate again
   309 		self._width = width
   325 		# there's surely a better, more pythonic way to short circuit this FIXME FIXME
       
   326 		if hasattr(self,'_width_calculated_once'): return
       
   327 		self._width_calculated_once = 1
       
   328 
       
   329 		# calculate the full table width
       
   330 		self._calc_width()
   310 
   331 
   311 	def setStyle(self, tblstyle):
   332 	def setStyle(self, tblstyle):
   312 		if type(tblstyle) is not TableStyleType:
   333 		if type(tblstyle) is not TableStyleType:
   313 			tblstyle = TableStyle(tblstyle)
   334 			tblstyle = TableStyle(tblstyle)
   314 		for cmd in tblstyle.getCommands():
   335 		for cmd in tblstyle.getCommands():
   454 		repeatCols = self.repeatCols
   475 		repeatCols = self.repeatCols
   455 		splitByRow = self.splitByRow
   476 		splitByRow = self.splitByRow
   456 		data = self._cellvalues
   477 		data = self._cellvalues
   457 
   478 
   458 		#we're going to split into two superRows
   479 		#we're going to split into two superRows
   459 		R0 = Table( data[:n], self._argW, self._argH[:n],
   480 		#R0 = Table( data[:n], self._argW, self._argH[:n],
       
   481 		R0 = Table( data[:n], self._colWidths, self._argH[:n],
   460 				repeatRows=repeatRows, repeatCols=repeatCols,
   482 				repeatRows=repeatRows, repeatCols=repeatCols,
   461 				splitByRow=splitByRow)
   483 				splitByRow=splitByRow)
   462 
   484 
   463 		#copy the styles and commands
   485 		#copy the styles and commands
   464 		R0._cellStyles = self._cellStyles[:n]
   486 		R0._cellStyles = self._cellStyles[:n]
   502 
   524 
   503 		R0._cr_0(n,A)
   525 		R0._cr_0(n,A)
   504 		R0._cr_0(n,self._bkgrndcmds)
   526 		R0._cr_0(n,self._bkgrndcmds)
   505 
   527 
   506 		if repeatRows:
   528 		if repeatRows:
   507 			R1 = Table(data[:repeatRows]+data[n:],
   529 			#R1 = Table(data[:repeatRows]+data[n:],self._argW, 
   508 					self._argW, self._argH[:repeatRows]+self._argH[n:],
   530 			R1 = Table(data[:repeatRows]+data[n:],self._colWidths, 
       
   531 					self._argH[:repeatRows]+self._argH[n:],
   509 					repeatRows=repeatRows, repeatCols=repeatCols,
   532 					repeatRows=repeatRows, repeatCols=repeatCols,
   510 					splitByRow=splitByRow)
   533 					splitByRow=splitByRow)
   511 			R1._cellStyles = self._cellStyles[:repeatRows]+self._cellStyles[n:]
   534 			R1._cellStyles = self._cellStyles[:repeatRows]+self._cellStyles[n:]
   512 			R1._cr_1_1(n,repeatRows,A)
   535 			R1._cr_1_1(n,repeatRows,A)
   513 			R1._cr_1_1(n,repeatRows,self._bkgrndcmds)
   536 			R1._cr_1_1(n,repeatRows,self._bkgrndcmds)
   514 		else:
   537 		else:
   515 			R1 = Table(data[n:], self._argW, self._argH[n:],
   538 			#R1 = Table(data[n:], self._argW, self._argH[n:],
       
   539 			R1 = Table(data[n:], self._colWidths, self._argH[n:],
   516 					repeatRows=repeatRows, repeatCols=repeatCols,
   540 					repeatRows=repeatRows, repeatCols=repeatCols,
   517 					splitByRow=splitByRow)
   541 					splitByRow=splitByRow)
   518 			R1._cellStyles = self._cellStyles[n:]
   542 			R1._cellStyles = self._cellStyles[n:]
   519 			R1._cr_1_0(n,A)
   543 			R1._cr_1_0(n,A)
   520 			R1._cr_1_0(n,self._bkgrndcmds)
   544 			R1._cr_1_0(n,self._bkgrndcmds)