tables.py: added span rows split handling & test contributed by Andre Reitz
authorrgbecker
Fri, 14 Jan 2005 16:06:57 +0000
changeset 2443 41262322cc3d
parent 2442 440a41488100
child 2444 5d4dd15fd528
tables.py: added span rows split handling & test contributed by Andre Reitz
reportlab/platypus/tables.py
reportlab/test/test_platypus_tables.py
--- a/reportlab/platypus/tables.py	Fri Jan 14 15:42:12 2005 +0000
+++ b/reportlab/platypus/tables.py	Fri Jan 14 16:06:57 2005 +0000
@@ -834,18 +834,9 @@
                 self._addCommand((c[0],)+((sc, sr), (ec, er))+c[3:])
 
     def _splitRows(self,availHeight):
-        h = 0
-        n = 0
+        n=self._getFirstPossibleSplitRowPosition(availHeight)
+        if n<=self.repeatRows: return []
         lim = len(self._rowHeights)
-        while n<self._hmax:
-            hn = h + self._rowHeights[n]
-            if hn>availHeight: break
-            h = hn
-            n = n + 1
-
-        if n<=self.repeatRows:
-            return []
-
         if n==lim: return [self]
 
         repeatRows = self.repeatRows
@@ -931,10 +922,53 @@
 
         R0.hAlign = R1.hAlign = self.hAlign
         R0.vAlign = R1.vAlign = self.vAlign
+        if self._spanCmds: R0._spanCmds, R1._spanCmds=self._cloneSpanCommands(n)
         self.onSplit(R0)
         self.onSplit(R1)
         return [R0,R1]
 
+    def _getFirstPossibleSplitRowPosition(self,availHeight):
+        if self._spanCmds:
+            impossible={}
+            for xy in self._rowSpanCells:
+                r=self._spanRanges[xy]
+                if r!=None:
+                    y1,y2=r[1],r[3]
+                    if y1!=y2:
+                        ymin=min(y1,y2) #normalize
+                        ymax=max(y1,y2) #normalize
+                        y=ymin+1
+                        while 1:
+                            if y>ymax: break
+                            impossible[y]=None #split at position y is impossible because of overlapping rowspan
+                            y=y+1
+        else:
+            impossible={} # any split possible because table does *not* have rowspans
+        h = 0
+        n = 1
+        split_at = 0 # from this point of view 0 is the first position where the table may *always* be splitted
+        for rh in self._rowHeights:
+            if h+rh>availHeight:
+                break
+            if not impossible.has_key(n):
+                split_at=n
+            h=h+rh
+            n=n+1
+        return split_at
+
+    def _cloneSpanCommands(self,n):
+        spans0=[]
+        spans1=[]
+        for rng in self._spanRanges.values():
+            if rng:
+                if rng[0:2]!=rng[2:4]:
+                    x1,y1,x2,y2=rng
+                    assert (x1<=x2) and (y1<=y2), "_spanRanges does contain unexpected values!"
+                    assert not (y1<n and y2>=n) , "Something got wrong with _getFirstPossibleSplitRowPosition! %r" % [ys,ye,n]
+                    if y1< n and y2< n: spans0.append(("SPAN",(x1,y1  ),(x2,y2  )))
+                    if y1>=n and y2>=n: spans1.append(("SPAN",(x1,y1-n),(x2,y2-n)))
+        return spans0,spans1
+
     def split(self, availWidth, availHeight):
         self._calc(availWidth, availHeight)
         if self.splitByRow:
--- a/reportlab/test/test_platypus_tables.py	Fri Jan 14 15:42:12 2005 +0000
+++ b/reportlab/test/test_platypus_tables.py	Fri Jan 14 16:06:57 2005 +0000
@@ -409,21 +409,60 @@
                     ('BACKGROUND', (1, 1), (1, 2), colors.lavender),
                     ('BACKGROUND', (2, 2), (2, 3), colors.orange),
                     ])
+    lst.append(Paragraph("Illustrating splits: nosplit", styleSheet['BodyText']))
     lst.append(t)
     lst.append(Spacer(0,6))
