[Zope3-checkins] CVS: Zope3/src/zope/app/form - __init__.py:1.1.2.1 configure.zcml:1.1.2.1 utility.py:1.1.2.1 widget.py:1.1.2.1

Jim Fulton jim@zope.com
Mon, 23 Dec 2002 14:31:36 -0500


Update of /cvs-repository/Zope3/src/zope/app/form
In directory cvs.zope.org:/tmp/cvs-serv19908/zope/app/form

Added Files:
      Tag: NameGeddon-branch
	__init__.py configure.zcml utility.py widget.py 
Log Message:
Initial renaming before debugging

=== Added File Zope3/src/zope/app/form/__init__.py ===
#
# This file is necessary to make this directory a package.


=== Added File Zope3/src/zope/app/form/configure.zcml ===
<zopeConfigure xmlns='http://namespaces.zope.org/zope'>

  <include package=".Views" />

</zopeConfigure>


=== Added File Zope3/src/zope/app/form/utility.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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.
# 
##############################################################################
"""Form utility functions

In Zope 2's formulator, forms provide a basic mechanism for
organizating collections of fields and providing unsert interfaces for
them, especially editing interfaces.

In Zope 3, formulator's forms are replaced by Schema (See
Zope.Schema). In addition, the Formulator fields have been replaced by
schema fields and form widgets. Schema fields just express the sematics
of data values. They contain no presentation logic or parameters.
Widgets are views on fields that take care of presentation. The widget
view names represent styles that can be selected by applications to
customise the presentation. There can also be custom widgets with
specific parameters.

This module provides some utility functions that provide some of the
functionality of formulator forms that isn't handled by schema,
fields, or widgets.

$Id: utility.py,v 1.1.2.1 2002/12/23 19:31:35 jim Exp $
"""
__metaclass__ = type

from zope.component import getView, getDefaultViewName
from zope.schema.interfaces import IField
from zope.app.interfaces.forms import IWidget
from zope.app.interfaces.forms import WidgetsError, MissingInputError
from zope.component.interfaces import IViewFactory


def setUpWidget(view, name, field, value=None, prefix=None,
                force=0, vname=None):
    """Set up a single view widget

    The widget will be an attribute of the view. If there is already
    an attribute of the given name, it must be a widget and it will be
    initialized with the given value if not None.

    If there isn't already a view attribute of the given name, then a
    widget will be created and assigned to the attribute.
    """

    # Has a (custom) widget already been defined?
    widget = getattr(view, name, None)

    if widget is None:
        # There isn't already a widget, create one
        field = field.bind(view.context)
        if vname is None:
            vname = getDefaultViewName(field, view.request)
        widget = getView(field, vname, view.request)
        setattr(view, name, widget)

    else:
        # We have an attribute of the right name, it it really a widget
        if IViewFactory.isImplementedBy(widget):
            # This is a view factory, probably a custom widget.
            # Try to make it into a widget.
            field = field.bind(view.context)
            widget = widget(field, view.request)
            if IWidget.isImplementedBy(widget):
                # Yee ha! We have a widget now, save it
                setattr(view, name, widget)            
            
        if not IWidget.isImplementedBy(widget):
            raise TypeError(
                "The %s view attribute named, %s, should be a widget, "
                "but isn't."
                % (view.__class__.__name__, name))

    if prefix:
        widget.setPrefix(prefix)

    if value is not None and (force or not widget.haveData()):
        widget.setData(value)

def fieldNames(schema):

    names = []
    for name in schema:
        field = schema[name]
        if IField.isImplementedBy(field):
            names.append((field.order, name))

    names.sort()

    return [name[1] for name in names]

def setUpWidgets(view, schema, prefix=None, force=0,
                 initial={}, names=None):
    """Set up widgets for the fields defined by a schema

    """

    for name in (names or schema):
        field = schema[name]
        if IField.isImplementedBy(field):
            # OK, we really got a field
            setUpWidget(view, name, field, initial.get(name),
                        prefix=prefix, force=force)

