Added tables to PythonPoint
authorandy_robinson
Mon, 10 Jul 2000 15:25:47 +0000
changeset 342 a6982189331d
parent 341 27c68d524504
child 343 fd432c274222
Added tables to PythonPoint
reportlab/demos/pythonpoint/pythonpoint.py
reportlab/demos/pythonpoint/pythonpoint.xml
reportlab/demos/pythonpoint/stdparser.py
reportlab/platypus/tables.py
--- a/reportlab/demos/pythonpoint/pythonpoint.py	Mon Jul 10 14:20:15 2000 +0000
+++ b/reportlab/demos/pythonpoint/pythonpoint.py	Mon Jul 10 15:25:47 2000 +0000
@@ -31,9 +31,12 @@
 #
 ###############################################################################
 #	$Log: pythonpoint.py,v $
+#	Revision 1.22  2000/07/10 15:25:47  andy_robinson
+#	Added tables to PythonPoint
+#
 #	Revision 1.21  2000/06/01 15:23:06  rgbecker
 #	Platypus re-organisation
-#
+#	
 #	Revision 1.20  2000/05/23 14:06:45  andy_robinson
 #	Preformatted objects now know how to split themselves.
 #	
@@ -99,7 +102,7 @@
 #	Revision 1.1.1.1  2000/02/15 15:08:55  rgbecker
 #	Initial setup of demos directory and contents.
 #	
-__version__=''' $Id: pythonpoint.py,v 1.21 2000/06/01 15:23:06 rgbecker Exp $ '''
+__version__=''' $Id: pythonpoint.py,v 1.22 2000/07/10 15:25:47 andy_robinson Exp $ '''
 # xml parser stuff for PythonPoint
 # PythonPoint Markup Language!
 __doc__="""
@@ -131,6 +134,8 @@
         PPPara - flowing text
         PPPreformatted - text with line breaks and tabs, for code..
         PPImage
+        PPTable - bulk formatted tabular data
+        PPSpacer
 
     Things to draw directly on the page...
         PPRect
@@ -147,11 +152,13 @@
 import imp
 
 from reportlab.pdfgen import canvas
-from reportlab.platypus import Preformatted, Paragraph, Frame, Image
+from reportlab.platypus import Preformatted, Paragraph, Frame, Image, \
+     Table, TableStyle, Spacer
 from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY
 from reportlab.lib import styles
 import stdparser 
 from reportlab.lib.pagesizes import DEFAULT_PAGE_SIZE
+from reportlab.lib import colors
 
 class PPPresentation:
     def __init__(self):
@@ -295,7 +302,61 @@
     def getFlowable(self):
         return Image(self.filename, self.width, self.height)
 
+class PPTable:
+    """Designed for bulk loading of data for use in presentations."""
+    def __init__(self):
+        self.rawBlocks = [] #parser stuffs things in here...
+        self.fieldDelim = ','  #tag args can override
+        self.rowDelim = '\n'   #tag args can override
+        self.data = None
+        self.style = None  #tag args must specify
+        self.widths = None  #tag args can override
+        self.heights = None #tag args can override
 
+    def getFlowable(self):
+        self.parseData()
+        t = Table(
+                self.widths,
+                self.heights,
+                self.data)
+        if self.style:
+            t.setStyle(getStyles()[self.style])
+
+        return t
+                
+    def parseData(self):
+        """Try to make sense of the table data!"""
+        rawdata = string.strip(string.join(self.rawBlocks, ''))
+        lines = string.split(rawdata, self.rowDelim)
+        #clean up...
+        lines = map(string.strip, lines)
+        self.data = []
+        for line in lines:
+            cells = string.split(line, self.fieldDelim)
+            self.data.append(cells)
+
+        #get the width list if not given
+        if not self.widths:
+            self.widths = [None] * len(self.data[0])
+        if not self.heights:
+            self.heights = [None] * len(self.data)
+        
+    
+##        import pprint
+##        print 'table data:'
+##        print 'style=',self.style
+##        print 'widths=',self.widths
+##        print 'heights=',self.heights
+##        print 'fieldDelim=',repr(self.fieldDelim)
+##        print 'rowDelim=',repr(self.rowDelim)
+##        pprint.pprint(self.data)
+
+class PPSpacer:
+    def __init__(self):
+        self.height = 24  #points
+
+    def getFlowable(self):
+        return Spacer(72, self.height)
 
     #############################################################
     #
@@ -496,7 +557,9 @@
 
 def getSampleStyleSheet():
     """Returns a dictionary of styles to get you started.  We will
