def renderValue(self, value): # Render the items with subordinate fields and support markup. self.bug_trackers = dict(self.renderItems(value)) self.product = self.context.context # The view must also use GhostWidget for the 'remote_product' field. self.remote_product = copy_field(IProduct['remote_product']) self.remote_product_widget = CustomWidgetFactory(TextWidget) setUpWidget(self, 'remote_product', self.remote_product, IInputWidget, prefix='field', value=self.product.remote_product, context=self.product) # The view must also use GhostWidget for the 'enable_bug_expiration' # field. self.enable_bug_expiration = copy_field( IProduct['enable_bug_expiration']) self.enable_bug_expiration_widget = CustomWidgetFactory(CheckBoxWidget) setUpWidget(self, 'enable_bug_expiration', self.enable_bug_expiration, IInputWidget, prefix='field', value=self.product.enable_bug_expiration, context=self.product) return self.template()
def initialize(self): """See `LaunchpadView.initialize`.""" review_status_field = copy_field( ICodeImport['review_status'], required=False, default=None) self.review_status_widget = CustomWidgetFactory(DropdownWidgetWithAny) setUpWidget(self, 'review_status', review_status_field, IInputWidget) rcs_type_field = copy_field( ICodeImport['rcs_type'], required=False, default=None) self.rcs_type_widget = CustomWidgetFactory(DropdownWidgetWithAny) setUpWidget(self, 'rcs_type', rcs_type_field, IInputWidget) # status should be None if either (a) there were no query arguments # supplied, i.e. the user browsed directly to this page (this is when # hasValidInput returns False) or (b) the user chose 'Any' in the # status widget (this is when hasValidInput returns True but # getInputValue returns None). review_status = None if self.review_status_widget.hasValidInput(): review_status = self.review_status_widget.getInputValue() # Similar for 'type' rcs_type = None if self.rcs_type_widget.hasValidInput(): rcs_type = self.rcs_type_widget.getInputValue() imports = self.context.search( review_status=review_status, rcs_type=rcs_type) self.batchnav = BatchNavigator(imports, self.request)
def __init__(self, field, vocabulary, request): super(LicenseWidget, self).__init__(field, vocabulary, request) # We want to put the license_info widget inside the licences widget's # HTML, for better alignment and JavaScript dynamism. This is # accomplished by ghosting the form's license_info widget (see # lp/registry/browser/product.py and the GhostWidget implementation # below) and creating a custom widget here. It's a pretty simple text # widget so create that now. The fun part is that it's all within the # same form, so posts work correctly. self.license_info = Text(__name__='license_info') self.license_info_widget = CustomWidgetFactory(DescriptionWidget) # The initial value of the license_info widget will be taken from the # field's context when available. This will be the IProduct when # we're editing an existing project, but when we're creating a new # one, it'll be an IProductSet, which does not have license_info. initial_value = getattr(field.context, 'license_info', None) setUpWidget(self, 'license_info', self.license_info, IInputWidget, prefix='field', value=initial_value, context=field.context) self.source_package_release = None # These will get filled in by _categorize(). They are the number of # selected licences in the category. The actual count doesn't matter, # since if it's greater than 0 it will start opened. Note that we # always want the recommended licences to be opened, so we initialize # its value to 1. self.recommended_count = 1 self.more_count = 0 self.deprecated_count = 0 self.special_count = 0
def initialize(self): self.terms = [] for series in self.context.valid_series: distro_version = "%(series_name)s (%(series_version)s)" % { 'series_name': series.displayname, 'series_version': series.version } self.terms.append(SimpleTerm(series, series.name, distro_version)) # If the call-site requested that the widget be displayed initially # without a selection, or we were not able to find a sensible # default series, then add an option to force the user to select # a distroseries. if self._initially_without_selection or self.default_series is None: initial_selection = "Choose your %s version" % ( self.context.distribution.displayname) self.terms.insert( 0, SimpleTerm(None, self.initial_value_without_selection, initial_selection)) field = Choice(__name__='series', title=_("Distro Series"), vocabulary=SimpleVocabulary(self.terms), required=True) setUpWidget(self, 'series', field, IInputWidget) self.series_widget.extra = "onChange='updateSeries(this);'"
def setUpSubWidgets(self): if self._widgets_set_up: return if bool(getFeatureFlag("disclosure.dsp_picker.enabled")): # Replace the default field with a field that uses the better # vocabulary. package_vocab = "DistributionSourcePackage" else: package_vocab = "BinaryAndSourcePackageName" fields = [ Choice(__name__="project", title=u"Project", required=True, vocabulary="Product"), Choice(__name__="distribution", title=u"Distribution", required=True, vocabulary="Distribution", default=getUtility(ILaunchpadCelebrities).ubuntu), Choice(__name__="package", title=u"Package", required=False, vocabulary=package_vocab), ] if not self._read_only: self.distribution_widget = CustomWidgetFactory( LaunchpadDropdownWidget) for field in fields: setUpWidget(self, field.__name__, field, self._sub_widget_interface, prefix=self.name) self._widgets_set_up = True
def __init__(self, field, vocabulary, request): LaunchpadRadioWidget.__init__(self, field, vocabulary, request) # Bug tracker widget. self.bugtracker = Choice( vocabulary="WebBugTracker", __name__='bugtracker') self.bugtracker_widget = CustomWidgetFactory(BugTrackerPickerWidget) setUpWidget( self, 'bugtracker', self.bugtracker, IInputWidget, prefix=self.name, value=field.context.bugtracker, context=field.context) self.bugtracker_widget.onKeyPress = ( "selectWidget('%s.2', event);" % self.name) # Upstream email address field and widget. ## This is to make email address bug trackers appear ## separately from the main bug tracker list. self.upstream_email_address = StrippedTextLine( required=False, constraint=email_validator, __name__='upstream_email_address') self.upstream_email_address_widget = ( CustomWidgetFactory(StrippedTextWidget)) setUpWidget( self, 'upstream_email_address', self.upstream_email_address, IInputWidget, prefix=self.name, value='', context=self.upstream_email_address.context) ## Select the corresponding radio option automatically if ## the user starts typing. if self.upstream_email_address_widget.extra is None: self.upstream_email_address_widget.extra = '' self.upstream_email_address_widget.extra += ( ''' onkeypress="selectWidget('%s.3', event);"\n''' % self.name)
def __init__(self, field, vocabulary, request): RadioWidget.__init__(self, field, vocabulary, request) self.url_widget = CustomWidgetFactory(URIWidget) setUpWidget( self, 'url', BugWatchEditForm['url'], IInputWidget, context=field.context) self.setUpJavascript()
def setUpSubWidgets(self): if self._widgets_set_up: return fields = [ Choice(__name__='product', title=u'Project', required=True, vocabulary=self.getProductVocabulary()), Choice(__name__='distribution', title=u"Distribution", required=True, vocabulary=self.getDistributionVocabulary(), default=getUtility(ILaunchpadCelebrities).ubuntu), Choice(__name__='package', title=u"Package", required=False, vocabulary='BinaryAndSourcePackageName'), ] self.distribution_widget = CustomWidgetFactory(LaunchpadDropdownWidget) for field in fields: setUpWidget(self, field.__name__, field, IInputWidget, prefix=self.name) self._widgets_set_up = True
def __init__(self, field, vocabulary, request): super(LicenseWidget, self).__init__(field, vocabulary, request) # We want to put the license_info widget inside the licences widget's # HTML, for better alignment and JavaScript dynamism. This is # accomplished by ghosting the form's license_info widget (see # lp/registry/browser/product.py and the GhostWidget implementation # below) and creating a custom widget here. It's a pretty simple text # widget so create that now. The fun part is that it's all within the # same form, so posts work correctly. self.license_info = Text(__name__='license_info') self.license_info_widget = CustomWidgetFactory(DescriptionWidget) # The initial value of the license_info widget will be taken from the # field's context when available. This will be the IProduct when # we're editing an existing project, but when we're creating a new # one, it'll be an IProductSet, which does not have license_info. initial_value = getattr(field.context, 'license_info', None) setUpWidget( self, 'license_info', self.license_info, IInputWidget, prefix='field', value=initial_value, context=field.context) self.source_package_release = None # These will get filled in by _categorize(). They are the number of # selected licences in the category. The actual count doesn't matter, # since if it's greater than 0 it will start opened. Note that we # always want the recommended licences to be opened, so we initialize # its value to 1. self.recommended_count = 1 self.more_count = 0 self.deprecated_count = 0 self.special_count = 0
def setUpSubWidgets(self): if self._widgets_set_up: return if bool(getFeatureFlag('disclosure.dsp_picker.enabled')): # Replace the default field with a field that uses the better # vocabulary. package_vocab = 'DistributionSourcePackage' else: package_vocab = 'BinaryAndSourcePackageName' fields = [ Choice(__name__='product', title=u'Project', required=True, vocabulary=self.getProductVocabulary()), Choice(__name__='distribution', title=u"Distribution", required=True, vocabulary=self.getDistributionVocabulary(), default=getUtility(ILaunchpadCelebrities).ubuntu), Choice(__name__='package', title=u"Package", required=False, vocabulary=package_vocab), ] self.distribution_widget = CustomWidgetFactory(LaunchpadDropdownWidget) for field in fields: setUpWidget(self, field.__name__, field, IInputWidget, prefix=self.name) self._widgets_set_up = True
def setUpSubWidgets(self): if self._widgets_set_up: return fields = [ Choice(__name__="person", title=u"Person", required=False, vocabulary="ValidPersonOrTeam"), ] if self._read_only: self.person_widget = CustomWidgetFactory( GitGranteePersonDisplayWidget) else: self.person_widget = CustomWidgetFactory( PersonPickerWidget, # XXX cjwatson 2018-10-18: This is a little unfortunate, but # otherwise there's no spacing at all between the # (deliberately unlabelled) radio button and the text box. style="margin-left: 4px;") for field in fields: setUpWidget(self, field.__name__, field, self._sub_widget_interface, prefix=self.name) self._widgets_set_up = True
def __init__(self, field, vocabulary, request): RadioWidget.__init__(self, field, vocabulary, request) self.url_widget = CustomWidgetFactory(URIWidget) setUpWidget(self, 'url', BugWatchEditForm['url'], IInputWidget, context=field.context) self.setUpJavascript()
def setUpSubWidgets(self): if self._widgets_set_up: return fields = [ Choice( __name__="ppa", title=u"PPA", required=True, vocabulary="PPA"), ] for field in fields: setUpWidget( self, field.__name__, field, IInputWidget, prefix=self.name) self._widgets_set_up = True
def setUpSubWidgets(self): if self._widgets_set_up: return fields = [ Choice( __name__='product', title=u'Project', required=True, vocabulary='Product'), ] for field in fields: setUpWidget( self, field.__name__, field, IInputWidget, prefix=self.name) self._widgets_set_up = True
def setUpSubWidgets(self): if self._widgets_set_up: return fields = [ TextLine(__name__=snap_name, title="%s channel" % snap_name, required=False) for snap_name in self.snap_names ] for field in fields: setUpWidget(self, field.__name__, field, IInputWidget, prefix=self.name) self._widgets_set_up = True
def setUpSubWidgets(self): if self._widgets_set_up: return fields = [ Choice(__name__='product', title=u'Project', required=True, vocabulary='Product'), ] for field in fields: setUpWidget(self, field.__name__, field, IInputWidget, prefix=self.name) self._widgets_set_up = True
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 setUpDisplayWidgets(view, schema, source=None, prefix=None, ignoreStickyValues=False, names=None, context=None, degradeDisplay=False): """Sets up widgets to display field values on a view. See `setUpWidgets` for details on `view`, `schema`, `prefix`, `ignoreStickyValues`, `names`, and `context`. `source`, if specified, is an object from which initial widget values are read. If source is not specified, the view context is used as the source. `degradeDisplay` is a flag that changes the behavior when a user does not have permission to access a field in the names. By default, the function raises Unauthorized. If degradeDisplay is True, the field is removed from the form. Returns a list of names, equal to or a subset of the names that were supposed to be drawn, with uninitialized undrawn fields missing. """ if context is None: context = view.context if source is None: source = view.context res_names = [] for name, field in _fieldlist(names, schema): try: value = field.get(source) except ForbiddenAttribute: raise except AttributeError: value = no_value except Unauthorized: if degradeDisplay: continue else: raise setUpWidget(view, name, field, IDisplayWidget, value, prefix, ignoreStickyValues, context) res_names.append(name) return res_names
def setUpSubWidgets(self): if self._widgets_set_up: return fields = [ GitRepositoryField(__name__="repository", title=u"Git repository", required=False, vocabulary="GitRepository", allow_external=self.allow_external), TextLine(__name__="path", title=u"Git branch", required=False), ] for field in fields: setUpWidget(self, field.__name__, field, IInputWidget, prefix=self.name) self._widgets_set_up = True
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 __init__(self, field, vocabulary, request): # Create the vocabulary and pass that to the radio button # constructor. self.suggestion_vocab = self._generateSuggestionVocab( field.context, vocabulary) LaunchpadRadioWidget.__init__( self, field, self.suggestion_vocab, request) self.other_selection_widget = getMultiAdapter( (field, request), IInputWidget) setUpWidget( self, 'other_selection', field, IInputWidget, prefix=self.name, context=field.context) # If there are suggestions to show explicitly, then we want to select # the 'Other' selection item when the user chooses a non-suggested # value. if self._shouldRenderSuggestions(): self._autoselectOther()
def setUpSubWidgets(self): if self._widgets_set_up: return fields = [ Choice( __name__='product', title=u'Project', required=True, vocabulary=self.getProductVocabulary()), Choice( __name__='distribution', title=u"Distribution", required=True, vocabulary=self.getDistributionVocabulary(), default=getUtility(ILaunchpadCelebrities).ubuntu), Choice( __name__='package', title=u"Package", required=False, vocabulary='BinaryAndSourcePackageName'), ] self.distribution_widget = CustomWidgetFactory( LaunchpadDropdownWidget) for field in fields: setUpWidget( self, field.__name__, field, IInputWidget, prefix=self.name) self._widgets_set_up = True
def renderValue(self, value): # Render the items with subordinate fields and support markup. self.bug_trackers = dict(self.renderItems(value)) self.product = self.context.context # The view must also use GhostWidget for the 'remote_product' field. self.remote_product = copy_field(IProduct['remote_product']) self.remote_product_widget = CustomWidgetFactory(TextWidget) setUpWidget( self, 'remote_product', self.remote_product, IInputWidget, prefix='field', value=self.product.remote_product, context=self.product) # The view must also use GhostWidget for the 'enable_bug_expiration' # field. self.enable_bug_expiration = copy_field( IProduct['enable_bug_expiration']) self.enable_bug_expiration_widget = CustomWidgetFactory( CheckBoxWidget) setUpWidget( self, 'enable_bug_expiration', self.enable_bug_expiration, IInputWidget, prefix='field', value=self.product.enable_bug_expiration, context=self.product) return self.template()
def __init__(self, field, vocabulary, request): LaunchpadRadioWidget.__init__(self, field, vocabulary, request) # Bug tracker widget. self.bugtracker = Choice(vocabulary="WebBugTracker", __name__='bugtracker') self.bugtracker_widget = CustomWidgetFactory(BugTrackerPickerWidget) setUpWidget(self, 'bugtracker', self.bugtracker, IInputWidget, prefix=self.name, value=field.context.bugtracker, context=field.context) self.bugtracker_widget.onKeyPress = ("selectWidget('%s.2', event);" % self.name) # Upstream email address field and widget. ## This is to make email address bug trackers appear ## separately from the main bug tracker list. self.upstream_email_address = StrippedTextLine( required=False, constraint=email_validator, __name__='upstream_email_address') self.upstream_email_address_widget = ( CustomWidgetFactory(StrippedTextWidget)) setUpWidget(self, 'upstream_email_address', self.upstream_email_address, IInputWidget, prefix=self.name, value='', context=self.upstream_email_address.context) ## Select the corresponding radio option automatically if ## the user starts typing. if self.upstream_email_address_widget.extra is None: self.upstream_email_address_widget.extra = '' self.upstream_email_address_widget.extra += ( ''' onkeypress="selectWidget('%s.3', event);"\n''' % self.name)
def __init__(self, field, vocabulary, request): # Create the vocabulary and pass that to the radio button # constructor. self.suggestion_vocab = self._generateSuggestionVocab( field.context, vocabulary) LaunchpadRadioWidget.__init__(self, field, self.suggestion_vocab, request) self.other_selection_widget = getMultiAdapter((field, request), IInputWidget) setUpWidget(self, 'other_selection', field, IInputWidget, prefix=self.name, context=field.context) # If there are suggestions to show explicitly, then we want to select # the 'Other' selection item when the user chooses a non-suggested # value. if self._shouldRenderSuggestions(): self._autoselectOther()
def setUpSubWidgets(self): if self._widgets_set_up: return fields = [ TextLine(__name__="track", title=u"Track", required=False, description=_( "Track defines a series for your software. " "If not specified, the default track ('latest') is " "assumed.")), List( __name__="risks", title=u"Risk", required=False, value_type=Choice(vocabulary="SnapStoreChannel"), description=_("Risks denote the stability of your software.")), TextLine( __name__="branch", title=u"Branch", required=False, description=_( "Branches provide users with an easy way to test bug " "fixes. They are temporary and created on demand. If " "not specified, no branch is used.")), ] self.risks_widget = CustomWidgetFactory(LabeledMultiCheckBoxWidget) for field in fields: setUpWidget(self, field.__name__, field, IInputWidget, prefix=self.name) self.risks_widget.orientation = 'horizontal' self._widgets_set_up = True
def initialize(self): self.terms = [] for series in self.context.valid_series: distro_version = "%(series_name)s (%(series_version)s)" % { 'series_name': series.displayname, 'series_version': series.version } self.terms.append(SimpleTerm(series, series.name, distro_version)) # If the call-site requested that the widget be displayed initially # without a selection, or we were not able to find a sensible # default series, then add an option to force the user to select # a distroseries. if self._initially_without_selection or self.default_series is None: initial_selection = "Choose your %s version" % ( self.context.distribution.displayname) self.terms.insert(0, SimpleTerm( None, self.initial_value_without_selection, initial_selection)) field = Choice(__name__='series', title=_("Distro Series"), vocabulary=SimpleVocabulary(self.terms), required=True) setUpWidget(self, 'series', field, IInputWidget) self.series_widget.extra = "onChange='updateSeries(this);'"
def status(self): setUpWidget(self, 'principal', self.principal_field, IInputWidget) if not self.principal_widget.hasInput(): return u'' try: principal = self.principal_widget.getInputValue() except MissingInputError: return u'' self.principal = principal # Make sure we can use the principal id in a form by base64ing it principal_token = unicode(principal).encode('base64').strip().replace( '=', '_') roles = [role for name, role in getUtilitiesFor(IRole)] roles.sort(lambda x, y: cmp(x.title, y.title)) principal_roles = IPrincipalRoleManager(self.context) self.roles = [] for role in roles: name = principal_token + '.role.'+role.id field = zope.schema.Choice(__name__= name, title=role.title, vocabulary=settings_vocabulary) setUpWidget(self, name, field, IInputWidget, principal_roles.getSetting(role.id, principal)) self.roles.append(getattr(self, name+'_widget')) perms = [perm for name, perm in getUtilitiesFor(IPermission)] perms.sort(lambda x, y: cmp(x.title, y.title)) principal_perms = IPrincipalPermissionManager(self.context) self.permissions = [] for perm in perms: if perm.id == 'zope.Public': continue name = principal_token + '.permission.'+perm.id field = zope.schema.Choice(__name__=name, title=perm.title, vocabulary=settings_vocabulary) setUpWidget(self, name, field, IInputWidget, principal_perms.getSetting(perm.id, principal)) self.permissions.append( getattr(self, name+'_widget')) if 'GRANT_SUBMIT' not in self.request: return u'' for role in roles: name = principal_token + '.role.'+role.id role_widget = getattr(self, name+'_widget') if role_widget.hasInput(): try: setting = role_widget.getInputValue() except MissingInputError: pass else: # Arrgh! if setting is Allow: principal_roles.assignRoleToPrincipal( role.id, principal) elif setting is Deny: principal_roles.removeRoleFromPrincipal( role.id, principal) else: principal_roles.unsetRoleForPrincipal( role.id, principal) for perm in perms: if perm.id == 'zope.Public': continue name = principal_token + '.permission.'+perm.id perm_widget = getattr(self, name+'_widget') if perm_widget.hasInput(): try: setting = perm_widget.getInputValue() except MissingInputError: pass else: # Arrgh! if setting is Allow: principal_perms.grantPermissionToPrincipal( perm.id, principal) elif setting is Deny: principal_perms.denyPermissionToPrincipal( perm.id, principal) else: principal_perms.unsetPermissionForPrincipal( perm.id, principal) return _('Grants updated.')
def setUpEditWidgets(view, schema, source=None, prefix=None, ignoreStickyValues=False, names=None, context=None, degradeInput=False, degradeDisplay=False): """Sets up widgets to collect input on a view. See `setUpWidgets` for details on `view`, `schema`, `prefix`, `ignoreStickyValues`, `names`, and `context`. `source`, if specified, is an object from which initial widget values are read. If source is not specified, the view context is used as the source. `degradeInput` is a flag that changes the behavior when a user does not have permission to edit a field in the names. By default, the function raises Unauthorized. If degradeInput is True, the field is changed to an IDisplayWidget. `degradeDisplay` is a flag that changes the behavior when a user does not have permission to access a field in the names. By default, the function raises Unauthorized. If degradeDisplay is True, the field is removed from the form. Returns a list of names, equal to or a subset of the names that were supposed to be drawn, with uninitialized undrawn fields missing. """ if context is None: context = view.context if source is None: source = view.context security_proxied = isProxy(source, Proxy) res_names = [] for name, field in _fieldlist(names, schema): try: value = field.get(source) except ForbiddenAttribute: raise except AttributeError: value = no_value except Unauthorized: if degradeDisplay: continue else: raise if field.readonly: viewType = IDisplayWidget else: if security_proxied: is_accessor = IMethod.providedBy(field) if is_accessor: set_name = field.writer.__name__ authorized = security.canAccess(source, set_name) else: set_name = name authorized = security.canWrite(source, name) if not authorized: if degradeInput: viewType = IDisplayWidget else: raise Unauthorized(set_name) else: viewType = IInputWidget else: # if object is not security proxied, might be a standard # adapter without a registered checker. If the feature of # paying attention to the users ability to actually set a # field is decided to be a must-have for the form machinery, # then we ought to change this case to have a deprecation # warning. viewType = IInputWidget setUpWidget(view, name, field, viewType, value, prefix, ignoreStickyValues, context) res_names.append(name) return res_names