def setUpEditWidgets(view, schema, content=None, prefix=None, force=0,
                     names=None):
    """Set up widgets for the fields defined by a schema

    Initial data is provided by content object attributes.
    No initial data is provided if the content lacks a named
    attribute, or if the named attribute value is None.
    """
    if content is None:
        content = view.context

    for name in (names or schema):
        field = schema[name]
        if IField.isImplementedBy(field):
            # OK, we really got a field
            if field.readonly:
                vname = 'display'
            else:
                vname = 'edit'

            try:
                value = getattr(content, name)
            except AttributeError, v:
                if v.__class__ != AttributeError:
                    raise
                value = None
                
            setUpWidget(view, name, field, value,
                        prefix = prefix, force = force, vname = vname)

def haveWidgetsData(view, schema, names=None):
    """Collect the user-entered data defined by a schema

    Data is collected from view widgets. For every field in the
    schema, we look for a view of the same name and get it's data.

    The data are returned in a mapping from field name to value.
    """

    for name in (names or schema):
        field = schema[name]
        if IField.isImplementedBy(field):
            # OK, we really got a field
            if  getattr(view, name).haveData():
                return True

    return False

def getWidgetsData(view, schema, required=1, names=None):
    """Collect the user-entered data defined by a schema

    Data is collected from view widgets. For every field in the
    schema, we look for a view of the same name and get it's data.

    The data are returned in a mapping from field name to value.

    If the required argument is true, then all of the data defined by
    the schema will be returned. If some required data are missing
    from the input, an error will be raised.

    """

    result = {}
    errors = []

    for name in (names or schema):
        field = schema[name]
        if IField.isImplementedBy(field):
            # OK, we really got a field
            widget = getattr(view, name)
            if widget.haveData():
                try:
                    result[name] = widget.getData()
                except Exception, v:
                    errors.append(v)
            elif required and field.required:
                raise MissingInputError(
                    widget.name, widget.title, name)

    if errors:
        raise WidgetsError(*errors)
    
    return result

def getWidgetsDataForContent(view, schema, content=None, required=0,
                             names=None):
    """Collect the user-entered data defined by a schema

    Data is collected from view widgets. For every field in the
    schema, we look for a view of the same name and get it's data.

    The data are assigned to the given content object.

    If the required argument is true, then all of the data defined by
    the schema will be set, at least for required fields. If some data
    for required fields are missing from the input, an error will be
    raised.
    
    """
    
    data = getWidgetsData(view, schema, required, names)
    
    if content is None:
        content = view.context

    errors = []

    for name in data:
        # OK, we really got a field
        try:
            setattr(content, name, data[name])
        except Exception, v:
            errors.append(v)
                
    if errors:
        raise WidgetsError(*errors)



=== Added File Zope3/src/zope/app/form/widget.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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.
# 
##############################################################################
"""
$Id: widget.py,v 1.1.2.1 2002/12/23 19:31:35 jim Exp $
"""
from zope.app.interfaces.forms import IWidget
from zope.schema.interfaces import ValidationError
from zope.app.interfaces.forms import WidgetInputError
from zope.component.interfaces import IViewFactory

class Widget(object):
    """Mix-in class providing some functionality common accross view types
    """


    __implements__ = IWidget

    _prefix = 'field.'
    _data = None

    def __init__(self, context, request):
        self.context = context
        self.request = request
        self.name = self._prefix + context.__name__

    # See Zope.App.Forms.IWidget.IWidget
    propertyNames = []

    def getValue(self, name):
        'See Zope.App.Forms.IWidget.IWidget'
        if name in self.propertyNames:
            return getattr(self, name, None)

    def setPrefix(self, prefix):
        if not prefix.endswith("."):
            prefix += '.'
        self._prefix = prefix
        self.name = prefix + self.context.__name__

    def setData(self, value):
        self._data = value

    def haveData(self):
        raise TypeError("haveData has not been implemented")

    def getData(self):
        raise TypeError("haveData has not been implemented")

    title = property(lambda self: self.context.title)

    required = property(lambda self: self.context.required)

class CustomWidget(object):
    """Custom Widget."""
    __implements__ = IViewFactory

    def __init__(self, widget, **kw):
        self.widget = widget
        self.kw = kw
        
    def __call__(self, context, request):
        instance = self.widget(context, request)
        for item in self.kw.items():
            setattr(instance, item[0], item[1])
        return instance