platypus: added in NotAtTopPageBreak and support
authorrgbecker
Fri, 23 Feb 2007 17:45:16 +0000
changeset 2762 48eadc6faff2
parent 2761 ab458bd75cea
child 2763 d97521dc288b
platypus: added in NotAtTopPageBreak and support
reportlab/platypus/__init__.py
reportlab/platypus/doctemplate.py
reportlab/platypus/flowables.py
--- a/reportlab/platypus/__init__.py	Mon Feb 19 17:57:36 2007 +0000
+++ b/reportlab/platypus/__init__.py	Fri Feb 23 17:45:16 2007 +0000
@@ -11,5 +11,5 @@
 from reportlab.platypus.tables import Table, TableStyle, CellStyle, LongTable
 from reportlab.platypus.frames import Frame
 from reportlab.platypus.doctemplate import BaseDocTemplate, NextPageTemplate, PageTemplate, ActionFlowable, \
-                        SimpleDocTemplate, FrameBreak, PageBegin, Indenter
+                        SimpleDocTemplate, FrameBreak, PageBegin, Indenter, NotAtTopPageBreak
 from xpreformatted import XPreformatted
--- a/reportlab/platypus/doctemplate.py	Mon Feb 19 17:57:36 2007 +0000
+++ b/reportlab/platypus/doctemplate.py	Fri Feb 23 17:45:16 2007 +0000
@@ -7,7 +7,7 @@
 __doc__="""
 This module contains the core structure of platypus.
 
-Platypus constructs documents.  Document styles are determined by DocumentTemplates.
+rlatypus constructs documents.  Document styles are determined by DocumentTemplates.
 
 Each DocumentTemplate contains one or more PageTemplates which defines the look of the
 pages of the document.
@@ -108,8 +108,10 @@
         action = self.action[0]
         args = tuple(self.action[1:])
         arn = 'handle_'+action
+        if arn=="handle_nextPageTemplate" and args[0]=='main':
+            pass
         try:
-            apply(getattr(doc,arn), args)
+            getattr(doc,arn)(*args)
         except AttributeError, aerr:
             if aerr.args[0]==arn:
                 raise NotImplementedError, "Can't handle ActionFlowable(%s)" % action
@@ -175,6 +177,7 @@
     return n
 
 class FrameActionFlowable(Flowable):
+    _fixedWidth = _fixedHeight = 1
     def __init__(self,*arg,**kw):
         raise NotImplementedError('Abstract Class')
 
@@ -195,12 +198,19 @@
         frame._leftExtraIndent += self.left
         frame._rightExtraIndent += self.right
 
+class NotAtTopPageBreak(FrameActionFlowable):
+    def __init__(self):
+        pass
+
+    def frameAction(self,frame):
+        if not frame._atTop:
+            frame._generated_content = [PageBreak()]
+
 class NextPageTemplate(ActionFlowable):
     """When you get to the next page, use the template specified (change to two column, for example)  """
     def __init__(self,pt):
         ActionFlowable.__init__(self,('nextPageTemplate',pt))
 
-
 class PageTemplate:
     """
     essentially a list of Frames and an onPage routine to call at the start
@@ -251,7 +261,6 @@
         this page."""
         pass
 
-
 class BaseDocTemplate:
     """
     First attempt at defining a document template class.
@@ -350,13 +359,11 @@
         self._pageRefs = {}
         self._indexingFlowables = []
 
-
         #callback facility for progress monitoring
         self._onPage = None
         self._onProgress = None
         self._flowableCount = 0  # so we know how far to go
 
-
         #infinite loop detection if we start doing lots of empty pages
         self._curPageFlowableCount = 0
         self._emptyPages = 0
@@ -602,7 +609,6 @@
         finally:
             if frame: del f._frame
 
-
     def handle_flowable(self,flowables):
         '''try to handle one flowable from the front of list flowables.'''
 
@@ -627,24 +633,32 @@
             f.apply(self)
             self.afterFlowable(f)
         else:
+            frame = self.frame
             #try to fit it then draw it
-            if self.frame.add(f, self.canv, trySplit=self.allowSplitting):
-                self._curPageFlowableCount += 1
-                self.afterFlowable(f)
+            if frame.add(f, self.canv, trySplit=self.allowSplitting):
+                if not isinstance(f,FrameActionFlowable):
+                    self._curPageFlowableCount += 1
+                    self.afterFlowable(f)
+                else:
+                    S = getattr(frame,'_generated_content',None)
+                    if S:
+                        for i,f in enumerate(S):
+                            flowables.insert(i,f)
+                        del frame._generated_content
             else:
                 if self.allowSplitting:
                     # see if this is a splittable thing
