1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
# Copyright 2009 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Widgets related to IProjectGroup."""
__metaclass__ = type
from textwrap import dedent
from zope.app.form import InputWidget
from zope.app.form.browser.widget import (
BrowserWidget,
renderElement,
)
from zope.app.form.interfaces import (
ConversionError,
IInputWidget,
InputErrors,
)
from zope.app.form.utility import setUpWidget
from zope.interface import implements
from zope.schema import Choice
from lp.app.errors import UnexpectedFormData
from lp.app.validators import LaunchpadValidationError
from lp.services.webapp.interfaces import IAlwaysSubmittedWidget
class ProjectScopeWidget(BrowserWidget, InputWidget):
"""Widget for selecting a scope. Either 'All projects' or only one."""
implements(IAlwaysSubmittedWidget, IInputWidget)
default_option = "all"
_error = None
def __init__(self, field, vocabulary, request):
super(ProjectScopeWidget, self).__init__(field, request)
# We copy the title, description and vocabulary from the main
# field since it determines the valid target types.
# XXX flacoste 2007-02-21 bug=86861: We must
# use field.vocabularyName instead of the vocabulary parameter
# otherwise VocabularyPickerWidget will fail.
target_field = Choice(
__name__='target', title=field.title,
description=field.description, vocabulary=field.vocabularyName,
required=True)
setUpWidget(
self, target_field.__name__, target_field, IInputWidget,
prefix=self.name)
self.setUpOptions()
def setUpOptions(self):
"""Set up options to be rendered."""
self.options = {}
for option in ['all', 'project']:
attributes = dict(
type='radio', name=self.name, value=option,
id='%s.option.%s' % (self.name, option))
if self.request.form_ng.getOne(
self.name, self.default_option) == option:
attributes['checked'] = 'checked'
if option == 'project':
attributes['onclick'] = (
"document.getElementById('field.scope.target').focus();")
self.options[option] = renderElement('input', **attributes)
self.target_widget.onKeyPress = (
"selectWidget('%s.option.project', event)" % self.name)
def hasInput(self):
"""See zope.app.form.interfaces.IInputWidget."""
return self.name in self.request.form
def hasValidInput(self):
"""See zope.app.form.interfaces.IInputWidget."""
try:
self.getInputValue()
return self.hasInput()
except (InputErrors, UnexpectedFormData, LaunchpadValidationError):
return False
def getInputValue(self):
"""See zope.app.form.interfaces.IInputWidget."""
scope = self.request.form_ng.getOne(self.name)
if scope == 'all':
return None
elif scope == 'project':
if not self.request.form_ng.getOne(self.target_widget.name):
self._error = LaunchpadValidationError(
'Please enter a project name')
raise self._error
try:
return self.target_widget.getInputValue()
except ConversionError:
entered_name = self.request.form_ng.getOne(
"%s.target" % self.name)
self._error = LaunchpadValidationError(
"There is no project named '%s' registered in"
" Launchpad" % entered_name)
raise self._error
elif self.required:
raise UnexpectedFormData("No valid option was selected.")
else:
return None
def getScope(self):
"""Return the selected scope or None if it isn't selected."""
return self.request.form_ng.getOne(self.name)
def setRenderedValue(self, value):
"""See IWidget."""
if value is None:
self.default_option = 'all'
self.target_widget.setRenderedValue(None)
else:
self.default_option = 'project'
self.target_widget.setRenderedValue(value)
self.setUpOptions()
def __call__(self):
"""See zope.app.form.interfaces.IBrowserWidget."""
return "\n".join([
self.renderScopeOptions(),
self.target_widget()])
def renderScopeOptions(self):
"""Render the HTML for the scope radio widgets."""
return dedent('''\
<label>
%(all)s All projects
</label>
<label>
%(project)s One project:
</label>
''' % self.options)
def error(self):
"""See zope.app.form.browser.interfaces.IBrowserWidget"""
if self._error:
return self._error.doc()
else:
return u""
|