web/views/actions.py
branch3.5
changeset 3219 be8cfc00ae04
parent 2715 acdaf780d4a6
child 3228 7b05b2709439
--- 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):