-                    S = self.frame.split(f,self.canv)
+                    S = frame.split(f,self.canv)
                     n = len(S)
                 else:
                     n = 0
                 if n:
                     if not isinstance(S[0],(PageBreak,SlowPageBreak,ActionFlowable)):
-                        if self.frame.add(S[0], self.canv, trySplit=0):
+                        if frame.add(S[0], self.canv, trySplit=0):
                             self._curPageFlowableCount += 1
                             self.afterFlowable(S[0])
                         else:
-                            ident = "Splitting error(n==%d) on page %d in\n%s" % (n,self.page,self._fIdent(f,30,self.frame))
+                            ident = "Splitting error(n==%d) on page %d in\n%s" % (n,self.page,self._fIdent(f,30,frame))
                             #leave to keep apart from the raise
                             raise LayoutError(ident)
                         del S[0]
@@ -652,7 +666,7 @@
                         flowables.insert(i,f)   # put split flowables back on the list
                 else:
                     if hasattr(f,'_postponed'):
-                        ident = "Flowable %s too large on page %d" % (self._fIdent(f,30,self.frame), self.page)
+                        ident = "Flowable %s too large on page %d" % (self._fIdent(f,30,frame), self.page)
                         #leave to keep apart from the raise
                         raise LayoutError(ident)
                     # this ought to be cleared when they are finally drawn!
@@ -682,7 +696,7 @@
         self.canv.setTitle(self.title)
         self.canv.setSubject(self.subject)
         self.canv.setKeywords(self.keywords)
-        
+
         if self._onPage:
             self.canv.setPageCallBack(self._onPage)
         self.handle_documentBegin()
@@ -744,7 +758,7 @@
                 self._onProgress('PROGRESS',flowableCount - len(flowables))
 
         #reapply pagecatcher info
-        self.canv._doc.info = self._savedInfo 
+        self.canv._doc.info = self._savedInfo
 
         self._endBuild()
         if self._onProgress:
@@ -856,7 +870,6 @@
         '''called after a flowable has been rendered'''
         pass
 
-
 class SimpleDocTemplate(BaseDocTemplate):
     """A special case document template that will handle many simple documents.
        See documentation for BaseDocTemplate.  No pageTemplates are required
@@ -897,7 +910,6 @@
             self.pageTemplates[1].beforeDrawPage = self.onLaterPages
         BaseDocTemplate.build(self,flowables, canvasmaker=canvasmaker)
 
-
 def progressCB(typ, value):
     """Example prototype for progress monitoring.
 
--- a/reportlab/platypus/flowables.py	Mon Feb 19 17:57:36 2007 +0000
+++ b/reportlab/platypus/flowables.py	Fri Feb 23 17:45:16 2007 +0000
@@ -38,7 +38,6 @@
         'CondPageBreak','KeepTogether','Macro','CallerMacro','ParagraphAndImage',
         'FailOnWrap','HRFlowable','PTOContainer','KeepInFrame','UseUpSpace')
 
-
 class TraceInfo:
     "Holder for info about where an object originated"
     def __init__(self):
@@ -79,8 +78,7 @@
         #many flowables handle text and must be processed in the
         #absence of a canvas.  tagging them with their encoding
         #helps us to get conversions right.  Use Python codec names.
-        self.encoding = None        
-
+        self.encoding = None
 
     def _drawOn(self,canv):
         '''ensure canv is set on and then draw'''
@@ -273,7 +271,6 @@
             style.firstLineIndent = 0
         return [Preformatted(text1, self.style), Preformatted(text2, style)]
 
-
     def draw(self):
         #call another method for historical reasons.  Besides, I
         #suspect I will be playing with alternate drawing routines
@@ -455,7 +452,7 @@
         H += h
         if not atTop:
             h = f.getSpaceBefore()
-            if mergeSpace: h = max(h-pS,0) 
+            if mergeSpace: h = max(h-pS,0)
             H += h
         else:
             if obj is not None: obj._spaceBefore = f.getSpaceBefore()
@@ -711,11 +708,11 @@
 
 class PTOContainer(_Container,Flowable):
     '''PTOContainer(contentList,trailerList,headerList)
-    
+
     A container for flowables decorated with trailer & header lists.
     If the split operation would be called then the trailer and header
     lists are injected before and after the split. This allows specialist
-    "please turn over" and "continued from previous" like behaviours.''' 
+    "please turn over" and "continued from previous" like behaviours.'''
     def __init__(self,content,trailer=None,header=None):
         I = _PTOInfo(trailer,header)
         self._content = C = []
@@ -811,7 +808,7 @@
     if r<0: return None
     r = sqrt(r)
     if t>=0:
-        s1 = -t - r 
+        s1 = -t - r
     else:
         s1 = -t + r
     s2 = f/s1