# HG changeset patch # User sylvain.thenault@logilab.fr # Date 1238091357 -3600 # Node ID 2d1b721fded94c6981243e5776f6a67a2644c0e6 # Parent 1e19b6ef53a18104c2849b95cea86505998d703e remove rtags/methods to handle the action box from Entity, move it to the action box... diff -r 1e19b6ef53a1 -r 2d1b721fded9 devtools/devctl.py --- a/devtools/devctl.py Thu Mar 26 19:00:20 2009 +0100 +++ b/devtools/devctl.py Thu Mar 26 19:15:57 2009 +0100 @@ -143,10 +143,10 @@ add_msg(w, rschema.description) w('# add related box generated message\n') w('\n') + actionbox = self.vreg['actions']['edit_box'][0] for eschema in schema.entities(): if eschema.is_final(): continue - entity = vreg.etype_class(eschema)(None, None) for x, rschemas in (('subject', eschema.subject_relations()), ('object', eschema.object_relations())): for rschema in rschemas: @@ -155,7 +155,7 @@ for teschema in rschema.targets(eschema, x): if defined_in_library(libschema, eschema, rschema, teschema, x): continue - if entity.relation_mode(rschema.type, teschema.type, x) == 'create': + if actionbox.relation_mode(rschema.type, teschema.type, x) == 'create': if x == 'subject': label = 'add %s %s %s %s' % (eschema, rschema, teschema, x) label2 = "creating %s (%s %%(linkto)s %s %s)" % (teschema, eschema, rschema, teschema) diff -r 1e19b6ef53a1 -r 2d1b721fded9 entities/__init__.py --- a/entities/__init__.py Thu Mar 26 19:00:20 2009 +0100 +++ b/entities/__init__.py Thu Mar 26 19:15:57 2009 +0100 @@ -201,39 +201,6 @@ return self.printable_value(rtype, format='text/plain').lower() return value - def add_related_schemas(self): - """this is actually used ui method to generate 'addrelated' actions from - the schema. - - If you're using explicit 'addrelated' actions for an entity types, you - should probably overrides this method to return an empty list else you - may get some unexpected actions. - """ - req = self.req - eschema = self.e_schema - for role, rschemas in (('subject', eschema.subject_relations()), - ('object', eschema.object_relations())): - for rschema in rschemas: - if rschema.is_final(): - continue - # check the relation can be added as well - if role == 'subject'and not rschema.has_perm(req, 'add', fromeid=self.eid): - continue - if role == 'object'and not rschema.has_perm(req, 'add', toeid=self.eid): - continue - # check the target types can be added as well - for teschema in rschema.targets(eschema, role): - if not self.relation_mode(rschema, teschema, role) == 'create': - continue - if teschema.has_local_role('add') or teschema.has_perm(req, 'add'): - yield rschema, teschema, role - - def relation_mode(self, rtype, targettype, role='subject'): - """return a string telling if the given relation is usually created - to a new entity ('create' mode) or to an existant entity ('link' mode) - """ - return self.rtags.get_mode(rtype, targettype, role) - # edition helper functions ################################################ def linked_to(self, rtype, target, remove=True): diff -r 1e19b6ef53a1 -r 2d1b721fded9 web/views/boxes.py --- a/web/views/boxes.py Thu Mar 26 19:00:20 2009 +0100 +++ b/web/views/boxes.py Thu Mar 26 19:15:57 2009 +0100 @@ -16,6 +16,7 @@ from logilab.mtconverter import html_escape +from cubicweb.rtags import RelationTags from cubicweb.selectors import match_user_groups, non_final_entity from cubicweb.web.htmlwidgets import BoxWidget, BoxMenu, BoxHtml, RawBoxItem from cubicweb.view import EntityView @@ -29,10 +30,55 @@ box with all actions impacting the entity displayed: edit, copy, delete change state, add related entities """ + id = 'edit_box' __select__ = BoxTemplate.__select__ & non_final_entity() - id = 'edit_box' + title = _('actions') order = 2 + # 'link' / 'create' relation tags, used to control the "add entity" submenu + rmode = RelationTags() + + @classmethod + def registered(cls, registry): + """build class using descriptor at registration time""" + super(AutomaticEntityForm, cls).registered(registry) + cls.init_rtags_mode() + return cls + + @classmethod + def init_rtags_mode(cls): + """set default category tags for relations where it's not yet defined in + the category relation tags + """ + for eschema in cls.schema.entities(): + for rschema, tschemas, role in eschema.relation_definitions(True): + for tschema in tschemas: + if role == 'subject': + X, Y = eschema, tschema + card = rschema.rproperty(X, Y, 'cardinality')[0] + else: + X, Y = tschema, eschema + card = rschema.rproperty(X, Y, 'cardinality')[1] + if not cls.rmode.rtag(role, rschema, X, Y): + if card in '?1': + # by default, suppose link mode if cardinality doesn't allow + # more than one relation + mode = 'link' + elif rschema.rproperty(X, Y, 'composite') == role: + # if self is composed of the target type, create mode + mode = 'create' + else: + # link mode by default + mode = 'link' + cls.rmode.set_rtag(category, role, rschema, X, Y) + + @classmethod + def relation_mode(cls, rtype, etype, targettype, role='subject'): + """return a string telling if the given relation is usually created + to a new entity ('create' mode) or to an existant entity ('link' mode) + """ + return cls.rmode.rtag(role, rtype, etype, targettype) + def call(self, **kwargs): _ = self.req._ @@ -92,7 +138,7 @@ actions = [] _ = self.req._ eschema = entity.e_schema - for rschema, teschema, x in entity.add_related_schemas(): + for rschema, teschema, x in self.add_related_schemas(entity): if x == 'subject': label = 'add %s %s %s %s' % (eschema, rschema, teschema, x) url = self.linkto_url(entity, rschema, teschema, 'object') @@ -102,6 +148,33 @@ actions.append(self.mk_action(_(label), url)) return actions + def add_related_schemas(self, entity): + """this is actually used ui method to generate 'addrelated' actions from + the schema. + + If you're using explicit 'addrelated' actions for an entity types, you + should probably overrides this method to return an empty list else you + may get some unexpected actions. + """ + req = self.req + eschema = entity.e_schema + for role, rschemas in (('subject', eschema.subject_relations()), + ('object', eschema.object_relations())): + for rschema in rschemas: + if rschema.is_final(): + continue + # check the relation can be added as well + if role == 'subject'and not rschema.has_perm(req, 'add', fromeid=entity.eid): + continue + if role == 'object'and not rschema.has_perm(req, 'add', toeid=entity.eid): + continue + # check the target types can be added as well + for teschema in rschema.targets(eschema, role): + if not self.relation_mode(rschema, eschema, teschema, role) == 'create': + continue + if teschema.has_local_role('add') or teschema.has_perm(req, 'add'): + yield rschema, teschema, role + def workflow_actions(self, entity, box): if 'in_state' in entity.e_schema.subject_relations() and entity.in_state: