# HG changeset patch # User Sylvain Thénault # Date 1271227763 -7200 # Node ID 471554b842d28cccce097da69f59db2a3658e562 # Parent 31c12863fd9d43abb75752ef1982c732be6f393d [schema view] the final touch. Things are getting nicely displayed, and code clean diff -r 31c12863fd9d -r 471554b842d2 entities/schemaobjs.py --- 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' diff -r 31c12863fd9d -r 471554b842d2 i18n/en.po --- 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" diff -r 31c12863fd9d -r 471554b842d2 i18n/es.po --- 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 " diff -r 31c12863fd9d -r 471554b842d2 i18n/fr.po --- 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" diff -r 31c12863fd9d -r 471554b842d2 schemaviewer.py --- 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) diff -r 31c12863fd9d -r 471554b842d2 web/schemaviewer.py --- /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) diff -r 31c12863fd9d -r 471554b842d2 web/views/cwuser.py --- 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' diff -r 31c12863fd9d -r 471554b842d2 web/views/emailaddress.py --- 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') diff -r 31c12863fd9d -r 471554b842d2 web/views/primary.py --- 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'') - 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') diff -r 31c12863fd9d -r 471554b842d2 web/views/schema.py --- 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'%s' % _(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'%s' % ( group, self._cw.build_url('cwgroup/%s' % group), label) for group, label in sorted((_(g), g) for g in groups)] w(u'
'.join(groups)) w(u'') - if permissions is None: - rqlexprs = sorted(e.expression for e in erschema.get_rqlexprs(action)) - else: - rqlexprs = permissions[action][1] w(u'
'.join(rqlexprs)) w(u'\n') w(u'') @@ -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'

%s

' % _('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 complete ' u'schema with meta-data.') % xml_escape(self._cw.build_url('view', vid='schemagraph', skipmeta=0))) + self.w(u'
%s
' % + (self._cw.build_url('view', vid='owl'), + self._cw._(u'Download schema as OWL'))) self.w(u'%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'
%s
' % - (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'
%s
' % xml_escape(entity.description or u'')) + # inheritance + if entity.specializes: + self.w(u'
%s' % _('Parent classes:')) + self.wview('csv', entity.related('specializes', 'subject')) + self.w(u'
') + if entity.reverse_specializes: + self.w(u'
%s' % _('Sub-classes:')) + self.wview('csv', entity.related('specializes', 'object')) + self.w(u'
') # entity schema image - url = entity.absolute_url(vid='schemagraph') self.w(u'%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'

%s

' % _('Attributes')) + self.w(u'

%s

' % _('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'

%s

' % _('Relations')) + self.w(u'

%s

' % _('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'
%s %s
' % (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'
') + 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'
%s %s
' % (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'
') + self.w(u'

%s

' % _('This entity type permissions:').capitalize()) self.permissions_table(eschema) - self.w(u'

%s

' % _('attributes permissions:').capitalize()) + self.w(u'
') + self.w(u'

%s

' % _('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('
%s
' % _('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'
%s
' % 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'

%s

' % 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'%s (%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'%s (%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'
'.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 ############################################################### diff -r 31c12863fd9d -r 471554b842d2 web/views/tableview.py --- 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: diff -r 31c12863fd9d -r 471554b842d2 web/views/workflow.py --- 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)