remove rtags/methods to handle the action box from Entity, move it to the action box...
--- 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)
--- 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):
--- 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: