mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-01-18 22:12:14 +00:00
357 lines
11 KiB
Python
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)
|