+    lst.append(Paragraph("Illustrating splits: split(4in,30)", styleSheet['BodyText']))
     for s in t.split(4*inch,30):
         lst.append(s)
         lst.append(Spacer(0,6))
     lst.append(Spacer(0,6))
+    lst.append(Paragraph("Illustrating splits: split(4in,36)", styleSheet['BodyText']))
     for s in t.split(4*inch,36):
         lst.append(s)
         lst.append(Spacer(0,6))
-
+    lst.append(Paragraph("Illustrating splits: split(4in,56)", styleSheet['BodyText']))
     lst.append(Spacer(0,6))
     for s in t.split(4*inch,56):
         lst.append(s)
         lst.append(Spacer(0,6))
 
+    lst.append(PageBreak())
+    data=  [['00', '01', '02', '03', '04'],
+            ['', '11', '12', '13', '14'],
+            ['20', '21', '22', '23', '24'],
+            ['30', '31', '', '33', '34']]
+    t=Table(data,style=[
+                    ('GRID',(0,0),(-1,-1),0.5,colors.grey),
+                    ('GRID',(1,1),(-2,-2),1,colors.green),
+                    ('BOX',(0,0),(1,-1),2,colors.red),
+                    ('BOX',(0,0),(-1,-1),2,colors.black),
+                    ('LINEABOVE',(1,2),(-2,2),1,colors.blue),
+                    ('LINEBEFORE',(2,1),(2,-2),1,colors.pink),
+                    ('BACKGROUND', (0, 0), (0, 1), colors.pink),
+                    ('SPAN',(0,0),(0,1)),
+                    ('BACKGROUND', (2, 2), (2, 3), colors.orange),
+                    ('SPAN',(2,2),(2,3)),
+                    ])
+    lst.append(Paragraph("Illustrating splits with spans: nosplit", styleSheet['BodyText']))
+    lst.append(t)
+    lst.append(Spacer(0,6))
+    lst.append(Paragraph("Illustrating splits with spans: split(4in,30)", styleSheet['BodyText']))
+    for s in t.split(4*inch,30):
+        lst.append(s)
+        lst.append(Spacer(0,6))
+    lst.append(Spacer(0,6))
+    lst.append(Paragraph("Illustrating splits with spans: split(4in,36)", styleSheet['BodyText']))
+    for s in t.split(4*inch,36):
+        lst.append(s)
+        lst.append(Spacer(0,6))
+    lst.append(Paragraph("Illustrating splits with spans: split(4in,56)", styleSheet['BodyText']))
+    lst.append(Spacer(0,6))
+    for s in t.split(4*inch,56):
+        lst.append(s)
+        lst.append(Spacer(0,6))
+
+    lst.append(PageBreak())
     import os, reportlab.platypus
     I = Image(os.path.join(os.path.dirname(reportlab.platypus.__file__),'..','tools','pythonpoint','demos','leftlogo.gif'))
     I.drawHeight = 1.25*inch*I.drawHeight / I.drawWidth
@@ -569,7 +608,7 @@
     lst.append(t)
 
     lst.append(PageBreak())
-    lst.append(Paragraph("This spanning example illustrates automatic remova of grids and lines in spanned cells!", styleSheet['BodyText']))
+    lst.append(Paragraph("This spanning example illustrates automatic removal of grids and lines in spanned cells!", styleSheet['BodyText']))
     lst.append(Spacer(0,6))
     data=  [['Top\nLeft', '', '02', '03', '04', '05', '06', '07'],
             ['', '', '12', 'Span (3,1) (6,2)', '','','','17'],
@@ -605,9 +644,6 @@
     t=LongTable(data, style=sty, colWidths = [50,100,200])
     lst.append(t)
 
-
-
-
     SimpleDocTemplate(outputfile('tables.pdf'), showBoundary=1).build(lst)
 
 
@@ -630,17 +666,3 @@
 #noruntests
 if __name__ == "__main__":
     unittest.TextTestRunner().run(makeSuite())
-
-
-#LINEABOVE
-#LINEBELOW
-#LINEBEFORE
-#LINEAFTER
-#GRID
-#BOX
-#INNERGRID ??
-
-#FONT
-#TEXTCOLOR
-#ALIGNMENT
-#PADDING