platypus: attempt to make KeepTogether/keepWithNext more robust
authorrgbecker
Thu, 03 Feb 2005 11:30:21 +0000
changeset 2449 47b15f941325
parent 2448 facfc9a8957a
child 2450 f2ae0122a66a
platypus: attempt to make KeepTogether/keepWithNext more robust
reportlab/platypus/doctemplate.py
reportlab/platypus/flowables.py
--- a/reportlab/platypus/doctemplate.py	Wed Feb 02 14:43:28 2005 +0000
+++ b/reportlab/platypus/doctemplate.py	Thu Feb 03 11:30:21 2005 +0000
@@ -71,7 +71,6 @@
         """Called after build ends but before isSatisfied"""
         pass
 
-
 class ActionFlowable(Flowable):
     '''This Flowable is never drawn, it can be used for data driven controls
        For example to change a page template (from one column to two, for example)
@@ -115,15 +114,18 @@
     def identity(self, maxLen=None):
         return "ActionFlowable: %s" % str(self.action)
 
+class LCActionFlowable(ActionFlowable):
+    locChanger = 1                  #we cause a frame or page change
+
 class NextFrameFlowable(ActionFlowable):
     def __init__(self,ix,resume=0):
         ActionFlowable.__init__(self,('nextFrame',ix,resume))
 
-class CurrentFrameFlowable(ActionFlowable):
+class CurrentFrameFlowable(LCActionFlowable):
     def __init__(self,ix,resume=0):
         ActionFlowable.__init__(self,('currentFrame',ix,resume))
 
-class _FrameBreak(ActionFlowable):
+class _FrameBreak(LCActionFlowable):
     '''
     A special ActionFlowable that allows setting doc._nextFrameIndex
 
@@ -139,7 +141,7 @@
         ActionFlowable.apply(self,doc)
 
 FrameBreak = _FrameBreak('frameEnd')
-PageBegin = ActionFlowable('pageBegin')
+PageBegin = LCActionFlowable('pageBegin')
 
 def _evalMeasurement(n):
     if type(n) is type(''):
@@ -461,7 +463,7 @@
             self.handle_frameBegin()
 
     def handle_nextPageTemplate(self,pt):
-        '''On endPage chenge to the page template with name or index pt'''
+        '''On endPage change to the page template with name or index pt'''
         if type(pt) is StringType:
             if hasattr(self, '_nextPageTemplateCycle'): del self._nextPageTemplateCycle
             for t in self.pageTemplates:
@@ -494,7 +496,7 @@
             raise TypeError, "argument pt should be string or integer or list"
 
     def handle_nextFrame(self,fx):
-        '''On endFrame chenge to the frame with name or index fx'''
+        '''On endFrame change to the frame with name or index fx'''
         if type(fx) is StringType:
             for f in self.pageTemplate.frames:
                 if f.id == fx:
@@ -507,7 +509,7 @@
             raise TypeError, "argument fx should be string or integer"
 
     def handle_currentFrame(self,fx):
-        '''chenge to the frame with name or index fx'''
+        '''change to the frame with name or index fx'''
         if type(fx) is StringType:
             for f in self.pageTemplate.frames:
                 if f.id == fx:
@@ -547,14 +549,13 @@
             flowables.insert(0, FrameBreak())
             return
 
-
     def handle_keepWithNext(self, flowables):
         "implements keepWithNext"
         i = 0
         n = len(flowables)
-        while i<n and flowables[i].getKeepWithNext(): i = i + 1
+        while i<n and flowables[i].getKeepWithNext(): i += 1
         if i:
-            i = i + 1
+            if not getattr(flowables[i],'locChanger',None): i += 1
             K = KeepTogether(flowables[:i])
             for f in K._flowables:
                 f.keepWithNext = 0
--- a/reportlab/platypus/flowables.py	Wed Feb 02 14:43:28 2005 +0000
+++ b/reportlab/platypus/flowables.py	Thu Feb 03 11:30:21 2005 +0000
@@ -445,14 +445,16 @@
             H += pS
     return W, H
 
-def _makeIndexable(V):
+def _flowableSublist(V):
     "if it isn't a list or tuple, wrap it in a list"
     if type(V) not in (ListType, TupleType): V = V is not None and [V] or []
+    from doctemplate import  ActionFlowable
+    assert not filter(lambda x: isinstance(x,ActionFlowable),V),'Action flowables not allowed in sublists'
     return V
 
 class KeepTogether(Flowable):
     def __init__(self,flowables,maxHeight=None):
-        self._flowables = _makeIndexable(flowables)
+        self._flowables = _flowableSublist(flowables)
         self._maxHeight = maxHeight
 
     def __repr__(self):
@@ -600,8 +602,8 @@
 
 class _PTOInfo:
     def __init__(self,trailer,header):
-        self.trailer = _makeIndexable(trailer)
-        self.header = _makeIndexable(header)
+        self.trailer = _flowableSublist(trailer)
+        self.header = _flowableSublist(header)
 
 class PTOContainer(Flowable):
     '''PTOContainer(contentList,trailerList,headerList)
@@ -613,7 +615,7 @@
     def __init__(self,content,trailer=None,header=None):
         I = _PTOInfo(trailer,header)
         self._content = C = []
-        for _ in _makeIndexable(content):
+        for _ in _flowableSublist(content):
             if isinstance(_,PTOContainer):
                 C.extend(_._content)
             else: