Files
PyRIGS/z3c/rml/template.py
2014-12-07 17:32:25 +00:00

277 lines
8.2 KiB
Python

##############################################################################
#
# Copyright (c) 2007 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Style Related Element Processing
"""
import zope.interface
from reportlab import platypus
from z3c.rml import attr, directive, interfaces, occurence
from z3c.rml import canvas, flowable, page, stylesheet
class IStory(flowable.IFlow):
"""The story of the PDF file."""
occurence.containing(
*flowable.IFlow.getTaggedValue('directives'))
firstPageTemplate = attr.Text(
title=u'First Page Template',
description=u'The first page template to be used.',
default=None,
required=False)
class Story(flowable.Flow):
signature = IStory
def process(self):
self.parent.flowables = super(Story, self).process()
self.parent.doc._firstPageTemplateIndex = self.getFirstPTIndex()
def getFirstPTIndex(self):
args = dict(self.getAttributeValues(select=('firstPageTemplate',)))
fpt = args.pop('firstPageTemplate', None)
if fpt is None:
return 0
for idx, pageTemplate in enumerate(self.parent.doc.pageTemplates):
if pageTemplate.id == fpt:
return idx
raise ValueError('%r is not a correct page template id.' %fpt)
class IFrame(interfaces.IRMLDirectiveSignature):
"""A frame on a page."""
x1 = attr.Measurement(
title=u'X-Position',
description=u'The X-Position of the lower-left corner of the frame.',
allowPercentage=True,
required=True)
y1 = attr.Measurement(
title=u'Y-Position',
description=u'The Y-Position of the lower-left corner of the frame.',
allowPercentage=True,
required=True)
width = attr.Measurement(
title=u'Width',
description=u'The width of the frame.',
allowPercentage=True,
required=True)
height = attr.Measurement(
title=u'Height',
description=u'The height of the frame.',
allowPercentage=True,
required=True)
id = attr.Text(
title=u'Id',
description=u'The id of the frame.',
required=False)
leftPadding = attr.Measurement(
title=u'Left Padding',
description=u'The left padding of the frame.',
default=0,
required=False)
rightPadding = attr.Measurement(
title=u'Right Padding',
description=u'The right padding of the frame.',
default=0,
required=False)
topPadding = attr.Measurement(
title=u'Top Padding',
description=u'The top padding of the frame.',
default=0,
required=False)
bottomPadding = attr.Measurement(
title=u'Bottom Padding',
description=u'The bottom padding of the frame.',
default=0,
required=False)
showBoundary = attr.Boolean(
title=u'Show Boundary',
description=u'A flag to show the boundary of the frame.',
required=False)
class Frame(directive.RMLDirective):
signature = IFrame
def process(self):
# get the page size
size = self.parent.pt.pagesize
if size is None:
size = self.parent.parent.parent.doc.pagesize
# Get the arguments
args = dict(self.getAttributeValues())
# Deal with percentages
for name, dir in (('x1', 0), ('y1', 1), ('width', 0), ('height', 1)):
if isinstance(args[name], basestring) and args[name].endswith('%'):
args[name] = float(args[name][:-1])/100*size[dir]
frame = platypus.Frame(**args)
self.parent.frames.append(frame)
class IPageGraphics(canvas.IDrawing):
"""Define the page graphics for the page template."""
class PageGraphics(directive.RMLDirective):
zope.interface.implements(interfaces.ICanvasManager)
signature = IPageGraphics
def process(self):
onPage = self.parent.pt.onPage
def drawOnCanvas(canv, doc):
onPage(canv, doc)
canv.saveState()
self.canvas = canv
drawing = canvas.Drawing(self.element, self)
drawing.process()
canv.restoreState()
self.parent.pt.onPage = drawOnCanvas
class IPageTemplate(interfaces.IRMLDirectiveSignature):
"""Define a page template."""
occurence.containing(
occurence.OneOrMore('frame', IFrame),
occurence.ZeroOrOne('pageGraphics', IPageGraphics),
occurence.ZeroOrOne('mergePage', page.IMergePage),
)
id = attr.Text(
title=u'Id',
description=u'The id of the template.',
required=True)
pagesize = attr.PageSize(
title=u'Page Size',
description=u'The Page Size.',
required=False)
autoNextTemplate = attr.String(
title=u'Auto Next Page Template',
description=u'The page template to use automatically for the next page.',
required=False)
class PageTemplate(directive.RMLDirective):
signature = IPageTemplate
attrMapping = {'autoNextTemplate': 'autoNextPageTemplate'}
factories = {
'frame': Frame,
'pageGraphics': PageGraphics,
'mergePage': page.MergePageInPageTemplate,
}
def process(self):
args = dict(self.getAttributeValues(attrMapping=self.attrMapping))
pagesize = args.pop('pagesize', None)
self.frames = []
self.pt = platypus.PageTemplate(**args)
self.processSubDirectives()
self.pt.frames = self.frames
if pagesize:
self.pt.pagesize = pagesize
self.parent.parent.doc.addPageTemplates(self.pt)
class ITemplate(interfaces.IRMLDirectiveSignature):
"""Define a page template."""
occurence.containing(
occurence.OneOrMore('pageTemplate', IPageTemplate),
)
pagesize = attr.PageSize(
title=u'Page Size',
description=u'The Page Size.',
required=False)
rotation = attr.Integer(
title=u'Rotation',
description=u'The rotation of the page in multiples of 90 degrees.',
required=False)
leftMargin = attr.Measurement(
title=u'Left Margin',
description=u'The left margin of the template.',
default=0,
required=False)
rightMargin = attr.Measurement(
title=u'Right Margin',
description=u'The right margin of the template.',
default=0,
required=False)
topMargin = attr.Measurement(
title=u'Top Margin',
description=u'The top margin of the template.',
default=0,
required=False)
bottomMargin = attr.Measurement(
title=u'Bottom Margin',
description=u'The bottom margin of the template.',
default=0,
required=False)
showBoundary = attr.Boolean(
title=u'Show Boundary',
description=u'A flag to show the boundary of the template.',
required=False)
allowSplitting = attr.Boolean(
title=u'Allow Splitting',
description=u'A flag to allow splitting over multiple templates.',
required=False)
title = attr.Text(
title=u'Title',
description=u'The title of the PDF document.',
required=False)
author = attr.Text(
title=u'Author',
description=u'The author of the PDF document.',
required=False)
class Template(directive.RMLDirective):
signature = ITemplate
factories = {
'pageTemplate': PageTemplate,
}
def process(self):
args = self.getAttributeValues()
args += self.parent.getAttributeValues(
select=('debug', 'compression', 'invariant'),
attrMapping={'debug': '_debug', 'compression': 'pageCompression'})
args += (('cropMarks', self.parent.cropMarks),)
self.parent.doc = platypus.BaseDocTemplate(
self.parent.outputFile, **dict(args))
self.processSubDirectives()