web/views/reledit.py
author Aurelien Campeas <aurelien.campeas@logilab.fr>
Fri, 02 Jul 2010 15:26:59 +0200
changeset 5869 8a129b3a5aff
child 5874 6afc88f439e8
permissions -rw-r--r--
reledit refactoring * js handling rewritten to exploit all form capabilities (such as file upload ...) * attribute-like composite relations (one ttype, cardinality in '?1' from composite side) are more cutely handled, with a 'add'/'delete' additional actions/icons * a reledit_ctrl rtag to finely control: reloading, edition and default values * a proper chapter in the documentation (book) * many bugfixes
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5869
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
     1
import copy
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
     2
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
     3
from logilab.mtconverter import xml_escape
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
     4
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
     5
from cubicweb import neg_role
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
     6
from cubicweb.schema import display_name
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
     7
from cubicweb.utils import json
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
     8
from cubicweb.selectors import non_final_entity, match_kwargs
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
     9
from cubicweb.view import EntityView
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    10
from cubicweb.web import uicfg, stdmsgs
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    11
from cubicweb.web.form import FormViewMixIn, FieldNotFound
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    12
from cubicweb.web.formwidgets import Button, SubmitButton
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    13
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    14
class DummyForm(object):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    15
    __slots__ = ('event_args',)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    16
    def form_render(self, **_args):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    17
        return u''
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    18
    def render(self, *_args, **_kwargs):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    19
        return u''
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    20
    def append_field(self, *args):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    21
        pass
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    22
    def field_by_name(self, rtype, role, eschema=None):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    23
        return None
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    24
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    25
class ClickAndEditFormView(FormViewMixIn, EntityView):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    26
    __regid__ = 'doreledit'
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    27
    __select__ = non_final_entity() & match_kwargs('rtype')
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    28
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    29
    # ui side continuations
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    30
    _onclick = (u"cw.reledit.loadInlineEditionForm('%(formid)s', %(eid)s, '%(rtype)s', '%(role)s', "
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    31
                "'%(divid)s', %(reload)s, '%(vid)s', '%(default_value)s');")
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    32
    _cancelclick = "cw.reledit.cleanupAfterCancel('%s')"
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    33
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    34
    # ui side actions/buttons
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    35
    _addzone = (u'<img title="%(msg)s" src="data/plus.png" '
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    36
                u'alt="%(msg)s"/>')
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    37
    _addmsg = _('click to add a value')
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    38
    _deletezone = (u'<img title="%(msg)s" src="data/cancel.png" alt="%(msg)s"/>')
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    39
    _deletemsg = _('click to delete this value')
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    40
    _editzone = (u'<img title="%(msg)s" src="data/pen_icon.png" alt="%(msg)s"/>')
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    41
    _editzonemsg = _('click to edit this field')
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    42
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    43
    # default relation vids according to cardinality
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    44
    _one_rvid = 'incontext'
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    45
    _many_rvid = 'csv'
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    46
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    47
    def cell_call(self, row, col, rtype=None, role='subject',
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    48
                  reload=False, # controls reloading the whole page after change
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    49
                                # boolean, eid (to redirect), or
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    50
                                # function taking the subject entity & returning a boolean or an eid
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    51
                  rvid=None,    # vid to be applied to other side of rtype (non final relations only)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    52
                  default_value=None,
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    53
                  formid=None
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    54
                  ):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    55
        """display field to edit entity's `rtype` relation on click"""
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    56
        assert rtype
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    57
        assert role in ('subject', 'object'), '%s is not an acceptable role value' % role
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    58
        if self.__regid__ == 'doreledit':
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    59
            assert formid
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    60
        self._cw.add_js('cubicweb.reledit.js')
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    61
        if formid:
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    62
            self._cw.add_js('cubicweb.edition.js')
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    63
        self._cw.add_css('cubicweb.form.css')
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    64
        entity = self.cw_rset.get_entity(row, col)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    65
        rschema = self._cw.vreg.schema[rtype]
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    66
        reload = self._compute_reload(entity, rschema, role, reload)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    67
        default_value = self._compute_default_value(entity, rschema, role, default_value)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    68
        # compute value, checking perms, build & display form
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    69
        divid = self._build_divid(rtype, role, entity.eid)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    70
        if rschema.final:
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    71
            value = entity.printable_value(rtype)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    72
            form, renderer = self._build_form(entity, rtype, role, divid, 'base',
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    73
                                              default_value, reload)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    74
            if not self._should_edit_attribute(entity, rschema, form):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    75
                self.w(value)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    76
                return
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    77
            value = value or default_value
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    78
            field = form.field_by_name(rtype, role, entity.e_schema)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    79
            form.append_field(field)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    80
            self.view_form(divid, value, form, renderer)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    81
        else:
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    82
            rvid = self._compute_best_vid(entity.e_schema, rschema, role)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    83
            related_rset = entity.related(rtype, role)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    84
            if related_rset:
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    85
                value = self._cw.view(rvid, related_rset)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    86
            else:
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    87
                value = default_value
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    88
            ttypes = self._compute_ttypes(rschema, role)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    89
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    90
            if not self._should_edit_relation(entity, rschema, role):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    91
                self.w(value)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    92
                return
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    93
            # this is for attribute-like composites (1 target type, 1 related entity at most)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    94
            edit_related = self._may_edit_related_entity(related_rset, entity, rschema, role, ttypes)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    95
            delete_related = edit_related and self._may_delete_related(related_rset, entity, rschema, role)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    96
            add_related = self._may_add_related(related_rset, entity, rschema, role, ttypes)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    97
            # compute formid
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    98
            if len(ttypes) > 1: # redundant safety belt
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    99
                formid = 'base'
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   100
            else:
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   101
                afs = uicfg.autoform_section.etype_get(entity.e_schema, rschema, role, ttypes[0])
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   102
                # is there an afs spec that says we should edit
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   103
                # the rschema as an attribute ?
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   104
                if afs and 'main_attributes' in afs:
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   105
                    formid = 'base'
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   106
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   107
            form, renderer = self._build_form(entity, rtype, role, divid, formid, default_value,
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   108
                                              reload, dict(vid=rvid),
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   109
                                              edit_related, add_related and ttypes[0])
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   110
            self.view_form(divid, value, form, renderer, edit_related,
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   111
                           delete_related, add_related)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   112
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   113
    def _compute_best_vid(self, eschema, rschema, role):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   114
        if eschema.rdef(rschema, role).role_cardinality(role) in '+*':
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   115
            return self._many_rvid
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   116
        return self._one_rvid
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   117
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   118
    def _compute_ttypes(self, rschema, role):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   119
        dual_role = neg_role(role)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   120
        return getattr(rschema, '%ss' % dual_role)()
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   121
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   122
    def _compute_reload(self, entity, rschema, role, reload):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   123
        rule = uicfg.reledit_ctrl.etype_get(entity.e_schema.type, rschema.type, role, '*')
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   124
        ctrl_reload = rule.get('reload', reload)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   125
        if callable(ctrl_reload):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   126
            ctrl_reload = ctrl_reload(entity)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   127
        if isinstance(ctrl_reload, int) and ctrl_reload > 1: # not True/False
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   128
            ctrl_reload = self._cw.build_url(ctrl_reload)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   129
        return ctrl_reload
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   130
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   131
    def _compute_default_value(self, entity, rschema, role, default_value):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   132
        etype = entity.e_schema.type
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   133
        rule = uicfg.reledit_ctrl.etype_get(etype, rschema.type, role, '*')
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   134
        ctrl_default = rule.get('default_value', default_value)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   135
        if ctrl_default:
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   136
            return ctrl_default
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   137
        if default_value is None:
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   138
            return xml_escape(self._cw._('<%s not specified>') %
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   139
                              display_name(self._cw, rschema.type, role))
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   140
        return default_value
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   141
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   142
    def _is_composite(self, eschema, rschema, role):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   143
        return eschema.rdef(rschema, role).composite == role
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   144
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   145
    def _may_add_related(self, rset, entity, rschema, role, ttypes):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   146
        """ ok for attribute-like composite entities """
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   147
        if self._is_composite(entity.e_schema, rschema, role):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   148
            if len(ttypes) > 1: # wrong cardinality: do not handle
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   149
                return False
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   150
            ttype = ttypes[0]
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   151
            if rset:
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   152
                eschema = entity.e_schema
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   153
                if role == 'subject':
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   154
                    source, target = eschema.type, ttype
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   155
                else:
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   156
                    source, target = ttype, eschema.type
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   157
                card = rschema.rdef(source, target).role_cardinality(role)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   158
                if card in '1?':
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   159
                    return False
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   160
            if rschema.has_perm(self._cw, 'add', toetype=ttype):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   161
                return True
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   162
        return False
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   163
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   164
    def _may_edit_related_entity(self, related_rset, entity, rschema, role, ttypes):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   165
        """ controls the edition of the related entity """
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   166
        if len(ttypes) > 1:
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   167
            return False
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   168
        if not self._is_composite(entity.e_schema, rschema, role):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   169
            return False
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   170
        if len(related_rset.rows) != 1:
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   171
            return False
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   172
        return related_rset.get_entity(0, 0).cw_has_perm('update')
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   173
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   174
    def _may_delete_related(self, related_rset, entity, rschema, role):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   175
        # we assume may_edit_related
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   176
        assert len(related_rset.rows) == 1
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   177
        kwargs = {'fromeid': entity.eid} if role == 'subject' else {'toeid': entity.eid}
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   178
        if not rschema.has_perm(self._cw, 'delete', **kwargs):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   179
            return False
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   180
        for related_entity in related_rset.entities():
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   181
            if not related_entity.cw_has_perm('delete'):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   182
                return False
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   183
        return True
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   184
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   185
    def _build_edit_zone(self):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   186
        return self._editzone % {'msg' : xml_escape(_(self._cw._(self._editzonemsg)))}
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   187
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   188
    def _build_delete_zone(self):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   189
        return self._deletezone % {'msg': xml_escape(self._cw._(self._deletemsg))}
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   190
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   191
    def _build_add_zone(self):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   192
        return self._addzone % {'msg': xml_escape(self._cw._(self._addmsg))}
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   193
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   194
    def _build_divid(self, rtype, role, entity_eid):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   195
        """ builds an id for the root div of a reledit widget """
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   196
        return '%s-%s-%s' % (rtype, role, entity_eid)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   197
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   198
    def _build_args(self, entity, rtype, role, formid, default_value, reload,
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   199
                    extradata=None):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   200
        divid = self._build_divid(rtype, role, entity.eid)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   201
        event_args = {'divid' : divid, 'eid' : entity.eid, 'rtype' : rtype, 'formid': formid,
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   202
                      'reload' : json.dumps(reload), 'default_value' : default_value,
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   203
                      'role' : role, 'vid' : u''}
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   204
        if extradata:
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   205
            event_args.update(extradata)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   206
        return event_args
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   207
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   208
    def _build_form(self, entity, rtype, role, divid, formid, default_value, reload,
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   209
                    extradata=None, edit_related=False, add_related=False, **formargs):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   210
        event_args = self._build_args(entity, rtype, role, formid, default_value,
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   211
                                      reload, extradata)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   212
        cancelclick = self._cancelclick % divid
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   213
        if edit_related:
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   214
            display_fields = None
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   215
            display_label = True
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   216
            related_entity = entity.related(rtype, role).get_entity(0, 0)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   217
            self._cw.form['eid'] = related_entity.eid
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   218
        elif add_related:
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   219
            display_fields = None
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   220
            display_label = True
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   221
            _new_entity = self._cw.vreg['etypes'].etype_class(add_related)(self._cw)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   222
            _new_entity.eid = self._cw.varmaker.next()
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   223
            related_entity = _new_entity
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   224
            self._cw.form['__linkto'] = '%s:%s:%s' % (rtype, entity.eid, neg_role(role))
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   225
        else: # base case: edition/attribute relation
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   226
            display_fields = [(rtype, role)]
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   227
            display_label = False
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   228
            related_entity = entity
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   229
        form = self._cw.vreg['forms'].select(
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   230
            formid, self._cw, rset=related_entity.as_rset(), entity=related_entity, domid='%s-form' % divid,
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   231
            display_fields=display_fields, formtype='inlined',
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   232
            action=self._cw.build_url('validateform?__onsuccess=window.parent.cw.reledit.onSuccess'),
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   233
            cwtarget='eformframe', cssstyle='display: none',
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   234
            **formargs)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   235
        # pass reledit arguments
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   236
        for pname, pvalue in event_args.iteritems():
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   237
            form.add_hidden('__reledit|' + pname, pvalue)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   238
        # handle buttons
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   239
        if form.form_buttons: # edition, delete
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   240
            form_buttons = []
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   241
            for button in form.form_buttons:
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   242
                if not button.label.endswith('apply'):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   243
                    if button.label.endswith('cancel'):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   244
                        button = copy.deepcopy(button)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   245
                        button.cwaction = None
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   246
                        button.onclick = cancelclick
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   247
                    form_buttons.append(button)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   248
            form.form_buttons = form_buttons
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   249
        else: # base
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   250
            form.form_buttons = [SubmitButton(),
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   251
                                 Button(stdmsgs.BUTTON_CANCEL, onclick=cancelclick)]
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   252
        form.event_args = event_args
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   253
        renderer = self._cw.vreg['formrenderers'].select(
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   254
            'base', self._cw, entity=related_entity, display_label=display_label,
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   255
            display_help=False, table_class='',
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   256
            button_bar_class='buttonbar', display_progress_div=False)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   257
        return form, renderer
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   258
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   259
    def _should_edit_attribute(self, entity, rschema, form):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   260
        # examine rtags
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   261
        noedit = uicfg.reledit_ctrl.etype_get(entity.e_schema, rschema.type, 'subject').get('noedit', False)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   262
        if noedit:
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   263
            return False
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   264
        rdef = entity.e_schema.rdef(rschema)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   265
        afs = uicfg.autoform_section.etype_get(entity.__regid__, rschema, 'subject', rdef.object)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   266
        if 'main_hidden' in  afs:
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   267
            return False
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   268
        # check permissions
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   269
        if not entity.cw_has_perm('update'):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   270
            return False
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   271
        rdef = entity.e_schema.rdef(rschema)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   272
        if not rdef.has_perm(self._cw, 'update', eid=entity.eid):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   273
            return False
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   274
        # XXX ?
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   275
        try:
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   276
            form.field_by_name(str(rschema), 'subject', entity.e_schema)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   277
        except FieldNotFound:
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   278
            return False
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   279
        return True
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   280
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   281
    def _should_edit_relation(self, entity, rschema, role):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   282
        # examine rtags
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   283
        rtype = rschema.type
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   284
        noedit = uicfg.reledit_ctrl.etype_get(entity.e_schema, rtype, role).get('noedit', False)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   285
        if noedit:
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   286
            return False
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   287
        rdef = entity.e_schema.rdef(rschema, role)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   288
        afs = uicfg.autoform_section.etype_get(
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   289
            entity.__regid__, rschema, role, rdef.object)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   290
        if 'main_hidden' in afs:
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   291
            return False
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   292
        perm_args = {'fromeid': entity.eid} if role == 'subject' else {'toeid': entity.eid}
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   293
        return rschema.has_perm(self._cw, 'add', **perm_args)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   294
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   295
    def view_form(self, divid, value, form=None, renderer=None,
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   296
                  edit_related=False, delete_related=False, add_related=False):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   297
        w = self.w
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   298
        w(u'<div id="%(id)s-reledit" onmouseout="%(out)s" onmouseover="%(over)s">' %
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   299
          {'id': divid,
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   300
           'out': "jQuery('#%s').addClass('hidden')" % divid,
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   301
           'over': "jQuery('#%s').removeClass('hidden')" % divid})
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   302
        w(u'<div id="%s-value" class="editableFieldValue">' % divid)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   303
        w(value)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   304
        w(u'</div>')
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   305
        w(form.render(renderer=renderer))
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   306
        w(u'<div id="%s" class="editableField hidden">' % divid)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   307
        args = form.event_args.copy()
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   308
        if not add_related: # excludes edition
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   309
            args['formid'] = 'edition'
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   310
            w(u'<div id="%s-update" class="editableField" onclick="%s" title="%s">' %
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   311
              (divid, xml_escape(self._onclick % args), self._cw._(self._editzonemsg)))
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   312
            w(self._build_edit_zone())
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   313
            w(u'</div>')
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   314
        else:
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   315
            args['formid'] = 'edition'
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   316
            w(u'<div id="%s-add" class="editableField" onclick="%s" title="%s">' %
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   317
              (divid, xml_escape(self._onclick % args), self._cw._(self._addmsg)))
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   318
            w(self._build_add_zone())
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   319
            w(u'</div>')
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   320
        if delete_related:
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   321
            args['formid'] = 'deleteconf'
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   322
            w(u'<div id="%s-add" class="editableField" onclick="%s" title="%s">' %
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   323
              (divid, xml_escape(self._onclick % args), self._cw._(self._deletemsg)))
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   324
            w(self._build_delete_zone())
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   325
            w(u'</div>')
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   326
        w(u'</div>')
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   327
        w(u'</div>')
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   328
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   329
class AutoClickAndEditFormView(ClickAndEditFormView):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   330
    __regid__ = 'reledit'
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   331
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   332
    def _build_form(self, entity, rtype, role, divid, formid, default_value, reload,
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   333
                  extradata=None, edit_related=False, add_related=False, **formargs):
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   334
        event_args = self._build_args(entity, rtype, role, 'base', default_value,
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   335
                                      reload, extradata)
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   336
        form = DummyForm()
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   337
        form.event_args = event_args
8a129b3a5aff reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   338
        return form, None