[Zope3-checkins] CVS: Zope3/src/zope/app/component/browser -
__init__.py:1.1 configure.zcml:1.1 interfacewidget.py:1.1
Stephan Richter
srichter at cosmos.phy.tufts.edu
Sat Mar 13 19:15:19 EST 2004
Update of /cvs-repository/Zope3/src/zope/app/component/browser
In directory cvs.zope.org:/tmp/cvs-serv10948/src/zope/app/component/browser
Added Files:
__init__.py configure.zcml interfacewidget.py
Log Message:
Move zope.app.browser.component to zope.app.component.browser.
=== Added File Zope3/src/zope/app/component/browser/__init__.py ===
#
# This file is necessary to make this directory a package.
=== Added File Zope3/src/zope/app/component/browser/configure.zcml ===
<configure xmlns="http://namespaces.zope.org/zope">
<view
type="zope.publisher.interfaces.browser.IBrowserRequest"
for="zope.app.component.interfaces.IInterfaceField"
provides="zope.app.form.interfaces.IInputWidget"
factory=".interfacewidget.InterfaceWidget"
permission="zope.Public"
/>
<view
type="zope.publisher.interfaces.browser.IBrowserRequest"
for="zope.app.component.interfaces.IInterfaceField"
provides="zope.app.form.interfaces.IDisplayWidget"
factory=".interfacewidget.InterfaceDisplayWidget"
permission="zope.Public"
/>
<view
type="zope.publisher.interfaces.browser.IBrowserRequest"
for="zope.app.component.interfaces.IInterfacesField"
provides="zope.app.form.interfaces.IInputWidget"
factory=".interfacewidget.MultiInterfaceWidget"
permission="zope.Public"
/>
<view
type="zope.publisher.interfaces.browser.IBrowserRequest"
for="zope.app.component.interfaces.IInterfacesField"
provides="zope.app.form.interfaces.IDisplayWidget"
factory=".interfacewidget.MultiInterfaceDisplayWidget"
permission="zope.Public"
/>
</configure>
=== Added File Zope3/src/zope/app/component/browser/interfacewidget.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.
#
##############################################################################
"""Interface widgets
$Id: interfacewidget.py,v 1.1 2004/03/14 00:15:18 srichter Exp $
"""
from zope.interface import Interface, implements
from zope.app.browser.form.widget import BrowserWidget
from zope.app.i18n import ZopeMessageIDFactory as _
from zope.app.form.interfaces import IInputWidget
from zope.app.form.interfaces import WidgetInputError
from zope.app.form.interfaces import ConversionError
from zope.app.form.interfaces import MissingInputError
from zope.app.introspector import interfaceToName
from zope.component import getService
from zope.component.exceptions import ComponentLookupError
from zope.publisher.browser import BrowserView
from xml.sax.saxutils import quoteattr
from zope.app.component.interface import searchInterfaceIds, nameToInterface
from zope.app.component.interface import searchInterface
class InterfaceWidget(BrowserWidget, BrowserView):
implements(IInputWidget)
def _convert(self, value):
if value and value != 'None':
try:
field = self.context
return nameToInterface(field, value)
except ComponentLookupError, e:
raise ConversionError('unknown interface', e)
else:
return None
def __call__(self):
name = self.name
search_name = name + ".search"
search_string = self.request.form.get(search_name, '')
field = self.context
base = field.basetype
include_none = base is None
if base == Interface:
base = None
items = list(searchInterface(self.context, search_string, base=base))
if field.constraint is not None:
items = [iface
for iface in items
if field.constraint(iface)
]
ids = [('%s.%s' %(iface.__module__, iface.__name__))
for iface in items
]
ids.sort()
# Only include None if there is no search string, and include_none
# is True
if include_none and not search_string:
ids = ['None'] + ids
marker = self
if field.default:
selected = field.default
else:
selected = marker
if not self._renderedValueSet():
value = self.request.form.get(self.name, marker) or marker
if value is not marker:
try:
selected = self.getInputValue()
except WidgetInputError, e:
self._error = e
selected = value
else:
selected = self._data
if selected is not marker:
selected = interfaceToName(field.context, selected)
return renderInterfaceSelect(
ids, selected, search_name, search_string, name)
def hidden(self):
'See IBrowserWidget'
field = self.context
try:
iface = self.getInputValue()
except WidgetInputError:
iface = None
return '<input type="hidden" name="%s" value="%s" />' % \
(self.name, interfaceToName(field.context, iface))
# A MultiInterfaceWidget is for use with an InterfacesField,
# which is a tuple of interfaces.
class MultiInterfaceWidget(BrowserWidget, BrowserView):
implements(IInputWidget)
# Names used:
#
# name.i0, name.i1, ... the value of the interfaces
# name.search.i0, ... the search box for that interface
#
def hasInput(self):
name_i = self.name+'.i'
field = self.context
for k,v in self.request.form.iteritems():
if k.startswith(name_i):
if v and (v == 'None' or nameToInterface(field, v)):
return True
return False
def getInputValue(self):
field = self.context
name_i = self.name+'.i'
items_sorted = self.request.form.items()
items_sorted.sort()
# values will be sorted in key order
values = [v
for k,v in items_sorted
if k.startswith(name_i)
if v]
# form input is required, otherwise raise an error
if not values:
raise MissingInputError(self.name, self.title, None) # XXX
# convert input to a tuple of interfaces
try:
values = [nameToInterface(field, value) for value in values]
return tuple(values)
except ComponentLookupError, e:
raise ConversionError('unknown interface', e)
def __call__(self):
'See IBrowserWidget'
field = self.context
form = self.request.form
name = self.name
name_i = name+'.i'
name_search_i = name+'.search.i'
base = field.basetype
include_none = base is None
if base == Interface:
base = None
first_is_blank = False
if self._data is self._data_marker: # no data has been set with
# Widget.setRenderedValue(),
# so use the data in the form
# If a search term is entered, that interface selection remains.
# If an interface is selected, that interface selection remains.
# Remove all others.
# Make sure there is at least one empty selection.
# Make sure there are at least two selections in total.
selections = {} # index:[search, value]
for k,v in form.iteritems():
if k.startswith(name_i):
index = int(k[len(name_i):])
selection = selections.setdefault(index, ['', ''])
selection[1] = v
elif k.startswith(name_search_i):
index = int(k[len(name_search_i):])
selection = selections.setdefault(index, ['', ''])
selection[0] = v.strip()
# remove all of the selections that have no search and no value
for k,(s,v) in selections.items():
if s == v == '':
del selections[k]
if selections:
selections = selections.items()
selections.sort()
# If the first selection really was blank, then remember this
# fact. We'll use it later if we need to add in an extra
# selection box: we can add it at the beginning to preserve
# the order as the user might expect.
if selections[0][0] != 0:
first_is_blank = True
# get just [search, value], and discard the keys
selections = [v for k,v in selections]
# XXX is validation here really needed?
field.validate(tuple([nameToInterface(field, v)
for s,v in selections
if v != '']))
else: # otherwise, use the default
selections = [('', interfaceToName(field.context, interface))
for interface in field.default]
else:
# data has been set with Widget.setRenderedValue()
selections = [('', interfaceToName(field.context, interface))
for interface in self._data]
# If there are no empty values, add one extra empty selection
if not [1 for s,v in selections if v == '']:
# if first_is_blank, put the empty selection at the start
if first_is_blank:
selections = [['', None]] + selections
else:
selections.append(['', None])
# If there is only one value, add another one. We want at least
# two values so that it is obvious this is a multi-value selection.
if len(selections) == 1:
selections.append(['', None])
rendered_selections = []
count = 0
for search, value in selections:
ids = list(searchInterfaceIds(self.context, search, base=base))
ids.sort()
# Only include None if there is no search string, and include_none
# is True
if include_none and not search:
ids = ['None'] + ids
search_name = '%s.search.i%s' % (name, count)
rendered_selections.append(
renderInterfaceSelect(ids, value, search_name,
search, '%s.i%s' % (name, count))
)
count += 1
HTML = (_(u'Use refresh to enter more interfaces') + '<br />' +
'<br />'.join(rendered_selections))
return HTML
def hidden(self):
'See IBrowserWidget'
field = self.context
if self._data is self._data_marker:
try:
data = self.getInputValue()
except WidgetInputError:
data = self.request.form.get(self.name, '')
else:
data = self._data
name = self.name
elements = []
count = 0
for interface in data:
elements.append(
'<input type="hidden" name="%s.i%s" value="%s" />'
% (name, count, interfaceToName(field.context, interface))
)
count += 1
return ''.join(elements)
class InterfaceDisplayWidget(InterfaceWidget):
def __call__(self):
field = self.context
if self._data is self._data_marker:
try:
data = self.getInputValue()
except WidgetInputError:
data = self.request.form.get(self.name, '')
else:
data = self._data
return interfaceToName(field.context, data)
class MultiInterfaceDisplayWidget(MultiInterfaceWidget):
def __call__(self):
field = self.context
if self._data is self._data_marker:
data = self._showData()
else:
data = self._data
return ', '.join([interfaceToName(field.context, interface)
for interface in data])
def renderInterfaceSelect(
interfaces, selected, search_name, search_string, select_name):
"""interfaces is a sequence, all of the other args are strings"""
options = ['<option value="">' + _(u"---select interface---") + \
'</option>']
for interface in interfaces:
if interface == 'None':
options.append('<option value="None"%s>' \
% (interface == selected and ' selected' or '') \
+ _('any-interface', "Anything") + '</option>'
)
else:
options.append('<option value="%s"%s>%s</option>'
% (interface,
interface == selected and ' selected' or '',
interface)
)
search_field = '<input type="text" name="%s" value=%s>' % (
search_name, quoteattr(search_string))
select_field = '<select name="%s">%s</select>' % (
select_name, ''.join(options))
HTML = search_field + select_field
return HTML
More information about the Zope3-Checkins
mailing list