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

357 lines
11 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.
#
##############################################################################
"""Page Drawing Related Element Processing
"""
import types
import reportlab.pdfbase.pdfform
from z3c.rml import attr, directive, interfaces, occurence
try:
import reportlab.graphics.barcode
except ImportError:
# barcode package has not been installed
import types
import reportlab.graphics
reportlab.graphics.barcode = types.ModuleType('barcode')
reportlab.graphics.barcode.getCodeNames = lambda : ()
class IBarCodeBase(interfaces.IRMLDirectiveSignature):
"""Create a bar code."""
code = attr.Choice(
title=u'Code',
description=u'The name of the type of code to use.',
choices=reportlab.graphics.barcode.getCodeNames(),
required=True)
value = attr.TextNode(
title=u'Value',
description=u'The value represented by the code.',
required=True)
width = attr.Measurement(
title=u'Width',
description=u'The width of the barcode.',
required=False)
height = attr.Measurement(
title=u'Height',
description=u'The height of the barcode.',
required=False)
barStrokeColor = attr.Color(
title=u'Bar Stroke Color',
description=(u'The color of the line strokes in the barcode.'),
required=False)
barStrokeWidth = attr.Measurement(
title=u'Bar Stroke Width',
description=u'The width of the line strokes in the barcode.',
required=False)
barFillColor = attr.Color(
title=u'Bar Fill Color',
description=(u'The color of the filled shapes in the barcode.'),
required=False)
gap = attr.Measurement(
title=u'Gap',
description=u'The width of the inter-character gaps.',
required=False)
# Bar code dependent attributes
# I2of5, Code128, Standard93, FIM, POSTNET, Ean13B
barWidth = attr.Measurement(
title=u'Bar Width',
description=u'The width of the smallest bar within the barcode',
required=False)
# I2of5, Code128, Standard93, FIM, POSTNET
barHeight = attr.Measurement(
title=u'Bar Height',
description=u'The height of the symbol.',
required=False)
# I2of5
ratio = attr.Float(
title=u'Ratio',
description=(u'The ratio of wide elements to narrow elements. '
u'Must be between 2.0 and 3.0 (or 2.2 and 3.0 if the '
u'barWidth is greater than 20 mils (.02 inch)).'),
min=2.0,
max=3.0,
required=False)
# I2of5
# Should be boolean, but some code want it as int; will still work
checksum = attr.Integer(
title=u'Ratio',
description=(u'A flag that enables the computation and inclusion of '
u'the check digit.'),
required=False)
# I2of5
bearers = attr.Float(
title=u'Bearers',
description=(u'Height of bearer bars (horizontal bars along the top '
u'and bottom of the barcode). Default is 3 '
u'x-dimensions. Set to zero for no bearer bars.'
u'(Bearer bars help detect misscans, so it is '
u'suggested to leave them on).'),
required=False)
# I2of5, Code128, Standard93, FIM, Ean13
quiet = attr.Boolean(
title=u'Quiet Zone',
description=(u'A flag to include quiet zones in the symbol.'),
required=False)
# I2of5, Code128, Standard93, FIM, Ean13
lquiet = attr.Measurement(
title=u'Left Quiet Zone',
description=(u"Quiet zone size to the left of code, if quiet is "
u"true. Default is the greater of .25 inch or .15 times "
u"the symbol's length."),
required=False)
# I2of5, Code128, Standard93, FIM, Ean13
rquiet = attr.Measurement(
title=u'Right Quiet Zone',
description=(u"Quiet zone size to the right of code, if quiet is "
u"true. Default is the greater of .25 inch or .15 times "
u"the symbol's length."),
required=False)
# I2of5, Code128, Standard93, FIM, POSTNET, Ean13
fontName = attr.String(
title=u'Font Name',
description=(u'The font used to print the value.'),
required=False)
# I2of5, Code128, Standard93, FIM, POSTNET, Ean13
fontSize = attr.Measurement(
title=u'Font Size',
description=(u'The size of the value text.'),
required=False)
# I2of5, Code128, Standard93, FIM, POSTNET, Ean13
humanReadable = attr.Boolean(
title=u'Human Readable',
description=(u'A flag when set causes the value to be printed below '
u'the bar code.'),
required=False)
# I2of5, Standard93
stop = attr.Boolean(
title=u'Show Start/Stop',
description=(u'A flag to specify whether the start/stop symbols '
u'are to be shown.'),
required=False)
# FIM, POSTNET
spaceWidth = attr.Measurement(
title=u'Space Width',
description=u'The space of the inter-character gaps.',
required=False)
# POSTNET
shortHeight = attr.Measurement(
title=u'Short Height',
description=u'The height of the short bar.',
required=False)
# Ean13
textColor = attr.Color(
title=u'Text Color',
description=(u'The color of human readable text.'),
required=False)
# USPS4S
routing = attr.String(
title=u'Routing',
description=u'The routing information string.',
required=False)
# QR
barLevel = attr.Choice(
title=u'Bar Level',
description=u'The error correction level for QR code',
choices=['L', 'M', 'Q', 'H'],
required=False)
class IBarCode(IBarCodeBase):
"""A barcode graphic."""
x = attr.Measurement(
title=u'X-Position',
description=u'The x-position of the lower-left corner of the barcode.',
default=0,
required=False)
y = attr.Measurement(
title=u'Y-Position',
description=u'The y-position of the lower-left corner of the barcode.',
default=0,
required=False)
isoScale = attr.Boolean(
title=u'Isometric Scaling',
description=u'When set, the aspect ration of the barcode is enforced.',
required=False)
class BarCode(directive.RMLDirective):
signature = IBarCode
def process(self):
kw = dict(self.getAttributeValues())
name = kw.pop('code')
kw['value'] = str(kw['value'])
x = kw.pop('x', 0)
y = kw.pop('y', 0)
code = reportlab.graphics.barcode.createBarcodeDrawing(name, **kw)
manager = attr.getManager(self, interfaces.ICanvasManager)
code.drawOn(manager.canvas, x, y)
class IField(interfaces.IRMLDirectiveSignature):
"""A field."""
title = attr.Text(
title=u'Title',
description=u'The title of the field.',
required=True)
x = attr.Measurement(
title=u'X-Position',
description=u'The x-position of the lower-left corner of the field.',
default=0,
required=True)
y = attr.Measurement(
title=u'Y-Position',
description=u'The y-position of the lower-left corner of the field.',
default=0,
required=True)
class Field(directive.RMLDirective):
signature = IField
callable = None
attrMapping = {}
def process(self):
kwargs = dict(self.getAttributeValues(attrMapping=self.attrMapping))
canvas = attr.getManager(self, interfaces.ICanvasManager).canvas
getattr(reportlab.pdfbase.pdfform, self.callable)(canvas, **kwargs)
class ITextField(IField):
"""A text field within the PDF"""
width = attr.Measurement(
title=u'Width',
description=u'The width of the text field.',
required=True)
height = attr.Measurement(
title=u'Height',
description=u'The height of the text field.',
required=True)
value = attr.Text(
title=u'Value',
description=u'The default text value of the field.',
required=False)
maxLength = attr.Integer(
title=u'Maximum Length',
description=u'The maximum amount of characters allowed in the field.',
required=False)
multiline = attr.Boolean(
title=u'Multiline',
description=u'A flag when set allows multiple lines within the field.',
required=False)
class TextField(Field):
signature = ITextField
callable = 'textFieldAbsolute'
attrMapping = {'maxLength': 'maxlen'}
class IButtonField(IField):
"""A button field within the PDF"""
value = attr.Choice(
title=u'Value',
description=u'The value of the button.',
choices=('Yes', 'Off'),
required=True)
class ButtonField(Field):
signature = IButtonField
callable = 'buttonFieldAbsolute'
class IOption(interfaces.IRMLDirectiveSignature):
"""An option in the select field."""
value = attr.TextNode(
title=u'Value',
description=u'The value of the option.',
required=True)
class Option(directive.RMLDirective):
signature = IOption
def process(self):
value = self.getAttributeValues(valuesOnly=True)[0]
self.parent.options.append(value)
class ISelectField(IField):
"""A selection field within the PDF"""
occurence.containing(
occurence.ZeroOrMore('option', IOption))
width = attr.Measurement(
title=u'Width',
description=u'The width of the select field.',
required=True)
height = attr.Measurement(
title=u'Height',
description=u'The height of the select field.',
required=True)
value = attr.Text(
title=u'Value',
description=u'The default value of the field.',
required=False)
class SelectField(Field):
signature = ISelectField
callable = 'selectFieldAbsolute'
factories = {'option': Option}
def process(self):
self.options = []
self.processSubDirectives()
kwargs = dict(self.getAttributeValues(attrMapping=self.attrMapping))
kwargs['options'] = self.options
canvas = attr.getManager(self, interfaces.ICanvasManager).canvas
getattr(reportlab.pdfbase.pdfform, self.callable)(canvas, **kwargs)