[schema view] the final touch. Things are getting nicely displayed, and code clean
--- a/entities/schemaobjs.py Tue Apr 13 19:43:51 2010 +0200
+++ b/entities/schemaobjs.py Wed Apr 14 08:49:23 2010 +0200
@@ -122,6 +122,9 @@
def otype(self):
return self.to_entity[0]
+ def yams_schema(self):
+ rschema = self._cw.vreg.schema.rschema(self.rtype.name)
+ return rschema.rdefs[(self.stype.name, self.otype.name)]
class CWAttribute(CWRelation):
__regid__ = 'CWAttribute'
--- a/i18n/en.po Tue Apr 13 19:43:51 2010 +0200
+++ b/i18n/en.po Wed Apr 14 08:49:23 2010 +0200
@@ -194,7 +194,7 @@
msgid "Any"
msgstr ""
-msgid "Attributes"
+msgid "Attributes permissions:"
msgstr ""
msgid "Attributes with non default permissions:"
@@ -510,9 +510,15 @@
msgid "No result matching query"
msgstr ""
+msgid "Non exhaustive list of views that may apply to entities of this type"
+msgstr ""
+
msgid "OR"
msgstr ""
+msgid "Parent classes:"
+msgstr ""
+
msgid "Password"
msgstr "Password"
@@ -592,6 +598,9 @@
msgid "String_plural"
msgstr "Strings"
+msgid "Sub-classes:"
+msgstr ""
+
msgid "SubWorkflowExitPoint"
msgstr "Subworkflow exit-point"
@@ -687,6 +696,9 @@
msgid "This WorkflowTransition"
msgstr "This workflow-transition"
+msgid "This entity type permissions:"
+msgstr ""
+
msgid "Time"
msgstr "Time"
@@ -788,9 +800,6 @@
msgid "abstract base class for transitions"
msgstr ""
-msgid "access type"
-msgstr ""
-
msgid "action(s) on this selection"
msgstr ""
@@ -1210,9 +1219,6 @@
msgid "attribute"
msgstr ""
-msgid "attributes permissions:"
-msgstr ""
-
msgid "august"
msgstr ""
@@ -1575,6 +1581,9 @@
msgid "constraints applying on this relation"
msgstr ""
+msgid "content type"
+msgstr ""
+
msgid "contentnavigation"
msgstr "contextual components"
@@ -1833,12 +1842,6 @@
msgid "cwgroup-permissions"
msgstr "permissions"
-msgid "cwrdef-description"
-msgstr "description"
-
-msgid "cwrdef-permissions"
-msgstr "permissions"
-
msgid "cwrtype-description"
msgstr "description"
@@ -2297,6 +2300,10 @@
msgid "facets_in_state-facet_description"
msgstr ""
+#, python-format
+msgid "failed to uniquify path (%s, %s)"
+msgstr ""
+
msgid "february"
msgstr ""
@@ -2399,9 +2406,6 @@
msgid "full text or RQL query"
msgstr ""
-msgid "fulltext indexed"
-msgstr ""
-
msgid "fulltext_container"
msgstr "fulltext container"
@@ -3017,6 +3021,9 @@
msgid "opened web sessions"
msgstr ""
+msgid "options"
+msgstr ""
+
msgid "order"
msgstr ""
@@ -3149,6 +3156,12 @@
msgid "project"
msgstr ""
+msgid "rdef-description"
+msgstr "description"
+
+msgid "rdef-permissions"
+msgstr "permissions"
+
msgid "read"
msgstr ""
@@ -3200,9 +3213,6 @@
msgid "relation add"
msgstr ""
-msgid "relation direction"
-msgstr ""
-
msgid "relation removal"
msgstr ""
@@ -3311,12 +3321,15 @@
msgid "schema's permissions definitions"
msgstr ""
-msgid "schema-description"
-msgstr "entity and relation types"
+msgid "schema-entity-types"
+msgstr ""
msgid "schema-image"
msgstr "image"
+msgid "schema-relation-types"
+msgstr ""
+
msgid "schema-security"
msgstr "permissions"
@@ -3968,15 +3981,18 @@
msgid "view history"
msgstr ""
+msgid "view identifier"
+msgstr ""
+
+msgid "view title"
+msgstr ""
+
msgid "view workflow"
msgstr ""
msgid "view_index"
msgstr "index"
-msgid "views"
-msgstr ""
-
msgid "visible"
msgstr ""
@@ -4074,3 +4090,6 @@
msgid "you should probably delete that property"
msgstr ""
+
+#~ msgid "schema-description"
+#~ msgstr "entity and relation types"
--- a/i18n/es.po Tue Apr 13 19:43:51 2010 +0200
+++ b/i18n/es.po Wed Apr 14 08:49:23 2010 +0200
@@ -202,8 +202,8 @@
msgid "Any"
msgstr "Cualquiera"
-msgid "Attributes"
-msgstr "Atributos"
+msgid "Attributes permissions:"
+msgstr ""
msgid "Attributes with non default permissions:"
msgstr ""
@@ -518,9 +518,15 @@
msgid "No result matching query"
msgstr "Ningún resultado corresponde a su búsqueda"
+msgid "Non exhaustive list of views that may apply to entities of this type"
+msgstr ""
+
msgid "OR"
msgstr "O"
+msgid "Parent classes:"
+msgstr ""
+
msgid "Password"
msgstr "Contraseña"
@@ -600,6 +606,9 @@
msgid "String_plural"
msgstr "Cadenas de caracteres"
+msgid "Sub-classes:"
+msgstr ""
+
msgid "SubWorkflowExitPoint"
msgstr ""
@@ -695,6 +704,9 @@
msgid "This WorkflowTransition"
msgstr ""
+msgid "This entity type permissions:"
+msgstr ""
+
msgid "Time"
msgstr "Hora"
@@ -811,9 +823,6 @@
msgid "abstract base class for transitions"
msgstr ""
-msgid "access type"
-msgstr "Tipo de Acceso"
-
msgid "action(s) on this selection"
msgstr "acción(es) en esta selección"
@@ -1235,9 +1244,6 @@
msgid "attribute"
msgstr "Atributo"
-msgid "attributes permissions:"
-msgstr ""
-
msgid "august"
msgstr "Agosto"
@@ -1606,6 +1612,9 @@
msgid "constraints applying on this relation"
msgstr "Restricciones que se aplican a esta relación"
+msgid "content type"
+msgstr ""
+
msgid "contentnavigation"
msgstr "Componentes contextuales"
@@ -1874,12 +1883,6 @@
msgid "cwgroup-permissions"
msgstr ""
-msgid "cwrdef-description"
-msgstr ""
-
-msgid "cwrdef-permissions"
-msgstr ""
-
msgid "cwrtype-description"
msgstr ""
@@ -2347,6 +2350,10 @@
msgid "facets_in_state-facet_description"
msgstr "faceta en el estado"
+#, python-format
+msgid "failed to uniquify path (%s, %s)"
+msgstr ""
+
msgid "february"
msgstr "Febrero"
@@ -2449,9 +2456,6 @@
msgid "full text or RQL query"
msgstr "Texto de búsqueda o demanda RQL"
-msgid "fulltext indexed"
-msgstr ""
-
msgid "fulltext_container"
msgstr "Contenedor de texto indexado"
@@ -3091,6 +3095,9 @@
msgid "opened web sessions"
msgstr ""
+msgid "options"
+msgstr ""
+
msgid "order"
msgstr "orden"
@@ -3222,6 +3229,12 @@
msgid "project"
msgstr "Proyecto"
+msgid "rdef-description"
+msgstr ""
+
+msgid "rdef-permissions"
+msgstr ""
+
msgid "read"
msgstr "Lectura"
@@ -3273,9 +3286,6 @@
msgid "relation add"
msgstr ""
-msgid "relation direction"
-msgstr ""
-
msgid "relation removal"
msgstr ""
@@ -3388,12 +3398,15 @@
msgid "schema's permissions definitions"
msgstr "definiciones de permisos del esquema"
-msgid "schema-description"
+msgid "schema-entity-types"
msgstr ""
msgid "schema-image"
msgstr "esquema imagen"
+msgid "schema-relation-types"
+msgstr ""
+
msgid "schema-security"
msgstr ""
@@ -4055,15 +4068,18 @@
msgid "view history"
msgstr ""
+msgid "view identifier"
+msgstr ""
+
+msgid "view title"
+msgstr ""
+
msgid "view workflow"
msgstr "ver workflow"
msgid "view_index"
msgstr ""
-msgid "views"
-msgstr "vistas"
-
msgid "visible"
msgstr "visible"
@@ -4171,6 +4187,9 @@
#~ msgid "Application"
#~ msgstr "Aplicación"
+#~ msgid "Attributes"
+#~ msgstr "Atributos"
+
#~ msgid "Debug level set to %s"
#~ msgstr "Nivel de debug puesto a %s"
@@ -4202,6 +4221,9 @@
#~ msgid "__msg state changed"
#~ msgstr "El estado a cambiado"
+#~ msgid "access type"
+#~ msgstr "Tipo de Acceso"
+
#~ msgid "account state"
#~ msgstr "Estado de la Cuenta"
@@ -4502,6 +4524,9 @@
#~ "usuario para el cual aplica esta propiedad. Si no se establece esta "
#~ "relación, la propiedad es considerada como una propiedad global."
+#~ msgid "views"
+#~ msgstr "vistas"
+
#~ msgid ""
#~ "when multiple addresses are equivalent (such as python-projects@logilab."
#~ "org and python-projects@lists.logilab.org), set this to true on one of "
--- a/i18n/fr.po Tue Apr 13 19:43:51 2010 +0200
+++ b/i18n/fr.po Wed Apr 14 08:49:23 2010 +0200
@@ -201,8 +201,8 @@
msgid "Any"
msgstr "N'importe"
-msgid "Attributes"
-msgstr "Attributs"
+msgid "Attributes permissions:"
+msgstr "Permissions des attributs"
msgid "Attributes with non default permissions:"
msgstr "Attributs ayant des permissions non-standard"
@@ -529,9 +529,15 @@
msgid "No result matching query"
msgstr "aucun résultat"
+msgid "Non exhaustive list of views that may apply to entities of this type"
+msgstr "Liste non exhausite des vues s'appliquant à ce type d'entité"
+
msgid "OR"
msgstr "OU"
+msgid "Parent classes:"
+msgstr "Classes parentes :"
+
msgid "Password"
msgstr "Mot de passe"
@@ -611,6 +617,9 @@
msgid "String_plural"
msgstr "Chaînes de caractères"
+msgid "Sub-classes:"
+msgstr "Classes filles :"
+
msgid "SubWorkflowExitPoint"
msgstr "Sortie de sous-workflow"
@@ -706,6 +715,9 @@
msgid "This WorkflowTransition"
msgstr "Cette transition workflow"
+msgid "This entity type permissions:"
+msgstr "Permissions pour ce type d'endité"
+
msgid "Time"
msgstr "Heure"
@@ -828,9 +840,6 @@
msgid "abstract base class for transitions"
msgstr "classe de base abstraite pour les transitions"
-msgid "access type"
-msgstr "type d'accès"
-
msgid "action(s) on this selection"
msgstr "action(s) sur cette sélection"
@@ -1254,9 +1263,6 @@
msgid "attribute"
msgstr "attribut"
-msgid "attributes permissions:"
-msgstr "permissions des attributs :"
-
msgid "august"
msgstr "août"
@@ -1626,6 +1632,9 @@
msgid "constraints applying on this relation"
msgstr "contraintes s'appliquant à cette relation"
+msgid "content type"
+msgstr "type MIME"
+
msgid "contentnavigation"
msgstr "composants contextuels"
@@ -1897,12 +1906,6 @@
msgid "cwgroup-permissions"
msgstr "permissions"
-msgid "cwrdef-description"
-msgstr "description"
-
-msgid "cwrdef-permissions"
-msgstr "permissions"
-
msgid "cwrtype-description"
msgstr "description"
@@ -2381,6 +2384,10 @@
msgid "facets_in_state-facet_description"
msgstr ""
+#, python-format
+msgid "failed to uniquify path (%s, %s)"
+msgstr ""
+
msgid "february"
msgstr "février"
@@ -2483,9 +2490,6 @@
msgid "full text or RQL query"
msgstr "texte à rechercher ou requête RQL"
-msgid "fulltext indexed"
-msgstr "indexation du texte"
-
msgid "fulltext_container"
msgstr "conteneur du texte indexé"
@@ -3125,6 +3129,9 @@
msgid "opened web sessions"
msgstr "sessions web ouvertes"
+msgid "options"
+msgstr "options"
+
msgid "order"
msgstr "ordre"
@@ -3258,6 +3265,12 @@
msgid "project"
msgstr "projet"
+msgid "rdef-description"
+msgstr "description"
+
+msgid "rdef-permissions"
+msgstr "permissions"
+
msgid "read"
msgstr "lecture"
@@ -3309,9 +3322,6 @@
msgid "relation add"
msgstr "ajout de relation"
-msgid "relation direction"
-msgstr "sens de la relation"
-
msgid "relation removal"
msgstr "suppression de relation"
@@ -3425,12 +3435,15 @@
msgid "schema's permissions definitions"
msgstr "permissions définies dans le schéma"
-msgid "schema-description"
-msgstr "types d'entité et de relation"
+msgid "schema-entity-types"
+msgstr "types d'entités"
msgid "schema-image"
msgstr "image"
+msgid "schema-relation-types"
+msgstr "types de relations"
+
msgid "schema-security"
msgstr "permissions"
@@ -4098,15 +4111,18 @@
msgid "view history"
msgstr "voir l'historique"
+msgid "view identifier"
+msgstr "identifiant"
+
+msgid "view title"
+msgstr "titre"
+
msgid "view workflow"
msgstr "voir les états possibles"
msgid "view_index"
msgstr "accueil"
-msgid "views"
-msgstr "vues"
-
msgid "visible"
msgstr "visible"
--- a/schemaviewer.py Tue Apr 13 19:43:51 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,209 +0,0 @@
-"""an helper class to display CubicWeb schema using ureports
-
-:organization: Logilab
-:copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
-:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
-:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
-"""
-__docformat__ = "restructuredtext en"
-_ = unicode
-
-from logilab.common.ureports import Section, Title, Table, Link, Span, Text
-
-from yams.schema2dot import CARD_MAP
-from yams.schema import RelationDefinitionSchema
-
-I18NSTRINGS = [_('read'), _('add'), _('delete'), _('update'), _('order')]
-
-
-class SchemaViewer(object):
- """return an ureport layout for some part of a schema"""
- def __init__(self, req=None, encoding=None):
- self.req = req
- if req is not None:
- self.req.add_css('cubicweb.schema.css')
- if not encoding:
- encoding = req.encoding
- self.encoding = encoding
-
- def format_acls(self, schema, access_types):
- """return a layout displaying access control lists"""
- data = [self.req._('access type'), self.req._('groups')]
- for access_type in access_types:
- data.append(self.req._(access_type))
- acls = [Link(self.req.build_url('cwgroup/%s' % group), self.req._(group))
- for group in schema.get_groups(access_type)]
- acls += (Text(rqlexp.expression) for rqlexp in schema.get_rqlexprs(access_type))
- acls = [n for _n in acls for n in (_n, Text(', '))][:-1]
- data.append(Span(children=acls))
- return Section(children=(Table(cols=2, cheaders=1, rheaders=1, children=data),),
- klass='acl')
-
- def visit_schema(self, schema, display_relations=0, skiptypes=()):
- """get a layout for a whole schema"""
- title = Title(self.req._('Schema %s') % schema.name,
- klass='titleUnderline')
- layout = Section(children=(title,))
- esection = Section(children=(Title(self.req._('Entities'),
- klass='titleUnderline'),))
- layout.append(esection)
- eschemas = [eschema for eschema in schema.entities()
- if not (eschema.final or eschema in skiptypes)]
- for eschema in sorted(eschemas):
- esection.append(self.visit_entityschema(eschema, skiptypes))
- if display_relations:
- title = Title(self.req._('Relations'), klass='titleUnderline')
- rsection = Section(children=(title,))
- layout.append(rsection)
- relations = [rschema for rschema in schema.relations()
- if not (rschema.final or rschema.type in skiptypes)]
- keys = [(rschema.type, rschema) for rschema in relations]
- for key, rschema in sorted(keys):
- relstr = self.visit_relationschema(rschema)
- rsection.append(relstr)
- return layout
-
- def _entity_attributes_data(self, eschema):
- _ = self.req._
- data = [_('attribute'), _('type'), _('default'), _('constraints')]
- for rschema, aschema in eschema.attribute_definitions():
- rdef = eschema.rdef(rschema)
- if not rdef.may_have_permission('read', self.req):
- continue
- aname = rschema.type
- if aname == 'eid':
- continue
- data.append('%s (%s)' % (aname, _(aname)))
- data.append(_(aschema.type))
- defaultval = eschema.default(aname)
- if defaultval is not None:
- default = self.to_string(defaultval)
- elif rdef.cardinality[0] == '1':
- default = _('required field')
- else:
- default = ''
- data.append(default)
- constraints = rschema.rproperty(eschema.type, aschema.type,
- 'constraints')
- data.append(', '.join(str(constr) for constr in constraints))
- return data
-
- def eschema_link_url(self, eschema):
- return self.req.build_url('cwetype/%s' % eschema)
-
- def rschema_link_url(self, rschema):
- return self.req.build_url('cwrtype/%s' % rschema)
-
- def stereotype(self, name):
- return Span((' <<%s>>' % name,), klass='stereotype')
-
- def visit_entityschema(self, eschema, skiptypes=()):
- """get a layout for an entity schema"""
- etype = eschema.type
- layout = Section(children=' ', klass='clear')
- layout.append(Link(etype,' ' , id=etype)) # anchor
- title = Link(self.eschema_link_url(eschema), etype)
- boxchild = [Section(children=(title, ' (%s)'% eschema.display_name(self.req)), klass='title')]
- data = []
- data.append(Section(children=boxchild, klass='box'))
- data.append(Section(children='', klass='vl'))
- data.append(Section(children='', klass='hl'))
- t_vars = []
- rels = []
- first = True
- for rschema, targetschemas, role in eschema.relation_definitions():
- if rschema.type in skiptypes:
- continue
- rschemaurl = self.rschema_link_url(rschema)
- for oeschema in targetschemas:
- rdef = rschema.role_rdef(eschema, oeschema, role)
- if not rdef.may_have_permission('read', self.req):
- continue
- label = rschema.type
- if role == 'subject':
- cards = rschema.rproperty(eschema, oeschema, 'cardinality')
- else:
- cards = rschema.rproperty(oeschema, eschema, 'cardinality')
- cards = cards[::-1]
- label = '%s %s (%s) %s' % (CARD_MAP[cards[1]], label,
- display_name(self.req, label, role),
- CARD_MAP[cards[0]])
- rlink = Link(rschemaurl, label)
- elink = Link(self.eschema_link_url(oeschema), oeschema.type)
- if first:
- t_vars.append(Section(children=(elink,), klass='firstvar'))
- rels.append(Section(children=(rlink,), klass='firstrel'))
- first = False
- else:
- t_vars.append(Section(children=(elink,), klass='var'))
- rels.append(Section(children=(rlink,), klass='rel'))
- data.append(Section(children=rels, klass='rels'))
- data.append(Section(children=t_vars, klass='vars'))
- layout.append(Section(children=data, klass='entityAttributes'))
- return layout
-
- def visit_relationschema(self, rschema, title=True):
- """get a layout for a relation schema"""
- _ = self.req._
- if title:
- title = Link(self.rschema_link_url(rschema), rschema.type)
- stereotypes = []
- if rschema.meta:
- stereotypes.append('meta')
- if rschema.symmetric:
- stereotypes.append('symmetric')
- if rschema.inlined:
- stereotypes.append('inlined')
- title = Section(children=(title, ' (%s)'%rschema.display_name(self.req)), klass='title')
- if stereotypes:
- title.append(self.stereotype(','.join(stereotypes)))
- layout = Section(children=(title,), klass='schema')
- else:
- layout = Section(klass='schema')
- data = [_('from'), _('to')]
- schema = rschema.schema
- rschema_objects = rschema.objects()
- if rschema_objects:
- # might be empty
- properties = [p for p in RelationDefinitionSchema.rproperty_defs(rschema_objects[0])
- if not p in ('cardinality', 'composite', 'eid')]
- else:
- properties = []
- data += [_(prop) for prop in properties]
- cols = len(data)
- done = set()
- for subjtype, objtypes in rschema.associations():
- for objtype in objtypes:
- if (subjtype, objtype) in done:
- continue
- done.add((subjtype, objtype))
- if rschema.symmetric:
- done.add((objtype, subjtype))
- data.append(Link(self.eschema_link_url(schema[subjtype]), subjtype))
- data.append(Link(self.eschema_link_url(schema[objtype]), objtype))
- rdef = rschema.rdef(subjtype, objtype)
- for prop in properties:
- val = getattr(rdef, prop)
- if val is None:
- val = ''
- elif prop == 'constraints':
- val = ', '.join([c.restriction for c in val])
- elif isinstance(val, (list, tuple)):
- val = ', '.join(str(v) for v in val)
- elif val and isinstance(val, basestring):
- val = _(val)
- else:
- val = str(val)
- data.append(Text(val))
- table = Table(cols=cols, rheaders=1, children=data, klass='listing')
- layout.append(Section(children=(table,), klass='relationDefinition'))
- #if self.req.user.matching_groups('managers'):
- # layout.append(self.format_acls(rschema, ('read', 'add', 'delete')))
- layout.append(Section(children='', klass='clear'))
- return layout
-
- def to_string(self, value):
- """used to converte arbitrary values to encoded string"""
- if isinstance(value, unicode):
- return value.encode(self.encoding, 'replace')
- return str(value)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/web/schemaviewer.py Wed Apr 14 08:49:23 2010 +0200
@@ -0,0 +1,193 @@
+"""an helper class to display CubicWeb schema using ureports
+
+:organization: Logilab
+:copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
+:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
+:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
+"""
+__docformat__ = "restructuredtext en"
+_ = unicode
+
+from logilab.common.ureports import Section, Title, Table, Link, Span, Text
+
+from yams.schema2dot import CARD_MAP
+from yams.schema import RelationDefinitionSchema
+
+I18NSTRINGS = [_('read'), _('add'), _('delete'), _('update'), _('order')]
+
+
+class SchemaViewer(object):
+ """return an ureport layout for some part of a schema"""
+ def __init__(self, req=None, encoding=None):
+ self.req = req
+ if req is not None:
+ self.req.add_css('cubicweb.schema.css')
+ if not encoding:
+ encoding = req.encoding
+ self.encoding = encoding
+
+ def visit_schema(self, schema, display_relations=0, skiptypes=()):
+ """get a layout for a whole schema"""
+ title = Title(self.req._('Schema %s') % schema.name,
+ klass='titleUnderline')
+ layout = Section(children=(title,))
+ esection = Section(children=(Title(self.req._('Entities'),
+ klass='titleUnderline'),))
+ layout.append(esection)
+ eschemas = [eschema for eschema in schema.entities()
+ if not (eschema.final or eschema in skiptypes)]
+ for eschema in sorted(eschemas):
+ esection.append(self.visit_entityschema(eschema, skiptypes))
+ if display_relations:
+ title = Title(self.req._('Relations'), klass='titleUnderline')
+ rsection = Section(children=(title,))
+ layout.append(rsection)
+ relations = [rschema for rschema in schema.relations()
+ if not (rschema.final or rschema.type in skiptypes)]
+ keys = [(rschema.type, rschema) for rschema in relations]
+ for key, rschema in sorted(keys):
+ relstr = self.visit_relationschema(rschema)
+ rsection.append(relstr)
+ return layout
+
+ def _entity_attributes_data(self, eschema):
+ _ = self.req._
+ data = [_('attribute'), _('type'), _('default'), _('constraints')]
+ for rschema, aschema in eschema.attribute_definitions():
+ rdef = eschema.rdef(rschema)
+ if not rdef.may_have_permission('read', self.req):
+ continue
+ aname = rschema.type
+ if aname == 'eid':
+ continue
+ data.append('%s (%s)' % (aname, _(aname)))
+ data.append(_(aschema.type))
+ defaultval = eschema.default(aname)
+ if defaultval is not None:
+ default = self.to_string(defaultval)
+ elif rdef.cardinality[0] == '1':
+ default = _('required field')
+ else:
+ default = ''
+ data.append(default)
+ constraints = rschema.rproperty(eschema.type, aschema.type,
+ 'constraints')
+ data.append(', '.join(str(constr) for constr in constraints))
+ return data
+
+ def eschema_link_url(self, eschema):
+ return self.req.build_url('cwetype/%s' % eschema)
+
+ def rschema_link_url(self, rschema):
+ return self.req.build_url('cwrtype/%s' % rschema)
+
+ def stereotype(self, name):
+ return Span((' <<%s>>' % name,), klass='stereotype')
+
+ def visit_entityschema(self, eschema, skiptypes=()):
+ """get a layout for an entity schema"""
+ etype = eschema.type
+ layout = Section(children=' ', klass='clear')
+ layout.append(Link(etype,' ' , id=etype)) # anchor
+ title = Link(self.eschema_link_url(eschema), etype)
+ boxchild = [Section(children=(title,), klass='title')]
+ data = []
+ data.append(Section(children=boxchild, klass='box'))
+ data.append(Section(children='', klass='vl'))
+ data.append(Section(children='', klass='hl'))
+ t_vars = []
+ rels = []
+ first = True
+ for rschema, targetschemas, role in eschema.relation_definitions():
+ if rschema.type in skiptypes:
+ continue
+ rschemaurl = self.rschema_link_url(rschema)
+ for oeschema in targetschemas:
+ rdef = rschema.role_rdef(eschema, oeschema, role)
+ if not rdef.may_have_permission('read', self.req):
+ continue
+ label = rschema.type
+ if role == 'subject':
+ cards = rschema.rproperty(eschema, oeschema, 'cardinality')
+ else:
+ cards = rschema.rproperty(oeschema, eschema, 'cardinality')
+ cards = cards[::-1]
+ label = '%s %s %s' % (CARD_MAP[cards[1]], label,
+ CARD_MAP[cards[0]])
+ rlink = Link(rschemaurl, label)
+ elink = Link(self.eschema_link_url(oeschema), oeschema.type)
+ if first:
+ t_vars.append(Section(children=(elink,), klass='firstvar'))
+ rels.append(Section(children=(rlink,), klass='firstrel'))
+ first = False
+ else:
+ t_vars.append(Section(children=(elink,), klass='var'))
+ rels.append(Section(children=(rlink,), klass='rel'))
+ data.append(Section(children=rels, klass='rels'))
+ data.append(Section(children=t_vars, klass='vars'))
+ layout.append(Section(children=data, klass='entityAttributes'))
+ return layout
+
+ def visit_relationschema(self, rschema, title=True):
+ """get a layout for a relation schema"""
+ _ = self.req._
+ if title:
+ title = Link(self.rschema_link_url(rschema), rschema.type)
+ stereotypes = []
+ if rschema.meta:
+ stereotypes.append('meta')
+ if rschema.symmetric:
+ stereotypes.append('symmetric')
+ if rschema.inlined:
+ stereotypes.append('inlined')
+ title = Section(children=(title, ' (%s)'%rschema.display_name(self.req)), klass='title')
+ if stereotypes:
+ title.append(self.stereotype(','.join(stereotypes)))
+ layout = Section(children=(title,), klass='schema')
+ else:
+ layout = Section(klass='schema')
+ data = [_('from'), _('to')]
+ schema = rschema.schema
+ rschema_objects = rschema.objects()
+ if rschema_objects:
+ # might be empty
+ properties = [p for p in RelationDefinitionSchema.rproperty_defs(rschema_objects[0])
+ if not p in ('cardinality', 'composite', 'eid')]
+ else:
+ properties = []
+ data += [_(prop) for prop in properties]
+ cols = len(data)
+ done = set()
+ for subjtype, objtypes in rschema.associations():
+ for objtype in objtypes:
+ if (subjtype, objtype) in done:
+ continue
+ done.add((subjtype, objtype))
+ if rschema.symmetric:
+ done.add((objtype, subjtype))
+ data.append(Link(self.eschema_link_url(schema[subjtype]), subjtype))
+ data.append(Link(self.eschema_link_url(schema[objtype]), objtype))
+ rdef = rschema.rdef(subjtype, objtype)
+ for prop in properties:
+ val = getattr(rdef, prop)
+ if val is None:
+ val = ''
+ elif prop == 'constraints':
+ val = ', '.join([c.restriction for c in val])
+ elif isinstance(val, (list, tuple)):
+ val = ', '.join(str(v) for v in val)
+ elif val and isinstance(val, basestring):
+ val = _(val)
+ else:
+ val = str(val)
+ data.append(Text(val))
+ table = Table(cols=cols, rheaders=1, children=data, klass='listing')
+ layout.append(Section(children=(table,), klass='relationDefinition'))
+ layout.append(Section(children='', klass='clear'))
+ return layout
+
+ def to_string(self, value):
+ """used to converte arbitrary values to encoded string"""
+ if isinstance(value, unicode):
+ return value.encode(self.encoding, 'replace')
+ return str(value)
--- a/web/views/cwuser.py Tue Apr 13 19:43:51 2010 +0200
+++ b/web/views/cwuser.py Wed Apr 14 08:49:23 2010 +0200
@@ -90,7 +90,7 @@
__regid__ = 'cwgroup-main'
__select__ = tabs.PrimaryTab.__select__ & implements('CWGroup')
- def render_entity_attributes(self, entity, siderelations=None):
+ def render_entity_attributes(self, entity):
rql = 'Any U, FN, LN, CD, LL ORDERBY L WHERE U in_group G, ' \
'U login L, U firstname FN, U surname LN, U creation_date CD, ' \
'U last_login_time LL, G eid %(x)s'
--- a/web/views/emailaddress.py Tue Apr 13 19:43:51 2010 +0200
+++ b/web/views/emailaddress.py Wed Apr 14 08:49:23 2010 +0200
@@ -12,8 +12,13 @@
from cubicweb.schema import display_name
from cubicweb.selectors import implements
from cubicweb import Unauthorized
+from cubicweb.web import uicfg
from cubicweb.web.views import baseviews, primary
+_pvs = uicfg.primaryview_section
+_pvs.tag_subject_of(('*', 'use_email', '*'), 'attributes')
+_pvs.tag_subject_of(('*', 'primary_email', '*'), 'hidden')
+
class EmailAddressPrimaryView(primary.PrimaryView):
__select__ = implements('EmailAddress')
--- a/web/views/primary.py Tue Apr 13 19:43:51 2010 +0200
+++ b/web/views/primary.py Wed Apr 14 08:49:23 2010 +0200
@@ -113,7 +113,7 @@
"""default implementation return an empty string"""
return u''
- def render_entity_attributes(self, entity, siderelations=None):
+ def render_entity_attributes(self, entity):
display_attributes = []
for rschema, _, role, dispctrl in self._section_def(entity, 'attributes'):
vid = dispctrl.get('vid', 'reledit')
@@ -139,7 +139,7 @@
self._render_attribute(rschema, value, role=role, table=True)
self.w(u'</table>')
- def render_entity_relations(self, entity, siderelations=None):
+ def render_entity_relations(self, entity):
for rschema, tschemas, role, dispctrl in self._section_def(entity, 'relations'):
rset = self._relation_rset(entity, rschema, role, dispctrl)
if rset:
@@ -297,18 +297,7 @@
_pvs = uicfg.primaryview_section
for rtype in ('eid', 'creation_date', 'modification_date', 'cwuri',
- 'is', 'is_instance_of', 'identity',
- 'owned_by', 'created_by', 'in_state',
- 'wf_info_for', 'by_transition', 'from_state', 'to_state',
- 'require_permission', 'from_entity', 'to_entity',
- 'see_also'):
+ 'is', 'is_instance_of', 'identity', 'owned_by', 'created_by',
+ 'require_permission', 'see_also'):
_pvs.tag_subject_of(('*', rtype, '*'), 'hidden')
_pvs.tag_object_of(('*', rtype, '*'), 'hidden')
-
-_pvs.tag_subject_of(('*', 'use_email', '*'), 'attributes')
-_pvs.tag_subject_of(('*', 'primary_email', '*'), 'hidden')
-
-for attr in ('name', 'final'):
- _pvs.tag_attribute(('CWEType', attr), 'hidden')
-for attr in ('name', 'final', 'symmetric', 'inlined'):
- _pvs.tag_attribute(('CWRType', attr), 'hidden')
--- a/web/views/schema.py Tue Apr 13 19:43:51 2010 +0200
+++ b/web/views/schema.py Wed Apr 14 08:49:23 2010 +0200
@@ -18,10 +18,9 @@
has_related_entities, authenticated_user)
from cubicweb.schema import (META_RTYPES, SCHEMA_TYPES, SYSTEM_RTYPES,
WORKFLOW_TYPES, INTERNAL_TYPES)
-from cubicweb.schemaviewer import SchemaViewer
from cubicweb.view import EntityView, StartupView
from cubicweb import tags, uilib
-from cubicweb.web import action, facet, uicfg
+from cubicweb.web import action, facet, uicfg, schemaviewer
from cubicweb.web.views import TmpFileViewMixin
from cubicweb.web.views import primary, baseviews, tabs, tableview, iprogress
@@ -36,15 +35,32 @@
return ALWAYS_SKIP_TYPES
_pvs = uicfg.primaryview_section
+_pvdc = uicfg.primaryview_display_ctrl
+
for _action in ('read', 'add', 'update', 'delete'):
_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')
+for _etype in ('CWEType', 'CWRType', 'CWAttribute', 'CWRelation'):
+ _pvdc.tag_attribute((_etype, 'description'), {'showlabel': False})
+_pvs.tag_attribute(('CWEType', 'name'), 'hidden')
+_pvs.tag_attribute(('CWEType', 'final'), 'hidden')
+_pvs.tag_object_of(('*', 'workflow_of', 'CWEType'), 'hidden')
+_pvs.tag_subject_of(('CWEType', 'default_workflow', '*'), 'hidden')
+_pvs.tag_object_of(('*', 'specializes', 'CWEType'), 'hidden')
+_pvs.tag_subject_of(('CWEType', 'specializes', '*'), 'hidden')
+_pvs.tag_object_of(('*', 'from_entity', 'CWEType'), 'hidden')
+_pvs.tag_object_of(('*', 'to_entity', 'CWEType'), 'hidden')
+
+_pvs.tag_attribute(('CWRType', 'name'), 'hidden')
+_pvs.tag_attribute(('CWRType', 'final'), 'hidden')
_pvs.tag_object_of(('*', 'relation_type', 'CWRType'), 'hidden')
+_pvs.tag_subject_of(('CWAttribute', 'constrained_by', '*'), 'hidden')
+_pvs.tag_subject_of(('CWRelation', 'constrained_by', '*'), 'hidden')
+
+
class SecurityViewMixIn(object):
"""mixin providing methods to display security information for a entity,
relation or relation definition schema
@@ -61,18 +77,16 @@
w(u'<tr><td>%s</td><td>' % _(action))
if permissions is None:
groups = erschema.get_groups(action)
+ rqlexprs = sorted(e.expression for e in erschema.get_rqlexprs(action))
else:
groups = permissions[action][0]
+ rqlexprs = 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 g 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>')
@@ -108,13 +122,14 @@
# global schema view ###########################################################
class SchemaView(tabs.TabsMixin, StartupView):
+ """display schema information (graphically, listing tables...) in tabs"""
__regid__ = 'schema'
title = _('instance schema')
- tabs = [_('schema-description'), _('schema-image'), _('schema-security')]
- default_tab = 'schema-description'
+ tabs = [_('schema-image'), _('schema-entity-types'),
+ _('schema-relation-types'), _('schema-security')]
+ default_tab = 'schema-image'
def call(self):
- """display schema information"""
self.w(u'<h1>%s</h1>' % _('Schema of the data model'))
self.render_tabs(self.tabs, self.default_tab)
@@ -127,24 +142,28 @@
u'meta-data, but you can also display a <a href="%s">complete '
u'schema with meta-data</a>.</div>')
% xml_escape(self._cw.build_url('view', vid='schemagraph', skipmeta=0)))
+ self.w(u'<div><a href="%s">%s</a></div>' %
+ (self._cw.build_url('view', vid='owl'),
+ self._cw._(u'Download schema as OWL')))
self.w(u'<img src="%s" alt="%s"/>\n' % (
xml_escape(self._cw.build_url('view', vid='schemagraph', skipmeta=1)),
self._cw._("graphical representation of the instance'schema")))
-class SchemaDescriptionTab(StartupView):
- __regid__ = 'schema-description'
+class SchemaETypeTab(StartupView):
+ __regid__ = 'schema-entity-types'
def call(self):
- rset = self._cw.execute('Any X ORDERBY N WHERE X is CWEType, X name N, '
- 'X final FALSE')
- self.wview('table', rset, displayfilter=True)
- rset = self._cw.execute('Any X ORDERBY N WHERE X is CWRType, X name N, '
- 'X final FALSE')
- self.wview('table', rset, displayfilter=True)
- owl_downloadurl = self._cw.build_url('view', vid='owl')
- self.w(u'<div><a href="%s">%s</a></div>' %
- (owl_downloadurl, self._cw._(u'Download schema as OWL')))
+ self.wview('table', self._cw.execute(
+ 'Any X ORDERBY N WHERE X is CWEType, X name N, X final FALSE'))
+
+
+class SchemaRTypeTab(StartupView):
+ __regid__ = 'schema-relation-types'
+
+ def call(self):
+ self.wview('table', self._cw.execute(
+ 'Any X ORDERBY N WHERE X is CWRType, X name N, X final FALSE'))
class SchemaPermissionsTab(SecurityViewMixIn, StartupView):
@@ -152,7 +171,6 @@
__select__ = StartupView.__select__ & match_user_groups('managers')
def call(self, display_relations=True):
- self._cw.add_css('cubicweb.acl.css')
skiptypes = skip_types(self._cw)
schema = self._cw.vreg.schema
# compute entities
@@ -267,65 +285,67 @@
__regid__ = 'cwetype-description'
__select__ = tabs.PrimaryTab.__select__ & implements('CWEType')
- def render_entity_attributes(self, entity, siderelations=None):
+ def render_entity_attributes(self, entity):
+ super(CWETypeDescriptionTab, self).render_entity_attributes(entity)
_ = self._cw._
- self.w(u'<div>%s</div>' % xml_escape(entity.description or u''))
+ # inheritance
+ if entity.specializes:
+ self.w(u'<div>%s' % _('Parent classes:'))
+ self.wview('csv', entity.related('specializes', 'subject'))
+ self.w(u'</div>')
+ if entity.reverse_specializes:
+ self.w(u'<div>%s' % _('Sub-classes:'))
+ self.wview('csv', entity.related('specializes', 'object'))
+ self.w(u'</div>')
# entity schema image
- url = entity.absolute_url(vid='schemagraph')
self.w(u'<img src="%s" alt="%s"/>' % (
- xml_escape(url),
+ xml_escape(entity.absolute_url(vid='schemagraph')),
xml_escape(_('graphical schema for %s') % entity.name)))
# entity schema attributes
- self.w(u'<h2>%s</h2>' % _('Attributes'))
+ self.w(u'<h2>%s</h2>' % _('CWAttribute_plural'))
rset = self._cw.execute(
- 'Any A,F,D,C,I,J,A,DE ORDERBY AA WHERE A is CWAttribute, '
+ 'Any A,ON,D,C,A,DE,A, IDX,FTI,I18N,R,O,RN,S ORDERBY AA '
+ 'WHERE A is CWAttribute, A from_entity S, S eid %(x)s, '
'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',
+ 'A fulltextindexed FTI, A internationalizable I18N, A indexed IDX, '
+ 'A relation_type R, R name RN, A to_entity O, O name ON',
{'x': entity.eid})
self.wview('table', rset, 'null',
cellvids={0: 'rdef-name-cell',
3: 'etype-attr-cardinality-cell',
- 6: 'rdef-constraints-cell'},
+ 4: 'rdef-constraints-cell',
+ 6: 'rdef-options-cell'},
headers=(_(u'name'), _(u'type'),
_(u'default value'), _(u'required'),
- _(u'fulltext indexed'), _(u'internationalizable'),
- _(u'constraints'), _(u'description')),
- mainindex=0)
+ _(u'constraints'), _(u'description'), _('options')))
# entity schema relations
- self.w(u'<h2>%s</h2>' % _('Relations'))
+ self.w(u'<h2>%s</h2>' % _('CWRelation_plural'))
+ cellvids = {0: 'rdef-name-cell',
+ 2: 'etype-rel-cardinality-cell',
+ 3: 'rdef-constraints-cell',
+ 4: 'rdef-options-cell'}
+ headers= [_(u'name'), _(u'object type'), _(u'cardinality'),
+ _(u'constraints'), _(u'options')]
rset = self._cw.execute(
- 'Any A,TT,"i18ncard_"+SUBSTRING(C, 1, 1),K,A,TTN ORDERBY RN '
- 'WHERE A is CWRelation, A composite K, A cardinality C, '
- 'A relation_type R, R name RN, '
- 'A to_entity TT, TT name TTN, A from_entity S, S eid %(x)s',
+ 'Any A,TT,"i18ncard_"+SUBSTRING(C,1,1),A,A, K,TTN,R,RN ORDERBY RN '
+ 'WHERE A is CWRelation, A from_entity S, S eid %(x)s, '
+ 'A composite K, A cardinality C, '
+ 'A relation_type R, R name RN, A to_entity TT, TT name TTN',
{'x': entity.eid})
if rset:
self.w(u'<h5>%s %s</h5>' % (entity.name, _('is subject of:')))
- self.wview('table', rset, 'null',
- cellvids={0: 'rdef-name-cell',
- 2: 'etype-rel-cardinality-cell',
- 4: 'rdef-constraints-cell'},
- headers=(_(u'name'), _(u'object type'), _(u'cardinality'),
- _(u'composite'), _(u'constraints')),
- displaycols=range(5))
- self.w(u'<br/>')
+ self.wview('table', rset, cellvids=cellvids, headers=headers)
rset = self._cw.execute(
- 'Any A,TT,"i18ncard_"+SUBSTRING(C, 2, 1),K,A,TTN ORDERBY RN '
- 'WHERE A is CWRelation, A composite K, A cardinality C, '
- 'A relation_type R, R name RN, '
- 'A from_entity TT, TT name TTN, A to_entity O, O eid %(x)s',
+ 'Any A,TT,"i18ncard_"+SUBSTRING(C,1,1),A,A, K,TTN,R,RN ORDERBY RN '
+ 'WHERE A is CWRelation, A to_entity O, O eid %(x)s, '
+ 'A composite K, A cardinality C, '
+ 'A relation_type R, R name RN, A from_entity TT, TT name TTN',
{'x': entity.eid})
if rset:
+ cellvids[0] = 'rdef-object-name-cell'
+ headers[1] = _(u'subject type')
self.w(u'<h5>%s %s</h5>' % (entity.name, _('is object of:')))
- self.wview('table', rset, 'null',
- cellvids={0: 'rdef-object-name-cell',
- 2: 'etype-rel-cardinality-cell',
- 4: 'rdef-constraints-cell'},
- headers=(_(u'name'), _(u'subject type'), _(u'cardinality'),
- _(u'composite'), _(u'constraints')),
- displaycols=range(5))
+ self.wview('table', rset, cellvids=cellvids, headers=headers)
class CWETypeAttributeCardinalityCell(baseviews.FinalView):
@@ -350,7 +370,7 @@
__select__ = implements('CWEType')
def cell_call(self, row, col):
- viewer = SchemaViewer(self._cw)
+ viewer = schemaviewer.SchemaViewer(self._cw)
entity = self.cw_rset.get_entity(row, col)
eschema = self._cw.vreg.schema.eschema(entity.name)
layout = viewer.visit_entityschema(eschema)
@@ -363,12 +383,12 @@
__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'<div style="margin: 0px 1.5em">')
+ self.w(u'<h4>%s</h4>' % _('This entity type permissions:').capitalize())
self.permissions_table(eschema)
- self.w(u'<h4>%s</h4>' % _('attributes permissions:').capitalize())
+ self.w(u'<div style="margin: 0px 1.5em">')
+ 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)
@@ -409,16 +429,20 @@
class CWETypeViewsTab(EntityView):
+ """possible views for this entity type"""
__regid__ = 'cwetype-views'
__select__ = EntityView.__select__ & implements('CWEType')
def cell_call(self, row, col):
entity = self.cw_rset.get_entity(row, col)
- etype = entity.name
_ = self._cw._
- # possible views for this entity type
- views = [(_(view.title),) for view in self.possible_views(etype)]
- self.wview('pyvaltable', pyvalue=sorted(views), headers=(_(u'views'),))
+ self.w('<div>%s</div>' % _('Non exhaustive list of views that may '
+ 'apply to entities of this type'))
+ views = [(view.content_type, view.__regid__, _(view.title))
+ for view in self.possible_views(entity.name)]
+ self.wview('pyvaltable', pyvalue=sorted(views),
+ headers=(_(u'content type'), _(u'view identifier'),
+ _(u'view title')))
def possible_views(self, etype):
rset = self._cw.etype_rset(etype)
@@ -450,22 +474,21 @@
__regid__ = 'cwrtype-description'
__select__ = implements('CWRType')
- def render_entity_attributes(self, entity, siderelations=None):
+ def render_entity_attributes(self, entity):
+ super(CWRTypeDescriptionTab, self).render_entity_attributes(entity)
_ = self._cw._
- self.w(u'<div>%s</div>' % xml_escape(entity.description or u''))
- rschema = self._cw.vreg.schema.rschema(entity.name)
- if not rschema.final:
+ if not entity.final:
msg = _('graphical schema for %s') % entity.name
self.w(tags.img(src=entity.absolute_url(vid='schemagraph'),
alt=msg))
- rset = self._cw.execute('Any R,C,CC,R WHERE R is CWRelation, '
+ rset = self._cw.execute('Any R,C,R,R, RT WHERE '
'R relation_type RT, RT eid %(x)s, '
- 'R cardinality C, R composite CC',
- {'x': entity.eid})
+ 'R cardinality C', {'x': entity.eid})
self.wview('table', rset, 'null',
- headers=(_(u'relation'), _(u'cardinality'), _(u'composite'),
- _(u'constraints')),
- cellvids={3: 'rdef-constraints-cell'})
+ headers=(_(u'relation'), _(u'cardinality'), _(u'constraints'),
+ _(u'options')),
+ cellvids={2: 'rdef-constraints-cell',
+ 3: 'rdef-options-cell'})
class CWRTypePermTab(SecurityViewMixIn, EntityView):
@@ -473,7 +496,6 @@
__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)
@@ -481,27 +503,33 @@
# CWAttribute / CWRelation #####################################################
-class CWRDEFPrimaryView(tabs.TabbedPrimaryView):
+class RDEFPrimaryView(tabs.TabbedPrimaryView):
__select__ = implements('CWRelation', 'CWAttribute')
- tabs = [_('cwrdef-description'), _('cwrdef-permissions')]
- default_tab = 'cwrdef-description'
+ tabs = [_('rdef-description'), _('rdef-permissions')]
+ default_tab = 'rdef-description'
-class CWRDEFDescriptionTab(tabs.PrimaryTab):
- __regid__ = 'cwrdef-description'
+
+class RDEFDescriptionTab(tabs.PrimaryTab):
+ __regid__ = 'rdef-description'
__select__ = implements('CWRelation', 'CWAttribute')
-class CWRDEFPermTab(SecurityViewMixIn, EntityView):
- __regid__ = 'cwrdef-permissions'
+ def render_entity_attributes(self, entity):
+ super(RDEFDescriptionTab, self).render_entity_attributes(entity)
+ rdef = entity.yams_schema()
+ if rdef.constraints:
+ self.w(u'<h4>%s</h4>' % self._cw._('constrained_by'))
+ self.w(entity.view('rdef-constraints-cell'))
+
+
+class RDEFPermTab(SecurityViewMixIn, EntityView):
+ __regid__ = 'rdef-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.permissions_table(rdef)
+ self.permissions_table(self.cw_rset.get_entity(row, col).yams_schema())
-class CWRDEFNameView(tableview.CellView):
+class RDEFNameView(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)
@@ -512,12 +540,12 @@
def cell_call(self, row, col):
entity = self.cw_rset.get_entity(row, col)
rtype = entity.relation_type[0].name
- # XXX use contect entity + pgettext
+ # XXX use context entity + pgettext
self.w(u'<a href="%s">%s</a> (%s)' % (
entity.absolute_url(), rtype, self._cw._(rtype)))
-class CWRDEFObjectNameView(tableview.CellView):
- """same as CWRDEFNameView but when the context is the object entity
+class RDEFObjectNameView(tableview.CellView):
+ """same as RDEFNameView but when the context is the object entity
"""
__regid__ = 'rdef-object-name-cell'
__select__ = implements('CWRelation', 'CWAttribute')
@@ -525,11 +553,11 @@
def cell_call(self, row, col):
entity = self.cw_rset.get_entity(row, col)
rtype = entity.relation_type[0].name
- # XXX use contect entity + pgettext
+ # XXX use context entity + pgettext
self.w(u'<a href="%s">%s</a> (%s)' % (
entity.absolute_url(), rtype, self._cw.__(rtype + '_object')))
-class CWRDEFConstraintsCell(EntityView):
+class RDEFConstraintsCell(EntityView):
__regid__ = 'rdef-constraints-cell'
__select__ = implements('CWAttribute', 'CWRelation')
@@ -540,6 +568,41 @@
constraints = [xml_escape(str(c)) for c in getattr(rdef, 'constraints')]
self.w(u'<br/>'.join(constraints))
+class CWAttributeOptionsCell(EntityView):
+ __regid__ = 'rdef-options-cell'
+ __select__ = implements('CWAttribute')
+
+ def cell_call(self, row, col):
+ entity = self.cw_rset.get_entity(row, col)
+ options = []
+ if entity.indexed:
+ options.append(self._cw._('indexed'))
+ if entity.fulltextindexed:
+ options.append(self._cw._('fulltextindexed'))
+ if entity.internationalizable:
+ options.append(self._cw._('internationalizable'))
+ self.w(u','.join(options))
+
+class CWRelationOptionsCell(EntityView):
+ __regid__ = 'rdef-options-cell'
+ __select__ = implements('CWRelation',)
+
+ def cell_call(self, row, col):
+ entity = self.cw_rset.get_entity(row, col)
+ rtype = entity.rtype
+ options = []
+ if rtype.symmetric:
+ options.append(self._cw._('symmetric'))
+ if rtype.inlined:
+ options.append(self._cw._('inlined'))
+ if rtype.fulltext_container:
+ options.append('%s=%s' % (self._cw._('fulltext_container'),
+ self._cw._(rtype.fulltext_container)))
+ if entity.composite:
+ options.append('%s=%s' % (self._cw._('composite'),
+ self._cw._(entity.composite)))
+ self.w(u','.join(options))
+
# schema images ###############################################################
--- a/web/views/tableview.py Tue Apr 13 19:43:51 2010 +0200
+++ b/web/views/tableview.py Wed Apr 14 08:49:23 2010 +0200
@@ -87,10 +87,12 @@
continue
return None
- def displaycols(self, displaycols):
+ def displaycols(self, displaycols, headers):
if displaycols is None:
if 'displaycols' in self._cw.form:
displaycols = [int(idx) for idx in self._cw.form['displaycols']]
+ elif headers is not None:
+ displaycols = range(len(headers))
else:
displaycols = range(len(self.cw_rset.syntax_tree().children[0].selection))
return displaycols
@@ -127,7 +129,7 @@
hidden = False
if displayactions is None and 'displayactions' in req.form:
displayactions = True
- displaycols = self.displaycols(displaycols)
+ displaycols = self.displaycols(displaycols, headers)
fromformfilter = 'fromformfilter' in req.form
# if fromformfilter is true, this is an ajax call and we only want to
# replace the inner div, so don't regenerate everything under the if
@@ -297,7 +299,7 @@
"""Dumps a table displaying a composite query"""
actrql = self._cw.form['actualrql']
self._cw.ensure_ro_rql(actrql)
- displaycols = self.displaycols(displaycols)
+ displaycols = self.displaycols(displaycols, headers)
if displayactions is None and 'displayactions' in self._cw.form:
displayactions = True
if divid is None and 'divid' in self._cw.form:
--- a/web/views/workflow.py Tue Apr 13 19:43:51 2010 +0200
+++ b/web/views/workflow.py Wed Apr 14 08:49:23 2010 +0200
@@ -33,6 +33,11 @@
_pvs.tag_subject_of(('Workflow', 'initial_state', '*'), 'hidden')
_pvs.tag_object_of(('*', 'state_of', 'Workflow'), 'hidden')
_pvs.tag_object_of(('*', 'transition_of', 'Workflow'), 'hidden')
+_pvs.tag_object_of(('*', 'wf_info_for', '*'), 'hidden')
+for rtype in ('in_state', 'by_transition', 'from_state', 'to_state'):
+ _pvs.tag_subject_of(('*', rtype, '*'), 'hidden')
+ _pvs.tag_object_of(('*', rtype, '*'), 'hidden')
+_pvs.tag_object_of(('*', 'wf_info_for', '*'), 'hidden')
_abaa = uicfg.actionbox_appearsin_addmenu
_abaa.tag_subject_of(('BaseTransition', 'condition', 'RQLExpression'), False)