--- a/web/views/actions.py Mon Sep 14 18:59:17 2009 +0200
+++ b/web/views/actions.py Mon Sep 14 19:01:24 2009 +0200
@@ -226,6 +226,71 @@
return self.build_url('add/%s' % self.rsettype)
+class AddRelatedActions(Action):
+ """fill 'addrelated' sub-menu of the actions box"""
+ id = 'addrelated'
+ __select__ = Action.__select__ & one_line_rset() & non_final_entity()
+
+ submenu = _('addrelated')
+ order = 20
+
+ def fill_menu(self, box, menu):
+ # when there is only one item in the sub-menu, replace the sub-menu by
+ # item's title prefixed by 'add'
+ menu.label_prefix = self.req._('add')
+ entity = self.rset.get_entity(self.row or 0, self.col or 0)
+ user = self.req.user
+ actions = []
+ _ = self.req._
+ eschema = entity.e_schema
+ 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')
+ else:
+ label = 'add %s %s %s %s' % (teschema, rschema, eschema, x)
+ url = self.linkto_url(entity, rschema, teschema, 'subject')
+ menu.append(box.mk_action(_(label), url))
+
+ def add_related_schemas(self, entity):
+ """this is actually used ui method to generate 'addrelated' actions from
+ the schema.
+
+ If you don't want any auto-generated actions, you should overrides this
+ method to return an empty list. If you only want some, you can configure
+ them by using uicfg.actionbox_appearsin_addmenu
+ """
+ appearsin_addmenu = uicfg.actionbox_appearsin_addmenu
+ 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
+ # XXX consider autoform_permissions_overrides?
+ 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 appearsin_addmenu.etype_get(eschema, rschema,
+ role, teschema):
+ continue
+ if teschema.has_local_role('add') or teschema.has_perm(req, 'add'):
+ yield rschema, teschema, role
+
+ def linkto_url(self, entity, rtype, etype, target):
+ return self.build_url(vid='creation', etype=etype,
+ __linkto='%s:%s:%s' % (rtype, entity.eid, target),
+ __redirectpath=entity.rest_path(), # should not be url quoted!
+ __redirectvid=self.req.form.get('vid', ''))
+
+
# logged user actions #########################################################
class UserPreferencesAction(Action):