-    provide a way to specify a module of these."""
+    provide a way to specify a module of these.  Note that this
+    ust includes TableStyles as well as ParagraphStyles for any
+    tables you wish to use."""
     stylesheet = {}
     ParagraphStyle = styles.ParagraphStyle
     
@@ -581,6 +644,19 @@
     para.leftIndent = 36
     stylesheet['Code'] = para
 
+    #now for a table
+    ts = TableStyle([
+         ('FONT', (0,0), (-1,-1), 'Times-Roman', 24),
+         ('LINEABOVE', (0,0), (-1,0), 2, colors.green),
+         ('LINEABOVE', (0,1), (-1,-1), 0.25, colors.black),
+         ('LINEBELOW', (0,-1), (-1,-1), 2, colors.green),
+         ('LINEBEFORE', (-1,0), (-1,-1), 2, colors.black),
+         ('ALIGN', (1,1), (-1,-1), 'RIGHT'),   #all numeric cells right aligned
+         ('TEXTCOLOR', (0,1), (0,-1), colors.red),
+         ('BACKGROUND', (0,0), (-1,0), colors.Color(0,0.7,0.7))
+         ])
+    stylesheet['table1'] = ts
+
     return stylesheet
 
 #make a singleton and a function to access it        
--- a/reportlab/demos/pythonpoint/pythonpoint.xml	Mon Jul 10 14:20:15 2000 +0000
+++ b/reportlab/demos/pythonpoint/pythonpoint.xml	Mon Jul 10 15:25:47 2000 +0000
@@ -183,6 +183,26 @@
         <customshape module="customshapes" class="Jigsaw" initargs="(700,200,1)"/>
     </slide>
 
+	<slide id="Slide008a" title="Tables" effectname='Glitter' outlinelevel='1'>
+        <frame x="120" y="72" width="700" height="468" 
+			leftmargin="36" rightmargin="36">
+            <para style='Heading1'>Tables</para>
+            <para>The Table tag lets you paste in bulk data and format it attractively:</para>
+			<spacer height="24"/>
+			<table widths="(144,72,72,72,108)" 
+				   heights="(28,28,28,28,28)"
+				   style="table1"
+				   >
+				Division,Jan,Feb,Mar,Q1 Total
+				North,100,115,120,335
+				South,215,145,180,540
+				East,75,90,135,300
+				West,100,120,115,335
+			</table>
+        </frame>
+
+    </slide>
+
 	<slide id="Slide009" title="Future Features" effectname='Glitter' outlinelevel='1'>
         <frame x="120" y="72" width="700" height="468" 
 			leftmargin="36" rightmargin="36">
--- a/reportlab/demos/pythonpoint/stdparser.py	Mon Jul 10 14:20:15 2000 +0000
+++ b/reportlab/demos/pythonpoint/stdparser.py	Mon Jul 10 15:25:47 2000 +0000
@@ -31,9 +31,12 @@
 #
 ###############################################################################
 #	$Log: stdparser.py,v $
+#	Revision 1.9  2000/07/10 15:25:47  andy_robinson
+#	Added tables to PythonPoint
+#
 #	Revision 1.8  2000/06/01 15:23:06  rgbecker
 #	Platypus re-organisation
-#
+#	
 #	Revision 1.7  2000/05/16 23:52:38  andy_robinson
 #	Bug in Image tag
 #	
@@ -118,6 +121,13 @@
             'width':'None',
             'height':'None'
             },
+        'table': {
+            'widths':'None',
+            'heights':'None',
+            'fieldDelim':',',
+            'rowDelim':'\n',
+            'style':'None'
+            },
         'rectangle': {
             'x':'0',
             'y':'0',
@@ -184,6 +194,9 @@
     
     def __init__(self):
         self.presentations = []
+        #yes, I know a generic stack would be easier...
+        #still, testing if we are 'in' something gives
+        #a degree of validation.
         self._curPres = None
         self._curSection = None
         self._curSlide = None
@@ -191,6 +204,7 @@
         self._curPara = None  #the only places we are interested in
         self._curPrefmt = None
         self._curString = None
+        self._curTable = None
         xmllib.XMLParser.__init__(self)
 
     def _arg(self,tag,args,name):
@@ -218,7 +232,8 @@
         
     def handle_data(self, data):
         #the only data should be paragraph text, preformatted para
-        #text, or 'string text' for a fixed string on the page
+        #text, 'string text' for a fixed string on the page,
+        #or table data
         
         if self._curPara:
             self._curPara.rawtext = self._curPara.rawtext + data
@@ -226,6 +241,8 @@
             self._curPrefmt.rawtext = self._curPrefmt.rawtext + data
         elif  self._curString:
             self._curString.text = self._curString.text + data
+        elif self._curTable:
+            self._curTable.rawBlocks.append(data)
             
     def handle_cdata(self, data):
         #just append to current paragraph text, so we can quote XML
@@ -346,6 +363,31 @@
         self._curFrame.content.append(self._curImage)
         self._curImage = None
 
+    def start_table(self, args):
+        self._curTable = pythonpoint.PPTable()
+        self._curTable.widths = self.ceval('table',args,'widths')
+        self._curTable.heights = self.ceval('table',args,'heights')
+        #these may contain escapes like tabs - handle with
+        #a bit more care.
+        if args.has_key('fieldDelim'):
+            self._curTable.fieldDelim = eval('"' + args['fieldDelim'] + '"')
+        if args.has_key('rowDelim'):
+            self._curTable.rowDelim = eval('"' + args['rowDelim'] + '"')
+        if args.has_key('style'):
+            self._curTable.style = args['style']
+        
+        
+        
+    def end_table(self):
+        self._curFrame.content.append(self._curTable)
+        self._curTable = None
+
+    def start_spacer(self, args):
+        """No contents so deal with it here."""
+        sp = pythonpoint.PPSpacer()
+        sp.height = eval(args['height'])
+        self._curFrame.content.append(sp)
+        
 
     ## the graphics objects - go into either the current section
     ## or the current slide.
--- a/reportlab/platypus/tables.py	Mon Jul 10 14:20:15 2000 +0000
+++ b/reportlab/platypus/tables.py	Mon Jul 10 15:25:47 2000 +0000
@@ -31,9 +31,12 @@
 #
 ###############################################################################
 #	$Log: tables.py,v $
+#	Revision 1.19  2000/07/10 15:25:47  andy_robinson
+#	Added tables to PythonPoint
+#
 #	Revision 1.18  2000/07/08 15:30:04  rgbecker
 #	Cosmetics and error testing
-#
+#	
 #	Revision 1.17  2000/07/07 16:22:10  rgbecker
 #	Fix auto hieght stuff
 #	
@@ -83,7 +86,7 @@
 #	Revision 1.2  2000/02/15 15:47:09  rgbecker
 #	Added license, __version__ and Logi comment
 #	
-__version__=''' $Id: tables.py,v 1.18 2000/07/08 15:30:04 rgbecker Exp $ '''
+__version__=''' $Id: tables.py,v 1.19 2000/07/10 15:25:47 andy_robinson Exp $ '''
 __doc__="""
 Tables are created by passing the constructor a tuple of column widths, a tuple of row heights and the data in
 row order. Drawing of the table can be controlled by using a TableStyle instance. This allows control of the
@@ -135,7 +138,7 @@
 TableStyleType = type(TableStyle())
 		
 class Table(Flowable):
-	def __init__(self, colWidths, rowHeights, data):
+	def __init__(self, colWidths, rowHeights, data, style=None):
 		if not colWidths:
 			raise ValueError, "Table must have at least 1 column"
 		if not rowHeights:
@@ -158,6 +161,9 @@
 		self._linecmds = []
 		self._curweight = self._curcolor = self._curcellstyle = None
 
+		if style:
+			self.setStyle(style)
+
 	def _calc(self):
 		if hasattr(self,'_argH'):
 			self._rowHeights = self._argH