--- a/web/views/schema.py Thu Mar 25 08:30:53 2010 -0700
+++ b/web/views/schema.py Tue Apr 06 12:23:05 2010 +0200
@@ -15,7 +15,7 @@
from yams.buildobjs import DEFAULT_ATTRPERMS
from cubicweb.selectors import (implements, yes, match_user_groups,
- has_related_entities, anonymous_user)
+ has_related_entities, authenticated_user)
from cubicweb.schema import (META_RTYPES, SCHEMA_TYPES, SYSTEM_RTYPES,
WORKFLOW_TYPES, INTERNAL_TYPES)
from cubicweb.schemaviewer import SchemaViewer
@@ -23,7 +23,7 @@
from cubicweb import tags, uilib
from cubicweb.web import action, facet, uicfg
from cubicweb.web.views import TmpFileViewMixin
-from cubicweb.web.views import primary, baseviews, tabs, management, tableview
+from cubicweb.web.views import primary, baseviews, tabs, tableview, iprogress
ALWAYS_SKIP_TYPES = BASE_TYPES | SCHEMA_TYPES
SKIP_TYPES = (ALWAYS_SKIP_TYPES | META_RTYPES | SYSTEM_RTYPES | WORKFLOW_TYPES
@@ -40,23 +40,91 @@
_pvs.tag_subject_of(('*', '%s_permission' % _action, '*'), 'hidden')
_pvs.tag_object_of(('*', '%s_permission' % _action, '*'), 'hidden')
+_pvs.tag_object_of(('Workflow', 'workflow_of', 'CWEType'), 'hidden')
+_pvs.tag_subject_of(('CWEType', 'default_workflow', 'Workflow'), 'hidden')
+
+_pvs.tag_object_of(('*', 'relation_type', 'CWRType'), 'hidden')
+
+
+class SecurityViewMixIn(object):
+ """mixin providing methods to display security information for a entity,
+ relation or relation definition schema
+ """
+
+ def permissions_table(self, erschema, permissions=None):
+ self._cw.add_css('cubicweb.acl.css')
+ w = self.w
+ _ = self._cw._
+ w(u'<table class="schemaInfo">')
+ w(u'<tr><th>%s</th><th>%s</th><th>%s</th></tr>' % (
+ _("permission"), _('granted to groups'), _('rql expressions')))
+ w(u'<table class="schemaInfo">')
+ w(u'<tr><th>%s</th><th>%s</th><th>%s</th></tr>\n' %
+ (_('permission'), _('granted to groups'),
+ _('rql expressions')))
+ for action in erschema.ACTIONS:
+ w(u'<tr><td>%s</td><td>' % _(action))
+ if permissions is None:
+ groups = erschema.get_groups(action)
+ else:
+ groups = permissions[action][1]
+ # XXX get group entity and call it's incontext view
+ groups = [u'<a class="%s" href="%s">%s</a>' % (
+ group, self._cw.build_url('cwgroup/%s' % group), label)
+ for group, label in sorted((_(g), g) for group in groups)]
+ w(u'<br/>'.join(groups))
+ w(u'</td><td>')
+ if permissions is None:
+ rqlexprs = sorted(e.expression for e in erschema.get_rqlexprs(action))
+ else:
+ rqlexprs = permissions[action][1]
+ w(u'<br/>'.join(rqlexprs))
+ w(u'</td></tr>\n')
+ w(u'</table>')
+
+ def grouped_permissions_table(self, rschema):
+ # group relation definitions with identical permissions
+ perms = {}
+ for rdef in rschema.rdefs.itervalues():
+ rdef_perms = []
+ for action in ('read', 'add', 'delete'):
+ groups = sorted(rdef.get_groups(action))
+ exprs = sorted(e.expression for e in rdef.get_rqlexprs(action))
+ rdef_perms.append( (action, (tuple(groups), tuple(exprs))) )
+ rdef_perms = tuple(rdef_perms)
+ if rdef_perms in perms:
+ perms[rdef_perms].append( (rdef.subject, rdef.object) )
+ else:
+ perms[rdef_perms] = [(rdef.subject, rdef.object)]
+ # set layout permissions in a table for each group of relation
+ # definition
+ w = self.w
+ w(u'<div style="margin: 0px 1.5em">')
+ tmpl = u'[<strong>%s</strong> %s <strong>%s</strong>]'
+ for perm, rdefs in perms:
+ w(u'<div>%s</div>' % u', '.join(
+ tmpl % (_(s.type), _(rschema.type), _(o.type)) for s, o in rdefs))
+ # accessing rdef from previous loop by design: only used to get
+ # ACTIONS
+ self.permissions_table(rdef, dict(perm))
+ w(u'</div>')
+
+
# global schema view ###########################################################
class SchemaView(tabs.TabsMixin, StartupView):
__regid__ = 'schema'
title = _('instance schema')
- tabs = [_('schema-text'), _('schema-image'), _('schema-security')]
- default_tab = 'schema-text'
+ tabs = [_('schema-description'), _('schema-image'), _('schema-security')]
+ default_tab = 'schema-description'
def call(self):
"""display schema information"""
- self._cw.add_js('cubicweb.ajax.js')
- self._cw.add_css(('cubicweb.schema.css','cubicweb.acl.css'))
self.w(u'<h1>%s</h1>' % _('Schema of the data model'))
self.render_tabs(self.tabs, self.default_tab)
-class SchemaTabImageView(StartupView):
+class SchemaImageTab(StartupView):
__regid__ = 'schema-image'
def call(self):
@@ -69,8 +137,8 @@
self._cw._("graphical representation of the instance'schema")))
-class SchemaTabTextView(StartupView):
- __regid__ = 'schema-text'
+class SchemaDescriptionTab(StartupView):
+ __regid__ = 'schema-description'
def call(self):
rset = self._cw.execute('Any X ORDERBY N WHERE X is CWEType, X name N, '
@@ -84,7 +152,7 @@
(owl_downloadurl, self._cw._(u'Download schema as OWL')))
-class SchemaPermissionsView(StartupView, management.SecurityViewMixIn):
+class SchemaPermissionsTab(SecurityViewMixIn, StartupView):
__regid__ = 'schema-security'
__select__ = StartupView.__select__ & match_user_groups('managers')
@@ -127,16 +195,19 @@
self.w(u'</div>')
def has_non_default_perms(self, rdef):
- for access_type in rdef.ACTIONS:
+ """return true if the given *attribute* relation definition has custom
+ permission
+ """
+ for action in rdef.ACTIONS:
def_rqlexprs = []
def_groups = []
- for perm in DEFAULT_ATTRPERMS[access_type]:
+ for perm in DEFAULT_ATTRPERMS[action]:
if not isinstance(perm, basestring):
def_rqlexprs.append(perm.expression)
else:
def_groups.append(perm)
- rqlexprs = [rql.expression for rql in rdef.get_rqlexprs(access_type)]
- groups = rdef.get_groups(access_type)
+ rqlexprs = [rql.expression for rql in rdef.get_rqlexprs(action)]
+ groups = rdef.get_groups(action)
if groups != frozenset(def_groups) or \
frozenset(rqlexprs) != frozenset(def_rqlexprs):
return True
@@ -154,7 +225,7 @@
url, self._cw.external_resource('UP_ICON'), _('up')))
self.w(u'</h3>')
self.w(u'<div style="margin: 0px 1.5em">')
- self.schema_definition(eschema)
+ self.permissions_table(eschema)
# display entity attributes only if they have some permissions modified
modified_attrs = []
for attr, etype in eschema.attribute_definitions():
@@ -168,7 +239,7 @@
for rdef in modified_attrs:
attrtype = str(rdef.rtype)
self.w(u'<h4 class="schema">%s (%s)</h4> ' % (attrtype, _(attrtype)))
- self.schema_definition(rdef)
+ self.permissions_table(rdef)
self.w(u'</div>')
def display_relations(self, relations):
@@ -182,105 +253,23 @@
self.w(u'<a href="%s#schema_security"><img src="%s" alt="%s"/></a>' % (
url, self._cw.external_resource('UP_ICON'), _('up')))
self.w(u'</h3>')
- self.w(u'<div style="margin: 0px 1.5em">')
- for rdef in rschema.rdefs.itervalues():
- self.w(u'<h4 class="schema">%s %s %s</h4>' % (
- rdef.subject, rschema, rdef.object))
- self.schema_definition(rdef)
- self.w(u'</div>')
-
-
-# CWAttribute / CWRelation #####################################################
-
-class CWRDEFPrimaryView(primary.PrimaryView):
- __select__ = implements('CWAttribute', 'CWRelation')
- cache_max_age = 60*60*2 # stawy in http cache for 2 hours by default
-
- def render_entity_title(self, entity):
- self.w(u'<h1><span class="etype">%s</span> %s</h1>'
- % (entity.dc_type().capitalize(),
- xml_escape(entity.dc_long_title())))
-
-
-class CWAttributeConstraints(EntityView):
- __regid__ = 'attr_constraints'
- __select__ = implements('CWAttribute')
-
- def cell_call(self, row, col):
- entity = self.cw_rset.get_entity(row, col)
- rschema = self._cw.vreg.schema.rschema(entity.rtype.name)
- rdef = rschema.rdefs[(entity.stype.name, entity.otype.name)]
- constraints = [xml_escape(str(c)) for c in getattr(rdef, 'constraints')]
- self.w(u', '.join(constraints))
-
+ self.grouped_permissions_table(rschema)
-class CWAttributeCellView(tableview.CellView):
- """display attribute name only in a cell view, link to
- cwattribute primary view"""
- __select__ = tableview.CellView.__select__ & implements('CWAttribute')
-
- def cell_call(self, row, col, cellvid=None):
- """display attribute name only in a cell view, link to
- cwattribute primary view"""
- etype, val = self.cw_rset.description[row][col], self.cw_rset[row][col]
- if val is not None and not self._cw.vreg.schema.eschema(etype).final:
- e = self.cw_rset.get_entity(row, col)
- if cellvid is not None and cellvid != 'incontext':
- self.wview(cellvid, e.as_rset(), 'null')
- else:
- desc = uilib.cut(e.dc_description(), 50)
- self.w(u'<a href="%s" title="%s">%s' %
- (xml_escape(e.absolute_url()) ,xml_escape(desc),
- self.cell_content(e)))
- self.w(u'</a>')
- elif val is None:
- # This is usually caused by a left outer join and in that case,
- # regular views will most certainly fail if they don't have
- # a real eid
- self.wview('final', self.cw_rset, row=row, col=col)
- else:
- self.wview(cellvid or 'final', self.cw_rset, 'null', row=row, col=col)
-
- def cell_content(self, entity):
- return entity.relation_type[0].name
-
-
-class CWRelationCellView(CWAttributeCellView):
- """display relation name and its translation only in a cell view, link to
- cwrelation primary view"""
- __select__ = tableview.CellView.__select__ & implements('CWRelation')
-
- def cell_content(self, entity):
- return u'%s (%s)' % (entity.relation_type[0].name,
- self._cw._(entity.relation_type[0].name))
# CWEType ######################################################################
-class CWETypeOneLineView(baseviews.OneLineView):
- __select__ = implements('CWEType')
-
- def cell_call(self, row, col, **kwargs):
- entity = self.cw_rset.get_entity(row, col)
- final = entity.final
- if final:
- self.w(u'<em class="finalentity">')
- super(CWETypeOneLineView, self).cell_call(row, col, **kwargs)
- if final:
- self.w(u'</em>')
-
+# register msgid generated in entity relations tables
+_('i18ncard_1'), _('i18ncard_?'), _('i18ncard_+'), _('i18ncard_*')
class CWETypePrimaryView(tabs.TabbedPrimaryView):
__select__ = implements('CWEType')
- tabs = [_('cwetype-text-tab'), _('cwetype-box-tab'), _('cwetype-workflow-tab'),
- _('cwetype-views-tab'), _('cwetype-perm-tab')]
- default_tab = 'cwetype-text-tab'
+ tabs = [_('cwetype-description'), _('cwetype-box'), _('cwetype-workflow'),
+ _('cwetype-views'), _('cwetype-permissions')]
+ default_tab = 'cwetype-description'
-# register generated msgid
-_('i18ncard_1'), _('i18ncard_?'), _('i18ncard_+'), _('i18ncard_*')
-
-class CWETypeTextTab(tabs.PrimaryTab):
- __regid__ = 'cwetype-text-tab'
+class CWETypeDescriptionTab(tabs.PrimaryTab):
+ __regid__ = 'cwetype-description'
__select__ = tabs.PrimaryTab.__select__ & implements('CWEType')
def render_entity_attributes(self, entity, siderelations=None):
@@ -292,17 +281,17 @@
xml_escape(self._cw._('graphical schema for %s') % entity.name)))
# entity schema attributes
self.w(u'<h2>%s</h2>' % _('Attributes'))
- rset = self._cw.execute('Any A,F,DE,D,C, I,J,A '
- 'ORDERBY AA WHERE A is CWAttribute, '
- 'A ordernum AA, A defaultval D, '
- 'A description DE, A cardinality C, '
- 'A fulltextindexed I, A internationalizable J, '
- 'A relation_type R, R name N, '
- 'A to_entity O, O name F, '
- 'A from_entity S, S eid %(x)s',
- {'x': entity.eid})
+ rset = self._cw.execute(
+ 'Any A,F,DE,D,C, I,J,A ORDERBY AA WHERE A is CWAttribute, '
+ 'A ordernum AA, A defaultval D, A description DE, A cardinality C, '
+ 'A fulltextindexed I, A internationalizable J, '
+ 'A relation_type R, R name N, A to_entity O, O name F, '
+ 'A from_entity S, S eid %(x)s',
+ {'x': entity.eid})
self.wview('table', rset, 'null',
- cellvids={4: 'attr_cardinality', 7: 'attr_constraints'},
+ cellvids={0: 'rdef-name-cell',
+ 4: 'etype-attr-cardinality-cell',
+ 7: 'rdef-constraints-cell'},
headers=(_(u'name'), _(u'type'), _(u'description'),
_(u'default value'), _(u'required'),
_(u'fulltext indexed'), _(u'internationalizable'),
@@ -311,7 +300,7 @@
# entity schema relations
self.w(u'<h2>%s</h2>' % _('Relations'))
rset = self._cw.execute(
- 'Any A, TT, "i18ncard_"+SUBSTRING(C, 1, 1),K,D,A,RN,TTN ORDERBY RN '
+ 'Any A, TT, "i18ncard_"+SUBSTRING(C, 1, 1),K,D,A,A,RN,TTN ORDERBY RN '
'WHERE A is CWRelation, A description D, A composite K, '
'A relation_type R, R name RN, A to_entity TT, TT name TTN, '
'A cardinality C, A from_entity S, S eid %(x)s',
@@ -319,14 +308,16 @@
if rset:
self.w(u'<h5>%s %s</h5>' % (entity.name, _('is subject of:')))
self.wview('table', rset, 'null',
- cellvids={2: 'entity_relation_cardinality',},
+ cellvids={0: 'rdef-name-cell',
+ 2: 'etype-rel-cardinality-cell',
+ 5: 'rdef-constraints-cell'},
headers=(_(u'name'), _(u'object type'), _(u'cardinality'),
_(u'composite'), _(u'description'),
- _(u'relation direction')),
+ _(u'constraints'), _(u'relation direction')),
displaycols=range(5), mainindex=0)
self.w(u'<br/>')
rset = self._cw.execute(
- 'Any A, TT, "i18ncard_"+SUBSTRING(C, 2, 1),K,D,A,RN,TTN ORDERBY RN '
+ 'Any A, TT, "i18ncard_"+SUBSTRING(C, 2, 1),K,D,A,A,RN,TTN ORDERBY RN '
'WHERE A is CWRelation, A description D, A composite K, '
'A relation_type R, R name RN, A from_entity TT, TT name TTN, '
'A cardinality C, A to_entity O, O eid %(x)s',
@@ -334,42 +325,67 @@
if rset:
self.w(u'<h5>%s %s</h5>' % (entity.name, _('is object of:')))
self.wview('table', rset, 'null',
- cellvids={2: 'entity_relation_cardinality',},
+ cellvids={0: 'rdef-object-name-cell',
+ 2: 'etype-rel-cardinality-cell',
+ 5: 'rdef-constraints-cell'},
headers=(_(u'name'), _(u'subject type'), _(u'cardinality'),
_(u'composite'), _(u'description'),
- _(u'relation direction')),
+ _(u'constraints'), _(u'relation direction')),
displaycols=range(5), mainindex=0)
-class CWETypePermTab(EntityView, management.SecurityViewMixIn):
- __regid__ = 'cwetype-perm-tab'
- __select__ = EntityView.__select__ & implements('CWEType') & ~anonymous_user()
+class CWETypeAttributeCardinalityCell(baseviews.FinalView):
+ __regid__ = 'etype-attr-cardinality-cell'
+
+ def cell_call(self, row, col):
+ if self.cw_rset.rows[row][col][0] == '1':
+ self.w(self._cw._(u'required'))
+
+
+class CWETypeRelationCardinalityCell(baseviews.FinalView):
+ __regid__ = 'etype-rel-cardinality-cell'
+
+ def cell_call(self, row, col):
+ self.w(self._cw._(self.cw_rset.rows[row][col]))
+
+
+class CWETypeBoxTab(EntityView):
+ __regid__ = 'cwetype-box'
+ __select__ = implements('CWEType')
+
+ def cell_call(self, row, col):
+ viewer = SchemaViewer(self._cw)
+ entity = self.cw_rset.get_entity(row, col)
+ eschema = self._cw.vreg.schema.eschema(entity.name)
+ layout = viewer.visit_entityschema(eschema)
+ self.w(uilib.ureport_as_html(layout))
+ self.w(u'<br class="clear"/>')
+
+
+class CWETypePermTab(SecurityViewMixIn, EntityView):
+ __regid__ = 'cwetype-permissions'
+ __select__ = implements('CWEType') & authenticated_user()
def cell_call(self, row, col):
self._cw.add_css('cubicweb.acl.css')
entity = self.cw_rset.get_entity(row, col)
eschema = self._cw.vreg.schema.eschema(entity.name)
- self.w(u'<a id="%s" href="cwetype/%s">' % (eschema.type, eschema.type))
- self.w(u'<h3 class="schema">%s (%s) ' % (eschema.type, _(eschema.type)))
- self.w(u'</h3></a>')
self.w(u'<div style="margin: 0px 1.5em">')
- self.schema_definition(eschema)
- # display entity attributes only if they have some permissions modified
- modified_attrs = []
+ self.permissions_table(eschema)
self.w(u'<h4>%s</h4>' % _('attributes permissions:').capitalize())
for attr, etype in eschema.attribute_definitions():
if attr not in META_RTYPES:
rdef = eschema.rdef(attr)
attrtype = str(rdef.rtype)
self.w(u'<h4 class="schema">%s (%s)</h4> ' % (attrtype, _(attrtype)))
- self.schema_definition(rdef, link=False)
+ self.permissions_table(rdef)
self.w(u'</div>')
class CWETypeWorkflowTab(EntityView):
- __regid__ = 'cwetype-workflow-tab'
- __select__ = (EntityView.__select__ & implements('CWEType') &
- has_related_entities('workflow_of', 'object'))
+ __regid__ = 'cwetype-workflow'
+ __select__ = (implements('CWEType')
+ & has_related_entities('workflow_of', 'object'))
def cell_call(self, row, col):
entity = self.cw_rset.get_entity(row, col)
@@ -396,21 +412,8 @@
wf.absolute_url(), self._cw._('more info about this workflow')))
-class CWETypeBoxTab(EntityView):
- __regid__ = 'cwetype-box-tab'
- __select__ = EntityView.__select__ & implements('CWEType')
-
- def cell_call(self, row, col):
- viewer = SchemaViewer(self._cw)
- entity = self.cw_rset.get_entity(row, col)
- eschema = self._cw.vreg.schema.eschema(entity.name)
- layout = viewer.visit_entityschema(eschema)
- self.w(uilib.ureport_as_html(layout))
- self.w(u'<br class="clear"/>')
-
-
class CWETypeViewsTab(EntityView):
- __regid__ = 'cwetype-views-tab'
+ __regid__ = 'cwetype-views'
__select__ = EntityView.__select__ & implements('CWEType')
def cell_call(self, row, col):
@@ -427,23 +430,117 @@
if v.category != 'startupview']
+class CWETypeOneLineView(baseviews.OneLineView):
+ __select__ = implements('CWEType')
+
+ def cell_call(self, row, col, **kwargs):
+ entity = self.cw_rset.get_entity(row, col)
+ if entity.final:
+ self.w(u'<em class="finalentity">')
+ super(CWETypeOneLineView, self).cell_call(row, col, **kwargs)
+ if entity.final:
+ self.w(u'</em>')
+
+
# CWRType ######################################################################
-class CWRTypeSchemaView(primary.PrimaryView):
+class CWRTypePrimaryView(tabs.TabbedPrimaryView):
__select__ = implements('CWRType')
- title = _('in memory relation schema')
- main_related_section = False
+ tabs = [_('cwrtype-description'), _('cwrtype-permissions')]
+ default_tab = 'cwrtype-description'
+
- def render_entity_attributes(self, entity):
- super(CWRTypeSchemaView, self).render_entity_attributes(entity)
+class CWRTypeDescriptionTab(tabs.PrimaryTab):
+ __regid__ = 'cwrtype-description'
+ __select__ = implements('CWRType')
+
+ def render_entity_attributes(self, entity, siderelations=None):
+ self.w(u'<div>%s</div>' % xml_escape(entity.description or u''))
rschema = self._cw.vreg.schema.rschema(entity.name)
- viewer = SchemaViewer(self._cw)
- layout = viewer.visit_relationschema(rschema, title=False)
- self.w(uilib.ureport_as_html(layout))
if not rschema.final:
msg = self._cw._('graphical schema for %s') % entity.name
self.w(tags.img(src=entity.absolute_url(vid='schemagraph'),
alt=msg))
+ rset = self._cw.execute('Any R,ST,OT,C,CC,R WHERE R is CWRelation, '
+ 'R relation_type RT, RT eid %(x)s, '
+ 'R from_type ST, R to_type OT, '
+ 'R cardinality C, R composite CC',
+ {'x': entity.eid})
+ self.wview('table', rset, 'null',
+ headers=(_(u'relation'), _(u'subject'), _(u'object'),
+ _(u'cardinality'), _(u'composite'),
+ _(u'constraints')),
+ cellvids={5: 'rdef-constraints-cell'})
+
+
+class CWRTypePermTab(SecurityViewMixIn, EntityView):
+ __regid__ = 'cwrtype-permissions'
+ __select__ = implements('CWRType') & authenticated_user()
+
+ def cell_call(self, row, col):
+ self._cw.add_css('cubicweb.acl.css')
+ entity = self.cw_rset.get_entity(row, col)
+ rschema = self._cw.vreg.schema.rschema(entity.name)
+ self.grouped_permissions_table(rschema)
+
+
+# CWAttribute / CWRelation #####################################################
+
+class CWRDEFPrimaryView(tabs.TabbedPrimaryView):
+ __select__ = implements('CWRelation', 'CWAttribute')
+ tabs = [_('cwrdef-description'), _('cwrdef-permissions')]
+ default_tab = 'cwrdef-description'
+
+class CWRDEFDescriptionTab(tabs.PrimaryTab):
+ __regid__ = 'cwrdef-description'
+ __select__ = implements('CWRelation', 'CWAttribute')
+
+class CWRDEFPermTab(SecurityViewMixIn, EntityView):
+ __regid__ = 'cwrdef-permissions'
+ __select__ = implements('CWRelation', 'CWAttribute') & authenticated_user()
+
+ def cell_call(self, row, col):
+ entity = self.cw_rset.get_entity(row, col)
+ rschema = self._cw.vreg.schema.rschema(entity.rtype.name)
+ rdef = rschema.rdefs[(entity.stype.name, entity.otype.name)]
+ self.display_permission(rdef)
+
+
+class CWRDEFNameView(tableview.CellView):
+ """display relation name and its translation only in a cell view, link to
+ relation definition's primary view (for use in entity type relations table
+ for instance)
+ """
+ __regid__ = 'rdef-name-cell'
+ __select__ = implements('CWRelation', 'CWAttribute')
+
+ def cell_content(self, entity):
+ rtype = entity.relation_type[0].name
+ # XXX use contect entity + pgettext
+ return u'%s (%s)' % (rtype, self._cw._(rtype))
+
+class CWRDEFObjectNameView(tableview.CellView):
+ """same as CWRDEFNameView but when the context is the object entity
+ """
+ __regid__ = 'rdef-object-name-cell'
+ __select__ = implements('CWRelation', 'CWAttribute')
+
+ def cell_content(self, entity):
+ rtype = entity.relation_type[0].name
+ # XXX use contect entity + pgettext
+ return u'%s (%s)' % (rtype, self._cw.__(rtype + '_object'))
+
+class CWRDEFConstraintsCell(EntityView):
+ __regid__ = 'rdef-constraints-cell'
+ __select__ = implements('CWAttribute', 'CWRelation')
+
+ def cell_call(self, row, col):
+ entity = self.cw_rset.get_entity(row, col)
+ rschema = self._cw.vreg.schema.rschema(entity.rtype.name)
+ rdef = rschema.rdefs[(entity.stype.name, entity.otype.name)]
+ constraints = [xml_escape(str(c)) for c in getattr(rdef, 'constraints')]
+ self.w(u', '.join(constraints))
+
# schema images ###############################################################
@@ -509,25 +606,6 @@
s2d.schema2dot(outputfile=tmpfile, visitor=visitor)
-# final views #################################################################
-
-class CardinalityRequiredCellView(baseviews.FinalView):
- __regid__ = 'attr_cardinality'
-
- def cell_call(self, row, col):
- value = self.cw_rset.rows[row][col]
- if value is not None and value[0] == '1':
- self.w(self._cw._(u'required'))
-
-class I18NCardinalityCellView(baseviews.FinalView):
- __regid__ = 'entity_relation_cardinality'
-
- def cell_call(self, row, col):
- value = self.cw_rset.rows[row][col]
- if value is not None:
- self.w(self._cw._(value))
-
-
# misc: facets, actions ########################################################
class CWFinalFacet(facet.AttributeFacet):