reportlab/platypus/flowables.py
changeset 2955 cc16265295fb
parent 2950 6c243412b06c
child 2956 5c17941635bd
equal deleted inserted replaced
2954:5ec6485e810a 2955:cc16265295fb
   397         r = Flowable.identity(self,maxLen)
   397         r = Flowable.identity(self,maxLen)
   398         if r[-4:]=='>...' and type(self.filename) is StringType:
   398         if r[-4:]=='>...' and type(self.filename) is StringType:
   399             r = "%s filename=%s>" % (r[:-4],self.filename)
   399             r = "%s filename=%s>" % (r[:-4],self.filename)
   400         return r
   400         return r
   401 
   401 
   402 class Spacer(Flowable):
   402 class NullDraw(Flowable):
       
   403     def draw(self):
       
   404         pass
       
   405 
       
   406 class Spacer(NullDraw):
   403     """A spacer just takes up space and doesn't draw anything - it guarantees
   407     """A spacer just takes up space and doesn't draw anything - it guarantees
   404        a gap between objects."""
   408        a gap between objects."""
   405     _fixedWidth = 1
   409     _fixedWidth = 1
   406     _fixedHeight = 1
   410     _fixedHeight = 1
   407     def __init__(self, width, height):
   411     def __init__(self, width, height):
   409         self.height = height
   413         self.height = height
   410 
   414 
   411     def __repr__(self):
   415     def __repr__(self):
   412         return "%s(%s, %s)" % (self.__class__.__name__,self.width, self.height)
   416         return "%s(%s, %s)" % (self.__class__.__name__,self.width, self.height)
   413 
   417 
   414     def draw(self):
   418 class UseUpSpace(NullDraw):
   415         pass
       
   416 
       
   417 class UseUpSpace(Flowable):
       
   418     def __init__(self):
   419     def __init__(self):
   419         pass
   420         pass
   420 
   421 
   421     def __repr__(self):
   422     def __repr__(self):
   422         return "%s()" % self.__class__.__name__
   423         return "%s()" % self.__class__.__name__
   423 
   424 
   424     def wrap(self, availWidth, availHeight):
   425     def wrap(self, availWidth, availHeight):
   425         self.width = availWidth
   426         self.width = availWidth
   426         self.height = availHeight
   427         self.height = availHeight
   427         return (availWidth,availHeight-1e-8)  #step back a point
   428         return (availWidth,availHeight-1e-8)  #step back a point
   428 
       
   429     def draw(self):
       
   430         pass
       
   431 
   429 
   432 class PageBreak(UseUpSpace):
   430 class PageBreak(UseUpSpace):
   433     """Move on to the next page in the document.
   431     """Move on to the next page in the document.
   434        This works by consuming all remaining space in the frame!"""
   432        This works by consuming all remaining space in the frame!"""
   435 
   433 
   640                 del self.P._offsets
   638                 del self.P._offsets
   641         else:
   639         else:
   642             self.I.drawOn(canv,self.width-self.wI-self.xpad,self.height-self.hI)
   640             self.I.drawOn(canv,self.width-self.wI-self.xpad,self.height-self.hI)
   643             self.P.drawOn(canv,0,0)
   641             self.P.drawOn(canv,0,0)
   644 
   642 
   645 class FailOnWrap(Flowable):
   643 class FailOnWrap(NullDraw):
   646     def wrap(self, availWidth, availHeight):
   644     def wrap(self, availWidth, availHeight):
   647         raise ValueError("FailOnWrap flowable wrapped and failing as ordered!")
   645         raise ValueError("FailOnWrap flowable wrapped and failing as ordered!")
   648 
   646 
   649     def draw(self):
       
   650         pass
       
   651 
       
   652 class FailOnDraw(Flowable):
   647 class FailOnDraw(Flowable):
   653     def wrap(self, availWidth, availHeight):
   648     def wrap(self, availWidth, availHeight):
   654         return (0,0)
   649         return 0,0
   655 
   650 
   656     def draw(self):
   651     def draw(self):
   657         raise ValueError("FailOnDraw flowable drawn, and failing as ordered!")
   652         raise ValueError("FailOnDraw flowable drawn, and failing as ordered!")
   658 
   653 
   659 class HRFlowable(Flowable):
   654 class HRFlowable(Flowable):
  1113         return 0,0
  1108         return 0,0
  1114 
  1109 
  1115     def draw(self):
  1110     def draw(self):
  1116         self.canv.bookmarkHorizontal(self._name,0,0)
  1111         self.canv.bookmarkHorizontal(self._name,0,0)
  1117 
  1112 
  1118 class FrameSplitter(Flowable):
  1113 class FrameSplitter(NullDraw):
  1119     '''When encountered this flowable should either switch directly to nextTemplate
  1114     '''When encountered this flowable should either switch directly to nextTemplate
  1120     if remaining space in the current frame is less than gap+required or it should
  1115     if remaining space in the current frame is less than gap+required or it should
  1121     temporarily modify the current template to have the frames from nextTemplate
  1116     temporarily modify the current template to have the frames from nextTemplate
  1122     that are listed in nextFrames and switch to the first of those frames. 
  1117     that are listed in nextFrames and switch to the first of those frames. 
  1123     '''
  1118     '''
  1163                 F[i]=f
  1158                 F[i]=f
  1164             T.frames=F
  1159             T.frames=F
  1165             G.append(CurrentFrameFlowable(F[0].id))
  1160             G.append(CurrentFrameFlowable(F[0].id))
  1166         frame.add_generated_content(*G)
  1161         frame.add_generated_content(*G)
  1167         return 0,0
  1162         return 0,0
  1168     def draw(self):
  1163 
  1169         pass
  1164 class DocAssign(NullDraw):
       
  1165     '''At wrap time this flowable evaluates var=expr in the doctemplate namespace'''
       
  1166     _ZEROSIZE=1
       
  1167     def __init__(self,var,expr,life='frame'):
       
  1168         Flowable.__init__(self)
       
  1169         self.args = var,expr,life
       
  1170     def wrap(self,aW,aH):
       
  1171         NS=self._doctemplateAttr('_nameSpace')
       
  1172         NS.update(dict(availableWidth=aW,availableHeight=aH))
       
  1173         try:
       
  1174             self._doctemplateAttr('d'+self.__class__.__name__[1:])(*self.args)
       
  1175         finally:
       
  1176             for k in 'availableWidth','availableHeight':
       
  1177                 try:
       
  1178                     del NS[k]
       
  1179                 except:
       
  1180                     pass
       
  1181         return 0,0
       
  1182 
       
  1183 class DocExec(DocAssign):
       
  1184     '''at wrap time exec stmt in doc._nameSpace'''
       
  1185     def __init__(self,stmt):
       
  1186         Flowable.__init__(self)
       
  1187         self.args=stmt,
       
  1188 
       
  1189 class DocPara(DocAssign):
       
  1190     '''at wrap time create a paragraph with the value of expr as text
       
  1191     if paraTemplate is specified it should use %(value)s for string interpolation
       
  1192     suitable defaults will be used if style and klass are None
       
  1193     '''
       
  1194     def __init__(self,expr,paraTemplate=None,style=None,klass=None):
       
  1195         Flowable.__init__(self)
       
  1196         self.expr=expr
       
  1197         self.paraTemplate=paraTemplate
       
  1198         self.style=style
       
  1199         self.klass=klass
       
  1200 
       
  1201     def wrap(self,aW,aH):
       
  1202         value=self._doctemplateAttr('docEval')(self.expr)
       
  1203         if self.paraTemplate:
       
  1204             value = self.paraTemplate % dict(value=value)
       
  1205         else:
       
  1206             value = str(value)
       
  1207         P = self.klass
       
  1208         if not P:
       
  1209             from reportlab.platypus.paragraph import Paragraph as P
       
  1210         style = self.style
       
  1211         if not style:
       
  1212             from reportlab.lib.styles import getSampleStyleSheet
       
  1213             style=getSampleStyleSheet()['Code']
       
  1214         self._doctemplateAttr('frame').add_generated_content(P(value,style=style))
       
  1215         return 0,0