mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-01-18 14:02:15 +00:00
277 lines
8.2 KiB
Python
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()
|