import os import OFS from Globals import ImageFile from FieldHelpTopic import FieldHelpTopic from AccessControl import ClassSecurityInfo from Products.PythonScripts.Utility import allow_class from ZPublisher.HTTPRequest import FileUpload from Globals import InitializeClass, get_request from StringIO import StringIO from zLOG import LOG import getopt, sys, os from urllib import quote class FieldRegistry: """A registry of fields, maintaining a dictionary with the meta_type of the field classes as key and the field class as values. Updates the Form as necessary as well. """ # Declarative security security = ClassSecurityInfo() def __init__(self): """Initializer of FieldRegistry. """ self._fields = {} def get_field_class(self, fieldname): """Get a certain field class by its name (meta_type) fieldname -- the name of the field to get from the registry """ return self._fields[fieldname] def get_field_classes(self): """Return all fields. """ return self._fields def registerField(self, field_class, icon=None): """Register field with Formulator. field_class -- the class of the field to be registered icon -- optional filename of the icon """ # put it in registry dictionary self._fields[field_class.meta_type] = field_class # set up dummy fields in field's form initializeFieldForm(field_class) # set up the icon if a filename is supplied if icon: setupIcon(field_class, icon, 'Formulator') def registerFieldHelp(self, context): """Register field help topics. context -- product registration context object """ # get help folder for product help = context.getProductHelp() for field_name, field_class in self._fields.items(): # don't register help for internal fields if (hasattr(field_class, 'internal_field') and getattr(field_class, 'internal_field')): continue # unregister any help topic already registered if field_name in help.objectIds('Help Topic'): help._delObject(field_name) # register help topic ht = FieldHelpTopic(field_name, "Formulator Field - %s" % field_name, field_class) context.registerHelpTopic(field_name, ht) def initializeFields(self): """Initialize all field classes in field forms to use actual field objects so we can finally eat our own dogfood. """ # for each field, realize fields in form # this is finally possible as all field classes are now # fully defined. for field_class in self._fields.values(): field_class.form._realize_fields() field_class.override_form._realize_fields() field_class.tales_form._realize_fields() # initialize registry as a singleton FieldRegistry = FieldRegistry() def initializeFieldForm(field_class): """Initialize the properties (fields and values) on a particular field class. Also add the tales and override methods. """ from Form import BasicForm from DummyField import fields form = BasicForm() override_form = BasicForm() tales_form = BasicForm() for field in getPropertyFields(field_class.widget): form.add_field(field, "widget") tales_field = fields.TALESField(field.id, title=field.get_value('title'), description="", default="", display_width=40, required=0) tales_form.add_field(tales_field, "widget") method_field = fields.MethodField(field.id, title=field.get_value("title"), description="", default="", required=0) override_form.add_field(method_field, "widget") for field in getPropertyFields(field_class.validator): form.add_field(field, "validator") tales_field = fields.TALESField(field.id, title=field.get_value('title'), description="", default="", display_with=40, required=0) tales_form.add_field(tales_field, "validator") method_field = fields.MethodField(field.id, title=field.get_value("title"), description="", default="", required=0) override_form.add_field(method_field, "validator") field_class.form = form field_class.override_form = override_form field_class.tales_form = tales_form def getPropertyFields(obj): """Get property fields from a particular widget/validator. """ fields = [] for property_name in obj.property_names: fields.append(getattr(obj, property_name)) return fields def setupIcon(klass, icon, repository): """Load icon into Zope image object and put it in Zope's repository for use by the ZMI, for a particular class. klass -- the class of the field we're adding icon -- the icon """ # set up misc_ respository if not existing yet if not hasattr(OFS.misc_.misc_, repository): setattr(OFS.misc_.misc_, repository, OFS.misc_.Misc_(repository, {})) # get name of icon in the misc_ directory icon_name = os.path.split(icon)[1] # set up image object from icon file icon_image = ImageFile(icon, globals()) icon_image.__roles__ = None # put icon image object in misc_/Formulator/ getattr(OFS.misc_.misc_, repository)[icon_name] = icon_image # set icon attribute in field_class to point to this image obj setattr(klass, 'icon', 'misc_/%s/%s' % (repository, icon_name)) InitializeClass(FieldRegistry) allow_class(FieldRegistry)