web/views/boxes.py
branchtls-sprint
changeset 1150 2d1b721fded9
parent 1132 96752791c2b6
child 1151 b20677336ee6
equal deleted inserted replaced
1149:1e19b6ef53a1 1150:2d1b721fded9
    14 """
    14 """
    15 __docformat__ = "restructuredtext en"
    15 __docformat__ = "restructuredtext en"
    16 
    16 
    17 from logilab.mtconverter import html_escape
    17 from logilab.mtconverter import html_escape
    18 
    18 
       
    19 from cubicweb.rtags import RelationTags
    19 from cubicweb.selectors import match_user_groups, non_final_entity
    20 from cubicweb.selectors import match_user_groups, non_final_entity
    20 from cubicweb.web.htmlwidgets import BoxWidget, BoxMenu, BoxHtml, RawBoxItem
    21 from cubicweb.web.htmlwidgets import BoxWidget, BoxMenu, BoxHtml, RawBoxItem
    21 from cubicweb.view import EntityView
    22 from cubicweb.view import EntityView
    22 from cubicweb.web.box import BoxTemplate
    23 from cubicweb.web.box import BoxTemplate
    23 
    24 
    27 class EditBox(BoxTemplate):
    28 class EditBox(BoxTemplate):
    28     """
    29     """
    29     box with all actions impacting the entity displayed: edit, copy, delete
    30     box with all actions impacting the entity displayed: edit, copy, delete
    30     change state, add related entities
    31     change state, add related entities
    31     """
    32     """
       
    33     id = 'edit_box'
    32     __select__ = BoxTemplate.__select__ & non_final_entity()
    34     __select__ = BoxTemplate.__select__ & non_final_entity()
    33     id = 'edit_box'
    35 
    34     title = _('actions')
    36     title = _('actions')
    35     order = 2
    37     order = 2
       
    38     # 'link' / 'create' relation tags, used to control the "add entity" submenu
       
    39     rmode = RelationTags() 
       
    40 
       
    41     @classmethod
       
    42     def registered(cls, registry):
       
    43         """build class using descriptor at registration time"""
       
    44         super(AutomaticEntityForm, cls).registered(registry)
       
    45         cls.init_rtags_mode()
       
    46         return cls
       
    47         
       
    48     @classmethod
       
    49     def init_rtags_mode(cls):
       
    50         """set default category tags for relations where it's not yet defined in
       
    51         the category relation tags
       
    52         """
       
    53         for eschema in cls.schema.entities():
       
    54             for rschema, tschemas, role in eschema.relation_definitions(True):
       
    55                 for tschema in tschemas:
       
    56                     if role == 'subject':
       
    57                         X, Y = eschema, tschema
       
    58                         card = rschema.rproperty(X, Y, 'cardinality')[0]
       
    59                     else:
       
    60                         X, Y = tschema, eschema
       
    61                         card = rschema.rproperty(X, Y, 'cardinality')[1]
       
    62                     if not cls.rmode.rtag(role, rschema, X, Y):
       
    63                         if card in '?1':
       
    64                             # by default, suppose link mode if cardinality doesn't allow
       
    65                             # more than one relation
       
    66                             mode = 'link'
       
    67                         elif rschema.rproperty(X, Y, 'composite') == role:
       
    68                             # if self is composed of the target type, create mode
       
    69                             mode = 'create'
       
    70                         else:
       
    71                             # link mode by default
       
    72                             mode = 'link'
       
    73                         cls.rmode.set_rtag(category, role, rschema, X, Y)
       
    74 
       
    75     @classmethod
       
    76     def relation_mode(cls, rtype, etype, targettype, role='subject'):
       
    77         """return a string telling if the given relation is usually created
       
    78         to a new entity ('create' mode) or to an existant entity ('link' mode)
       
    79         """
       
    80         return cls.rmode.rtag(role, rtype, etype, targettype)
       
    81 
    36 
    82 
    37     def call(self, **kwargs):
    83     def call(self, **kwargs):
    38         _ = self.req._
    84         _ = self.req._
    39         title = _(self.title)
    85         title = _(self.title)
    40         if self.rset:
    86         if self.rset:
    90     def schema_actions(self, entity):
   136     def schema_actions(self, entity):
    91         user = self.req.user
   137         user = self.req.user
    92         actions = []
   138         actions = []
    93         _ = self.req._
   139         _ = self.req._
    94         eschema = entity.e_schema
   140         eschema = entity.e_schema
    95         for rschema, teschema, x in entity.add_related_schemas():
   141         for rschema, teschema, x in self.add_related_schemas(entity):
    96             if x == 'subject':
   142             if x == 'subject':
    97                 label = 'add %s %s %s %s' % (eschema, rschema, teschema, x)
   143                 label = 'add %s %s %s %s' % (eschema, rschema, teschema, x)
    98                 url = self.linkto_url(entity, rschema, teschema, 'object')
   144                 url = self.linkto_url(entity, rschema, teschema, 'object')
    99             else:
   145             else:
   100                 label = 'add %s %s %s %s' % (teschema, rschema, eschema, x)
   146                 label = 'add %s %s %s %s' % (teschema, rschema, eschema, x)
   101                 url = self.linkto_url(entity, rschema, teschema, 'subject')
   147                 url = self.linkto_url(entity, rschema, teschema, 'subject')
   102             actions.append(self.mk_action(_(label), url))
   148             actions.append(self.mk_action(_(label), url))
   103         return actions
   149         return actions
       
   150 
       
   151     def add_related_schemas(self, entity):
       
   152         """this is actually used ui method to generate 'addrelated' actions from
       
   153         the schema.
       
   154 
       
   155         If you're using explicit 'addrelated' actions for an entity types, you
       
   156         should probably overrides this method to return an empty list else you
       
   157         may get some unexpected actions.
       
   158         """
       
   159         req = self.req
       
   160         eschema = entity.e_schema
       
   161         for role, rschemas in (('subject', eschema.subject_relations()),
       
   162                                ('object', eschema.object_relations())):
       
   163             for rschema in rschemas:
       
   164                 if rschema.is_final():
       
   165                     continue
       
   166                 # check the relation can be added as well
       
   167                 if role == 'subject'and not rschema.has_perm(req, 'add', fromeid=entity.eid):
       
   168                     continue
       
   169                 if role == 'object'and not rschema.has_perm(req, 'add', toeid=entity.eid):
       
   170                     continue
       
   171                 # check the target types can be added as well
       
   172                 for teschema in rschema.targets(eschema, role):
       
   173                     if not self.relation_mode(rschema, eschema, teschema, role) == 'create':
       
   174                         continue
       
   175                     if teschema.has_local_role('add') or teschema.has_perm(req, 'add'):
       
   176                         yield rschema, teschema, role
   104 
   177 
   105 
   178 
   106     def workflow_actions(self, entity, box):
   179     def workflow_actions(self, entity, box):
   107         if 'in_state' in entity.e_schema.subject_relations() and entity.in_state:
   180         if 'in_state' in entity.e_schema.subject_relations() and entity.in_state:
   108             _ = self.req._
   181             _ = self.req._