web/views/autoform.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 08 Apr 2010 13:38:36 +0200
changeset 5195 e8235b2789fc
parent 5174 78438ad513ca
child 5223 6abd6e3599f4
permissions -rw-r--r--
le patch move-pdf-export-to-cubes a été importé
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
     1
"""The automatic entity form.
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
     2
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
     3
:organization: Logilab
4212
ab6573088b4a update copyright: welcome 2010
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3874
diff changeset
     4
:copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
     5
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
1977
606923dff11b big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1969
diff changeset
     6
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
     7
"""
4160
3fbdeef9a610 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4110
diff changeset
     8
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
     9
__docformat__ = "restructuredtext en"
1702
312310ed8a2f cleanup
sylvain.thenault@logilab.fr
parents: 1607
diff changeset
    10
_ = unicode
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
    11
4932
dce5ebe5d598 add missing warn imports
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4758
diff changeset
    12
from warnings import warn
dce5ebe5d598 add missing warn imports
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4758
diff changeset
    13
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    14
from simplejson import dumps
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    15
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    16
from logilab.mtconverter import xml_escape
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    17
from logilab.common.decorators import iclassmethod, cached
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
    18
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    19
from cubicweb import typed_eid, neg_role, uilib
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    20
from cubicweb.schema import display_name
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    21
from cubicweb.view import EntityView
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    22
from cubicweb.selectors import (
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    23
    match_kwargs, match_form_params, non_final_entity,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    24
    specified_etype_implements)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    25
from cubicweb.web import stdmsgs, uicfg, eid_param, \
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    26
     form as f, formwidgets as fw, formfields as ff
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    27
from cubicweb.web.views import forms
1528
864ae7c15ef5 other fixlets
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1498
diff changeset
    28
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
    29
_AFS = uicfg.autoform_section
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
    30
_AFFK = uicfg.autoform_field_kwargs
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
    31
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
    32
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    33
# inlined form handling ########################################################
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    34
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    35
class InlinedFormField(ff.Field):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    36
    def __init__(self, view=None, **kwargs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    37
        kwargs.setdefault('label', None)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    38
        super(InlinedFormField, self).__init__(name=view.rtype, role=view.role,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    39
                                               eidparam=True, **kwargs)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    40
        self.view = view
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    41
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    42
    def render(self, form, renderer):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    43
        """render this field, which is part of form, using the given form
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    44
        renderer
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    45
        """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    46
        view = self.view
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    47
        i18nctx = 'inlined:%s.%s.%s' % (form.edited_entity.e_schema,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    48
                                        view.rtype, view.role)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    49
        return u'<div class="inline-%s-%s-slot">%s</div>' % (
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    50
            view.rtype, view.role,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    51
            view.render(i18nctx=i18nctx, row=view.cw_row, col=view.cw_col))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    52
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    53
    def form_init(self, form):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    54
        """method called before by build_context to trigger potential field
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    55
        initialization requiring the form instance
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    56
        """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    57
        if self.view.form:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    58
            self.view.form.build_context(form.formvalues)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    59
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    60
    @property
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    61
    def needs_multipart(self):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    62
        if self.view.form:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    63
            # take a look at inlined forms to check (recursively) if they need
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    64
            # multipart handling.
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    65
            return self.view.form.needs_multipart
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    66
        return False
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    67
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    68
    def has_been_modified(self, form):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    69
        return False
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    70
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    71
    def process_posted(self, form):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    72
        pass # handled by the subform
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    73
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    74
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    75
class InlineEntityEditionFormView(f.FormViewMixIn, EntityView):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    76
    """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    77
    :attr peid: the parent entity's eid hosting the inline form
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    78
    :attr rtype: the relation bridging `etype` and `peid`
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    79
    :attr role: the role played by the `peid` in the relation
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    80
    :attr pform: the parent form where this inlined form is being displayed
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    81
    """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    82
    __regid__ = 'inline-edition'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    83
    __select__ = non_final_entity() & match_kwargs('peid', 'rtype')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    84
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    85
    _select_attrs = ('peid', 'rtype', 'role', 'pform', 'etype')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    86
    removejs = "removeInlinedEntity('%s', '%s', '%s')"
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    87
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    88
    def __init__(self, *args, **kwargs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    89
        for attr in self._select_attrs:
4585
912aba7e6400 [inlined formos] don't pop attributes from kwargs, so they end-up in
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4579
diff changeset
    90
            # don't pop attributes from kwargs, so the end-up in
912aba7e6400 [inlined formos] don't pop attributes from kwargs, so they end-up in
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4579
diff changeset
    91
            # self.cw_extra_kwargs which is then passed to the edition form (see
912aba7e6400 [inlined formos] don't pop attributes from kwargs, so they end-up in
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4579
diff changeset
    92
            # the .form method)
912aba7e6400 [inlined formos] don't pop attributes from kwargs, so they end-up in
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4579
diff changeset
    93
            setattr(self, attr, kwargs.get(attr))
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    94
        super(InlineEntityEditionFormView, self).__init__(*args, **kwargs)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    95
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    96
    def _entity(self):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    97
        assert self.cw_row is not None, self
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    98
        return self.cw_rset.get_entity(self.cw_row, self.cw_col)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
    99
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   100
    @property
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   101
    @cached
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   102
    def form(self):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   103
        entity = self._entity()
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   104
        form = self._cw.vreg['forms'].select('edition', self._cw,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   105
                                             entity=entity,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   106
                                             formtype='inlined',
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   107
                                             form_renderer_id='inline',
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   108
                                             copy_nav_params=False,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   109
                                             mainform=False,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   110
                                             parent_form=self.pform,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   111
                                             **self.cw_extra_kwargs)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   112
        if self.pform is None:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   113
            form.restore_previous_post(form.session_key())
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   114
        #assert form.parent_form
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   115
        self.add_hiddens(form, entity)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   116
        return form
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   117
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   118
    def cell_call(self, row, col, i18nctx, **kwargs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   119
        """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   120
        :param peid: the parent entity's eid hosting the inline form
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   121
        :param rtype: the relation bridging `etype` and `peid`
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   122
        :param role: the role played by the `peid` in the relation
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   123
        """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   124
        entity = self._entity()
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   125
        divonclick = "restoreInlinedEntity('%s', '%s', '%s')" % (
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   126
            self.peid, self.rtype, entity.eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   127
        self.render_form(i18nctx, divonclick=divonclick, **kwargs)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   128
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   129
    def render_form(self, i18nctx, **kwargs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   130
        """fetch and render the form"""
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   131
        entity = self._entity()
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   132
        divid = '%s-%s-%s' % (self.peid, self.rtype, entity.eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   133
        title = self.form_title(entity, i18nctx)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   134
        removejs = self.removejs and self.removejs % (
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   135
            self.peid, self.rtype, entity.eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   136
        countkey = '%s_count' % self.rtype
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   137
        try:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   138
            self._cw.data[countkey] += 1
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   139
        except KeyError:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   140
            self._cw.data[countkey] = 1
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   141
        self.w(self.form.render(
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   142
            divid=divid, title=title, removejs=removejs, i18nctx=i18nctx,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   143
            counter=self._cw.data[countkey] , **kwargs))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   144
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   145
    def form_title(self, entity, i18nctx):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   146
        return self._cw.pgettext(i18nctx, entity.__regid__)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   147
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   148
    def add_hiddens(self, form, entity):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   149
        """to ease overriding (see cubes.vcsfile.views.forms for instance)"""
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   150
        iid = 'rel-%s-%s-%s' % (self.peid, self.rtype, entity.eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   151
        #  * str(self.rtype) in case it's a schema object
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   152
        #  * neged_role() since role is the for parent entity, we want the role
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   153
        #    of the inlined entity
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   154
        form.add_hidden(name=str(self.rtype), value=self.peid,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   155
                        role=neg_role(self.role), eidparam=True, id=iid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   156
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   157
    def keep_entity(self, form, entity):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   158
        if not entity.has_eid():
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   159
            return True
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   160
        # are we regenerating form because of a validation error ?
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   161
        if form.form_previous_values:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   162
            cdvalues = self._cw.list_form_param(eid_param(self.rtype, self.peid),
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   163
                                                form.form_previous_values)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   164
            if unicode(entity.eid) not in cdvalues:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   165
                return False
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   166
        return True
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   167
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   168
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   169
class InlineEntityCreationFormView(InlineEntityEditionFormView):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   170
    """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   171
    :attr etype: the entity type being created in the inline form
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   172
    """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   173
    __regid__ = 'inline-creation'
4629
1eeef3cbf528 fix 4626:c26b4df9fc90 (#703911): use can't rely on peid since it's not an actual eid when we're creating the parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4626
diff changeset
   174
    __select__ = (match_kwargs('peid', 'petype', 'rtype')
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   175
                  & specified_etype_implements('Any'))
4629
1eeef3cbf528 fix 4626:c26b4df9fc90 (#703911): use can't rely on peid since it's not an actual eid when we're creating the parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4626
diff changeset
   176
    _select_attrs = InlineEntityEditionFormView._select_attrs + ('petype',)
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   177
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   178
    @property
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   179
    def removejs(self):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   180
        entity = self._entity()
4629
1eeef3cbf528 fix 4626:c26b4df9fc90 (#703911): use can't rely on peid since it's not an actual eid when we're creating the parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4626
diff changeset
   181
        rdef = entity.e_schema.rdef(self.rtype, neg_role(self.role), self.petype)
4626
c26b4df9fc90 [forms/inline] fix #703911: add new link disappears if inline box removed. Since we've the information, we must specify the target type else we get random cardinality on ambiguous relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4625
diff changeset
   182
        card= rdef.role_cardinality(self.role)
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   183
        # when one is adding an inline entity for a relation of a single card,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   184
        # the 'add a new xxx' link disappears. If the user then cancel the addition,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   185
        # we have to make this link appears back. This is done by giving add new link
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   186
        # id to removeInlineForm.
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   187
        if card not in '?1':
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   188
            return "removeInlineForm('%%s', '%%s', '%s', '%%s')" % self.role
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   189
        divid = "addNew%s%s%s:%s" % (
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   190
            self.etype, self.rtype, self.role, self.peid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   191
        return "removeInlineForm('%%s', '%%s', '%s', '%%s', '%s')" % (
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   192
            self.role, divid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   193
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   194
    @cached
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   195
    def _entity(self):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   196
        try:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   197
            cls = self._cw.vreg['etypes'].etype_class(self.etype)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   198
        except:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   199
            self.w(self._cw._('no such entity type %s') % etype)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   200
            return
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   201
        entity = cls(self._cw)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   202
        entity.eid = self._cw.varmaker.next()
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   203
        return entity
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   204
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   205
    def call(self, i18nctx, **kwargs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   206
        self.render_form(i18nctx, **kwargs)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   207
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   208
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   209
class InlineAddNewLinkView(InlineEntityCreationFormView):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   210
    """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   211
    :attr card: the cardinality of the relation according to role of `peid`
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   212
    """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   213
    __regid__ = 'inline-addnew-link'
4629
1eeef3cbf528 fix 4626:c26b4df9fc90 (#703911): use can't rely on peid since it's not an actual eid when we're creating the parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4626
diff changeset
   214
    __select__ = (match_kwargs('peid', 'petype', 'rtype')
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   215
                  & specified_etype_implements('Any'))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   216
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   217
    _select_attrs = InlineEntityCreationFormView._select_attrs + ('card',)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   218
    form = None # no actual form wrapped
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   219
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   220
    def call(self, i18nctx, **kwargs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   221
        self._cw.set_varmaker()
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   222
        divid = "addNew%s%s%s:%s" % (self.etype, self.rtype, self.role, self.peid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   223
        self.w(u'<div class="inlinedform" id="%s" cubicweb:limit="true">'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   224
          % divid)
4629
1eeef3cbf528 fix 4626:c26b4df9fc90 (#703911): use can't rely on peid since it's not an actual eid when we're creating the parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4626
diff changeset
   225
        js = "addInlineCreationForm('%s', '%s', '%s', '%s', '%s', '%s')" % (
1eeef3cbf528 fix 4626:c26b4df9fc90 (#703911): use can't rely on peid since it's not an actual eid when we're creating the parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4626
diff changeset
   226
            self.peid, self.petype, self.etype, self.rtype, self.role, i18nctx)
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   227
        if self.pform.should_hide_add_new_relation_link(self.rtype, self.card):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   228
            js = "toggleVisibility('%s'); %s" % (divid, js)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   229
        __ = self._cw.pgettext
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   230
        self.w(u'<a class="addEntity" id="add%s:%slink" href="javascript: %s" >+ %s.</a>'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   231
          % (self.rtype, self.peid, js, __(i18nctx, 'add a %s' % self.etype)))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   232
        self.w(u'</div>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   233
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   234
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   235
# generic relations handling ##################################################
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   236
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   237
def relation_id(eid, rtype, role, reid):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   238
    """return an identifier for a relation between two entities"""
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   239
    if role == 'subject':
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   240
        return u'%s:%s:%s' % (eid, rtype, reid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   241
    return u'%s:%s:%s' % (reid, rtype, eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   242
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   243
def toggleable_relation_link(eid, nodeid, label='x'):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   244
    """return javascript snippet to delete/undelete a relation between two
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   245
    entities
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   246
    """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   247
    js = u"javascript: togglePendingDelete('%s', %s);" % (
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   248
        nodeid, xml_escape(dumps(eid)))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   249
    return u'[<a class="handle" href="%s" id="handle%s">%s</a>]' % (
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   250
        js, nodeid, label)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   251
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   252
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   253
def get_pending_inserts(req, eid=None):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   254
    """shortcut to access req's pending_insert entry
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   255
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   256
    This is where are stored relations being added while editing
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   257
    an entity. This used to be stored in a temporary cookie.
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   258
    """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   259
    pending = req.get_session_data('pending_insert') or ()
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   260
    return ['%s:%s:%s' % (subj, rel, obj) for subj, rel, obj in pending
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   261
            if eid is None or eid in (subj, obj)]
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   262
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   263
def get_pending_deletes(req, eid=None):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   264
    """shortcut to access req's pending_delete entry
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   265
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   266
    This is where are stored relations being removed while editing
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   267
    an entity. This used to be stored in a temporary cookie.
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   268
    """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   269
    pending = req.get_session_data('pending_delete') or ()
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   270
    return ['%s:%s:%s' % (subj, rel, obj) for subj, rel, obj in pending
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   271
            if eid is None or eid in (subj, obj)]
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   272
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   273
def parse_relations_descr(rdescr):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   274
    """parse a string describing some relations, in the form
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   275
    subjeids:rtype:objeids
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   276
    where subjeids and objeids are eids separeted by a underscore
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   277
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   278
    return an iterator on (subject eid, relation type, object eid) found
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   279
    """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   280
    for rstr in rdescr:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   281
        subjs, rtype, objs = rstr.split(':')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   282
        for subj in subjs.split('_'):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   283
            for obj in objs.split('_'):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   284
                yield typed_eid(subj), rtype, typed_eid(obj)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   285
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   286
def delete_relations(req, rdefs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   287
    """delete relations from the repository"""
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   288
    # FIXME convert to using the syntax subject:relation:eids
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   289
    execute = req.execute
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   290
    for subj, rtype, obj in parse_relations_descr(rdefs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   291
        rql = 'DELETE X %s Y where X eid %%(x)s, Y eid %%(y)s' % rtype
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
   292
        execute(rql, {'x': subj, 'y': obj})
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   293
    req.set_message(req._('relations deleted'))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   294
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   295
def insert_relations(req, rdefs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   296
    """insert relations into the repository"""
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   297
    execute = req.execute
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   298
    for subj, rtype, obj in parse_relations_descr(rdefs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   299
        rql = 'SET X %s Y where X eid %%(x)s, Y eid %%(y)s' % rtype
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
   300
        execute(rql, {'x': subj, 'y': obj})
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   301
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   302
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   303
class GenericRelationsWidget(fw.FieldWidget):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   304
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   305
    def render(self, form, field, renderer):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   306
        stream = []
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   307
        w = stream.append
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   308
        req = form._cw
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   309
        _ = req._
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   310
        __ = _
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   311
        eid = form.edited_entity.eid
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   312
        w(u'<table id="relatedEntities">')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   313
        for rschema, role, related in field.relations_table(form):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   314
            # already linked entities
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   315
            if related:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   316
                w(u'<tr><th class="labelCol">%s</th>' % rschema.display_name(req, role))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   317
                w(u'<td>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   318
                w(u'<ul>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   319
                for viewparams in related:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   320
                    w(u'<li class="invisible">%s<div id="span%s" class="%s">%s</div></li>'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   321
                      % (viewparams[1], viewparams[0], viewparams[2], viewparams[3]))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   322
                if not form.force_display and form.maxrelitems < len(related):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   323
                    link = (u'<span class="invisible">'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   324
                            '[<a href="javascript: window.location.href+=\'&amp;__force_display=1\'">%s</a>]'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   325
                            '</span>' % _('view all'))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   326
                    w(u'<li class="invisible">%s</li>' % link)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   327
                w(u'</ul>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   328
                w(u'</td>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   329
                w(u'</tr>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   330
        pendings = list(field.restore_pending_inserts(form))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   331
        if not pendings:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   332
            w(u'<tr><th>&#160;</th><td>&#160;</td></tr>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   333
        else:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   334
            for row in pendings:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   335
                # soon to be linked to entities
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   336
                w(u'<tr id="tr%s">' % row[1])
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   337
                w(u'<th>%s</th>' % row[3])
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   338
                w(u'<td>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   339
                w(u'<a class="handle" title="%s" href="%s">[x]</a>' %
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   340
                  (_('cancel this insert'), row[2]))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   341
                w(u'<a id="a%s" class="editionPending" href="%s">%s</a>'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   342
                  % (row[1], row[4], xml_escape(row[5])))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   343
                w(u'</td>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   344
                w(u'</tr>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   345
        w(u'<tr id="relationSelectorRow_%s" class="separator">' % eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   346
        w(u'<th class="labelCol">')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   347
        w(u'<select id="relationSelector_%s" tabindex="%s" '
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   348
          'onchange="javascript:showMatchingSelect(this.options[this.selectedIndex].value,%s);">'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   349
          % (eid, req.next_tabindex(), xml_escape(dumps(eid))))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   350
        w(u'<option value="">%s</option>' % _('select a relation'))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   351
        for i18nrtype, rschema, role in field.relations:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   352
            # more entities to link to
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   353
            w(u'<option value="%s_%s">%s</option>' % (rschema, role, i18nrtype))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   354
        w(u'</select>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   355
        w(u'</th>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   356
        w(u'<td id="unrelatedDivs_%s"></td>' % eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   357
        w(u'</tr>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   358
        w(u'</table>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   359
        return '\n'.join(stream)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   360
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   361
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   362
class GenericRelationsField(ff.Field):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   363
    widget = GenericRelationsWidget
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   364
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   365
    def __init__(self, relations, name='_cw_generic_field', **kwargs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   366
        assert relations
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   367
        kwargs['eidparam'] = True
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   368
        super(GenericRelationsField, self).__init__(name, **kwargs)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   369
        self.relations = relations
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   370
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   371
    def process_posted(self, form):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   372
        todelete = get_pending_deletes(form._cw)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   373
        if todelete:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   374
            delete_relations(form._cw, todelete)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   375
        toinsert = get_pending_inserts(form._cw)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   376
        if toinsert:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   377
            insert_relations(form._cw, toinsert)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   378
        return ()
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   379
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   380
    def relations_table(self, form):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   381
        """yiels 3-tuples (rtype, role, related_list)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   382
        where <related_list> itself a list of :
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   383
          - node_id (will be the entity element's DOM id)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   384
          - appropriate javascript's togglePendingDelete() function call
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   385
          - status 'pendingdelete' or ''
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   386
          - oneline view of related entity
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   387
        """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   388
        entity = form.edited_entity
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   389
        pending_deletes = get_pending_deletes(form._cw, entity.eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   390
        for label, rschema, role in self.relations:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   391
            related = []
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   392
            if entity.has_eid():
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   393
                rset = entity.related(rschema, role, limit=form.related_limit)
4579
19d73051eb57 [autoform] we should consider role when checking delete permission
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   394
                if role == 'subject':
19d73051eb57 [autoform] we should consider role when checking delete permission
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   395
                    haspermkwargs = {'fromeid': entity.eid}
19d73051eb57 [autoform] we should consider role when checking delete permission
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   396
                else:
19d73051eb57 [autoform] we should consider role when checking delete permission
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   397
                    haspermkwargs = {'toeid': entity.eid}
19d73051eb57 [autoform] we should consider role when checking delete permission
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   398
                if rschema.has_perm(form._cw, 'delete', **haspermkwargs):
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   399
                    toggleable_rel_link_func = toggleable_relation_link
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   400
                else:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   401
                    toggleable_rel_link_func = lambda x, y, z: u''
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   402
                for row in xrange(rset.rowcount):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   403
                    nodeid = relation_id(entity.eid, rschema, role,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   404
                                         rset[row][0])
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   405
                    if nodeid in pending_deletes:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   406
                        status, label = u'pendingDelete', '+'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   407
                    else:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   408
                        status, label = u'', 'x'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   409
                    dellink = toggleable_rel_link_func(entity.eid, nodeid, label)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   410
                    eview = form._cw.view('oneline', rset, row=row)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   411
                    related.append((nodeid, dellink, status, eview))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   412
            yield (rschema, role, related)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   413
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   414
    def restore_pending_inserts(self, form):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   415
        """used to restore edition page as it was before clicking on
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   416
        'search for <some entity type>'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   417
        """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   418
        entity = form.edited_entity
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   419
        pending_inserts = set(get_pending_inserts(form._cw, form.edited_entity.eid))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   420
        for pendingid in pending_inserts:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   421
            eidfrom, rtype, eidto = pendingid.split(':')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   422
            if typed_eid(eidfrom) == entity.eid: # subject
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   423
                label = display_name(form._cw, rtype, 'subject',
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   424
                                     entity.__regid__)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   425
                reid = eidto
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   426
            else:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   427
                label = display_name(form._cw, rtype, 'object',
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   428
                                     entity.__regid__)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   429
                reid = eidfrom
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   430
            jscall = "javascript: cancelPendingInsert('%s', 'tr', null, %s);" \
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   431
                     % (pendingid, entity.eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   432
            rset = form._cw.eid_rset(reid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   433
            eview = form._cw.view('text', rset, row=0)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   434
            yield rtype, pendingid, jscall, label, reid, eview
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   435
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   436
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   437
class UnrelatedDivs(EntityView):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   438
    __regid__ = 'unrelateddivs'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   439
    __select__ = match_form_params('relation')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   440
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   441
    def cell_call(self, row, col):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   442
        entity = self.cw_rset.get_entity(row, col)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   443
        relname, role = self._cw.form.get('relation').rsplit('_', 1)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   444
        rschema = self._cw.vreg.schema.rschema(relname)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   445
        hidden = 'hidden' in self._cw.form
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   446
        is_cell = 'is_cell' in self._cw.form
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   447
        self.w(self.build_unrelated_select_div(entity, rschema, role,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   448
                                               is_cell=is_cell, hidden=hidden))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   449
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   450
    def build_unrelated_select_div(self, entity, rschema, role,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   451
                                   is_cell=False, hidden=True):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   452
        options = []
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   453
        divid = 'div%s_%s_%s' % (rschema.type, role, entity.eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   454
        selectid = 'select%s_%s_%s' % (rschema.type, role, entity.eid)
4467
0e73d299730a fix long-waiting symetric typo: should be spelled symmetric. Add auto database migration on schema deserialization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4387
diff changeset
   455
        if rschema.symmetric or role == 'subject':
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   456
            targettypes = rschema.objects(entity.e_schema)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   457
            etypes = '/'.join(sorted(etype.display_name(self._cw) for etype in targettypes))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   458
        else:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   459
            targettypes = rschema.subjects(entity.e_schema)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   460
            etypes = '/'.join(sorted(etype.display_name(self._cw) for etype in targettypes))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   461
        etypes = uilib.cut(etypes, self._cw.property_value('navigation.short-line-size'))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   462
        options.append('<option>%s %s</option>' % (self._cw._('select a'), etypes))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   463
        options += self._get_select_options(entity, rschema, role)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   464
        options += self._get_search_options(entity, rschema, role, targettypes)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   465
        relname, role = self._cw.form.get('relation').rsplit('_', 1)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   466
        return u"""\
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   467
<div class="%s" id="%s">
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   468
  <select id="%s" onchange="javascript: addPendingInsert(this.options[this.selectedIndex], %s, %s, '%s');">
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   469
    %s
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   470
  </select>
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   471
</div>
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   472
""" % (hidden and 'hidden' or '', divid, selectid,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   473
       xml_escape(dumps(entity.eid)), is_cell and 'true' or 'null', relname,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   474
       '\n'.join(options))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   475
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   476
    def _get_select_options(self, entity, rschema, role):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   477
        """add options to search among all entities of each possible type"""
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   478
        options = []
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   479
        pending_inserts = get_pending_inserts(self._cw, entity.eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   480
        rtype = rschema.type
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   481
        form = self._cw.vreg['forms'].select('edition', self._cw, entity=entity)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   482
        field = form.field_by_name(rschema, role, entity.e_schema)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   483
        limit = self._cw.property_value('navigation.combobox-limit')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   484
        # NOTE: expect 'limit' arg on choices method of relation field
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   485
        for eview, reid in field.vocabulary(form, limit=limit):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   486
            if reid is None:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   487
                if eview: # skip blank value
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   488
                    options.append('<option class="separator">-- %s --</option>'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   489
                                   % xml_escape(eview))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   490
            elif reid != ff.INTERNAL_FIELD_VALUE:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   491
                optionid = relation_id(entity.eid, rtype, role, reid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   492
                if optionid not in pending_inserts:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   493
                    # prefix option's id with letters to make valid XHTML wise
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   494
                    options.append('<option id="id%s" value="%s">%s</option>' %
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   495
                                   (optionid, reid, xml_escape(eview)))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   496
        return options
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   497
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   498
    def _get_search_options(self, entity, rschema, role, targettypes):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   499
        """add options to search among all entities of each possible type"""
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   500
        options = []
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   501
        _ = self._cw._
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   502
        for eschema in targettypes:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   503
            mode = '%s:%s:%s:%s' % (role, entity.eid, rschema.type, eschema)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   504
            url = self._cw.build_url(entity.rest_path(), vid='search-associate',
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   505
                                 __mode=mode)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   506
            options.append((eschema.display_name(self._cw),
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   507
                            '<option value="%s">%s %s</option>' % (
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   508
                xml_escape(url), _('Search for'), eschema.display_name(self._cw))))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   509
        return [o for l, o in sorted(options)]
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   510
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   511
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   512
# The automatic entity form ####################################################
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   513
2005
e8032965f37a turn every form class into appobject. They should not be instantiated manually anymore.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1982
diff changeset
   514
class AutomaticEntityForm(forms.EntityFieldsForm):
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   515
    """base automatic form to edit any entity.
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   516
1560
7dd2a81b8bc8 [basecontrollers] add edit_relation next to edit_field, misc notes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1540
diff changeset
   517
    Designed to be fully generated from schema but highly configurable through:
3476
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   518
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   519
    * uicfg (autoform_* relation tags)
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   520
    * various standard form parameters
3476
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   521
    * overriding
2780
ad1dfc3855b0 B web/tests back to green
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2652
diff changeset
   522
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   523
    You can also easily customise it by adding/removing fields in
3476
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   524
    AutomaticEntityForm instances or by inheriting from it.
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   525
    """
3408
c92170fca813 [api] use __regid__ instead of deprecated id
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3360
diff changeset
   526
    __regid__ = 'edition'
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   527
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   528
    cwtarget = 'eformframe'
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   529
    cssclass = 'entityForm'
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   530
    copy_nav_params = True
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   531
    form_buttons = [fw.SubmitButton(),
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   532
                    fw.Button(stdmsgs.BUTTON_APPLY, cwaction='apply'),
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   533
                    fw.Button(stdmsgs.BUTTON_CANCEL, cwaction='cancel')]
3476
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   534
    # for attributes selection when searching in uicfg.autoform_section
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   535
    formtype = 'main'
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   536
    # set this to a list of [(relation, role)] if you want to explictily tell
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   537
    # which relations should be edited
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   538
    display_fields = None
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   539
4277
35cd057339b2 turn all the stuff used to handle 'generic relations' in forms into proper
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   540
    @iclassmethod
35cd057339b2 turn all the stuff used to handle 'generic relations' in forms into proper
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   541
    def field_by_name(cls_or_self, name, role=None, eschema=None):
35cd057339b2 turn all the stuff used to handle 'generic relations' in forms into proper
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   542
        """return field with the given name and role. If field is not explicitly
35cd057339b2 turn all the stuff used to handle 'generic relations' in forms into proper
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   543
        defined for the form but `eclass` is specified, guess_field will be
35cd057339b2 turn all the stuff used to handle 'generic relations' in forms into proper
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   544
        called.
35cd057339b2 turn all the stuff used to handle 'generic relations' in forms into proper
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   545
        """
35cd057339b2 turn all the stuff used to handle 'generic relations' in forms into proper
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   546
        try:
35cd057339b2 turn all the stuff used to handle 'generic relations' in forms into proper
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   547
            return super(AutomaticEntityForm, cls_or_self).field_by_name(name, role, eschema)
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   548
        except f.FieldNotFound:
4277
35cd057339b2 turn all the stuff used to handle 'generic relations' in forms into proper
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   549
            if name == '_cw_generic_field' and not isinstance(cls_or_self, type):
35cd057339b2 turn all the stuff used to handle 'generic relations' in forms into proper
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   550
                return cls_or_self._generic_relations_field()
35cd057339b2 turn all the stuff used to handle 'generic relations' in forms into proper
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   551
            raise
35cd057339b2 turn all the stuff used to handle 'generic relations' in forms into proper
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   552
3360
b02df886eb3e cleanup, reorganize
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3358
diff changeset
   553
    # base automatic entity form methods #######################################
b02df886eb3e cleanup, reorganize
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3358
diff changeset
   554
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   555
    def __init__(self, *args, **kwargs):
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   556
        super(AutomaticEntityForm, self).__init__(*args, **kwargs)
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   557
        entity = self.edited_entity
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   558
        if entity.has_eid():
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   559
            entity.complete()
3476
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   560
        for rtype, role in self.editable_attributes():
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   561
            try:
3476
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   562
                self.field_by_name(str(rtype), role)
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   563
                continue # explicitly specified
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   564
            except f.FieldNotFound:
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   565
                # has to be guessed
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   566
                try:
3476
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   567
                    field = self.field_by_name(str(rtype), role,
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   568
                                               eschema=entity.e_schema)
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   569
                    self.fields.append(field)
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   570
                except f.FieldNotFound:
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   571
                    # meta attribute such as <attr>_format
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   572
                    continue
4642
606364845c34 [auto/inline forms] reallow nested inline forms #703910
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4629
diff changeset
   573
        if self.fieldsets_in_order:
606364845c34 [auto/inline forms] reallow nested inline forms #703910
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4629
diff changeset
   574
            fsio = list(self.fieldsets_in_order)
606364845c34 [auto/inline forms] reallow nested inline forms #703910
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4629
diff changeset
   575
        else:
606364845c34 [auto/inline forms] reallow nested inline forms #703910
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4629
diff changeset
   576
            fsio = [None]
606364845c34 [auto/inline forms] reallow nested inline forms #703910
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4629
diff changeset
   577
        self.fieldsets_in_order = fsio
606364845c34 [auto/inline forms] reallow nested inline forms #703910
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4629
diff changeset
   578
        # add fields for relation whose target should have an inline form
606364845c34 [auto/inline forms] reallow nested inline forms #703910
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4629
diff changeset
   579
        for formview in self.inlined_form_views():
606364845c34 [auto/inline forms] reallow nested inline forms #703910
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4629
diff changeset
   580
            field = self._inlined_form_view_field(formview)
606364845c34 [auto/inline forms] reallow nested inline forms #703910
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4629
diff changeset
   581
            self.fields.append(field)
606364845c34 [auto/inline forms] reallow nested inline forms #703910
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4629
diff changeset
   582
            if not field.fieldset in fsio:
606364845c34 [auto/inline forms] reallow nested inline forms #703910
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4629
diff changeset
   583
                fsio.append(field.fieldset)
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   584
        if self.formtype == 'main':
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   585
            # add the generic relation field if necessary
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   586
            if entity.has_eid() and (
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   587
                self.display_fields is None or
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   588
                '_cw_generic_field' in self.display_fields):
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   589
                try:
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   590
                    field = self.field_by_name('_cw_generic_field')
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   591
                except f.FieldNotFound:
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   592
                    # no editable relation
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   593
                    pass
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   594
                else:
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   595
                    self.fields.append(field)
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   596
                    if not field.fieldset in fsio:
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   597
                        fsio.append(field.fieldset)
3418
7b49fa7e942d [api] use _cw, cw_row, cw_col, cw_rset etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3408
diff changeset
   598
        self.maxrelitems = self._cw.property_value('navigation.related-limit')
7b49fa7e942d [api] use _cw, cw_row, cw_col, cw_rset etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3408
diff changeset
   599
        self.force_display = bool(self._cw.form.get('__force_display'))
3874
7d0d4a6be046 [formfields] allow fields ordering with autoform_field_kwargs
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3689
diff changeset
   600
        fnum = len(self.fields)
7d0d4a6be046 [formfields] allow fields ordering with autoform_field_kwargs
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3689
diff changeset
   601
        self.fields.sort(key=lambda f: f.order is None and fnum or f.order)
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   602
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   603
    @property
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   604
    def related_limit(self):
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   605
        if self.force_display:
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   606
            return None
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   607
        return self.maxrelitems + 1
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   608
3360
b02df886eb3e cleanup, reorganize
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3358
diff changeset
   609
    def action(self):
b02df886eb3e cleanup, reorganize
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3358
diff changeset
   610
        """return the form's action attribute. Default to validateform if not
b02df886eb3e cleanup, reorganize
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3358
diff changeset
   611
        explicitly overriden.
b02df886eb3e cleanup, reorganize
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3358
diff changeset
   612
        """
b02df886eb3e cleanup, reorganize
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3358
diff changeset
   613
        try:
b02df886eb3e cleanup, reorganize
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3358
diff changeset
   614
            return self._action
b02df886eb3e cleanup, reorganize
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3358
diff changeset
   615
        except AttributeError:
3457
0924d0d08d60 [api] __regid__, cw_* and friends
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3451
diff changeset
   616
            return self._cw.build_url('validateform')
3360
b02df886eb3e cleanup, reorganize
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3358
diff changeset
   617
b02df886eb3e cleanup, reorganize
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3358
diff changeset
   618
    def set_action(self, value):
b02df886eb3e cleanup, reorganize
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3358
diff changeset
   619
        """override default action"""
b02df886eb3e cleanup, reorganize
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3358
diff changeset
   620
        self._action = value
b02df886eb3e cleanup, reorganize
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3358
diff changeset
   621
b02df886eb3e cleanup, reorganize
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3358
diff changeset
   622
    action = property(action, set_action)
b02df886eb3e cleanup, reorganize
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3358
diff changeset
   623
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   624
    # autoform specific fields #################################################
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   625
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   626
    def _generic_relations_field(self):
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   627
        try:
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   628
            srels_by_cat = self.srelations_by_category('generic', 'add', strict=True)
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   629
            warn('[3.6] %s: srelations_by_category is deprecated, use uicfg or '
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   630
                 'override editable_relations instead' % classid(form),
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   631
                 DeprecationWarning)
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   632
        except AttributeError:
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   633
            srels_by_cat = self.editable_relations()
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   634
        if not srels_by_cat:
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   635
            raise f.FieldNotFound('_cw_generic_field')
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   636
        fieldset = u'%s :' % self._cw.__('This %s' % self.edited_entity.e_schema)
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   637
        fieldset = fieldset.capitalize()
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   638
        return GenericRelationsField(self.editable_relations(),
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   639
                                     fieldset=fieldset, label=None)
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   640
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   641
    def _inlined_form_view_field(self, view):
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   642
        # XXX allow more customization
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   643
        kwargs = _AFFK.etype_get(self.edited_entity.e_schema, view.rtype,
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   644
                                 view.role, view.etype)
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   645
        if kwargs is None:
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   646
            kwargs = {}
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   647
        return InlinedFormField(view=view, **kwargs)
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   648
3360
b02df886eb3e cleanup, reorganize
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3358
diff changeset
   649
    # methods mapping edited entity relations to fields in the form ############
b02df886eb3e cleanup, reorganize
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3358
diff changeset
   650
3476
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   651
    def _relations_by_section(self, section, permission='add', strict=False):
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   652
        """return a list of (relation schema, target schemas, role) matching
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   653
        given category(ies) and permission
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   654
        """
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   655
        return _AFS.relations_by_section(
3476
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   656
            self.edited_entity, self.formtype, section, permission, strict)
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   657
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   658
    def editable_attributes(self, strict=False):
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   659
        """return a list of (relation schema, role) to edit for the entity"""
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   660
        if self.display_fields is not None:
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   661
            return self.display_fields
4625
d8c3a50a8ee7 this is not the form renderer responsability to check for update permissions. Move this to autoform editable_attributes relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4587
diff changeset
   662
        if self.edited_entity.has_eid() and not self.edited_entity.has_perm('update'):
d8c3a50a8ee7 this is not the form renderer responsability to check for update permissions. Move this to autoform editable_attributes relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4587
diff changeset
   663
            return []
3476
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   664
        # XXX we should simply put eid in the generated section, no?
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   665
        return [(rtype, role) for rtype, _, role in self._relations_by_section(
4758
0efdcf0fa4c7 fix code and tests broken by 4744:13a5d3a7410e (proper permission on eid/has_text/identity relations)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4642
diff changeset
   666
            'attributes', 'update', strict)]
3476
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   667
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   668
    def editable_relations(self):
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   669
        """return a sorted list of (relation's label, relation'schema, role) for
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   670
        relations in the 'relations' section
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   671
        """
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   672
        result = []
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   673
        for rschema, _, role in self._relations_by_section('relations',
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   674
                                                           strict=True):
3505
c0c7a944c00d fix dumb name error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
   675
            result.append( (rschema.display_name(self.edited_entity._cw, role,
c0c7a944c00d fix dumb name error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
   676
                                                 self.edited_entity.__regid__),
3476
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   677
                            rschema, role) )
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   678
        return sorted(result)
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   679
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   680
    def inlined_relations(self):
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   681
        """return a list of (relation schema, target schemas, role) matching
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   682
        given category(ies) and permission
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   683
        """
3476
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   684
        return self._relations_by_section('inlined')
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   685
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   686
    # inlined forms control ####################################################
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   687
3518
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   688
    def inlined_form_views(self):
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   689
        """compute and return list of inlined form views (hosting the inlined
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   690
        form object)
3518
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   691
        """
3593
987232bd79cd fix inlined forms initialization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3586
diff changeset
   692
        allformviews = []
3518
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   693
        entity = self.edited_entity
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   694
        for rschema, ttypes, role in self.inlined_relations():
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   695
            # show inline forms only if there's one possible target type
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   696
            # for rschema
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   697
            if len(ttypes) != 1:
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   698
                self.warning('entity related by the %s relation should have '
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   699
                             'inlined form but there is multiple target types, '
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   700
                             'dunno what to do', rschema)
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   701
                continue
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   702
            ttype = ttypes[0].type
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   703
            if self.should_inline_relation_form(rschema, ttype, role):
3593
987232bd79cd fix inlined forms initialization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3586
diff changeset
   704
                formviews = list(self.inline_edition_form_view(rschema, ttype, role))
4519
cce343c7d18a fix bug w/ object relation used as inlined form
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4518
diff changeset
   705
                card = rschema.role_rdef(entity.e_schema, ttype, role).role_cardinality(role)
3518
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   706
                # there is no related entity and we need at least one: we need to
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   707
                # display one explicit inline-creation view
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   708
                if self.should_display_inline_creation_form(rschema, formviews, card):
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   709
                    formviews += self.inline_creation_form_view(rschema, ttype, role)
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   710
                # we can create more than one related entity, we thus display a link
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   711
                # to add new related entities
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   712
                if self.should_display_add_new_relation_link(rschema, formviews, card):
4083
3b285889b8e9 3.6 api update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4082
diff changeset
   713
                    addnewlink = self._cw.vreg['views'].select(
4082
c7117119e215 3.6 api update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4015
diff changeset
   714
                        'inline-addnew-link', self._cw,
4629
1eeef3cbf528 fix 4626:c26b4df9fc90 (#703911): use can't rely on peid since it's not an actual eid when we're creating the parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4626
diff changeset
   715
                        etype=ttype, rtype=rschema, role=role, card=card,
1eeef3cbf528 fix 4626:c26b4df9fc90 (#703911): use can't rely on peid since it's not an actual eid when we're creating the parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4626
diff changeset
   716
                        peid=self.edited_entity.eid,
1eeef3cbf528 fix 4626:c26b4df9fc90 (#703911): use can't rely on peid since it's not an actual eid when we're creating the parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4626
diff changeset
   717
                        petype=self.edited_entity.e_schema, pform=self)
3518
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   718
                    formviews.append(addnewlink)
3593
987232bd79cd fix inlined forms initialization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3586
diff changeset
   719
                allformviews += formviews
987232bd79cd fix inlined forms initialization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3586
diff changeset
   720
        return allformviews
3518
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   721
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   722
    def should_inline_relation_form(self, rschema, targettype, role):
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   723
        """return true if the given relation with entity has role and a
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   724
        targettype target should be inlined
3483
feedfe5d4932 [autoform] no need to recheck inlined tag here
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3482
diff changeset
   725
feedfe5d4932 [autoform] no need to recheck inlined tag here
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3482
diff changeset
   726
        At this point we now relation has inlined_attributes tag (eg is returned
feedfe5d4932 [autoform] no need to recheck inlined tag here
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3482
diff changeset
   727
        by `inlined_relations()`. Overrides this for more finer control.
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   728
        """
3595
b61f1c5e6c55 at this point we know this is true
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3594
diff changeset
   729
        return True
3358
0cddc4d8cad8 [forms] do similar refactoring for inline edition than for inline creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3356
diff changeset
   730
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   731
    def should_display_inline_creation_form(self, rschema, existant, card):
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   732
        """return true if a creation form should be inlined
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   733
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   734
        by default true if there is no related entity and we need at least one
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   735
        """
3418
7b49fa7e942d [api] use _cw, cw_row, cw_col, cw_rset etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3408
diff changeset
   736
        return not existant and card in '1+' or self._cw.form.has_key('force_%s_display' % rschema)
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   737
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   738
    def should_display_add_new_relation_link(self, rschema, existant, card):
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   739
        """return true if we should add a link to add a new creation form
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   740
        (through ajax call)
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   741
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   742
        by default true if there is no related entity or if the relation has
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   743
        multiple cardinality
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   744
        """
4160
3fbdeef9a610 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4110
diff changeset
   745
        return not existant or card in '+*' # XXX add target type permisssions
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   746
3332
91cff87c368f introduced to ease overriding for fancy stuff...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3293
diff changeset
   747
    def should_hide_add_new_relation_link(self, rschema, card):
91cff87c368f introduced to ease overriding for fancy stuff...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3293
diff changeset
   748
        """return true if once an inlined creation form is added, the 'add new'
91cff87c368f introduced to ease overriding for fancy stuff...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3293
diff changeset
   749
        link should be hidden
91cff87c368f introduced to ease overriding for fancy stuff...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3293
diff changeset
   750
91cff87c368f introduced to ease overriding for fancy stuff...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3293
diff changeset
   751
        by default true if the relation has single cardinality
91cff87c368f introduced to ease overriding for fancy stuff...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3293
diff changeset
   752
        """
91cff87c368f introduced to ease overriding for fancy stuff...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3293
diff changeset
   753
        return card in '1?'
91cff87c368f introduced to ease overriding for fancy stuff...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3293
diff changeset
   754
3518
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   755
    def inline_edition_form_view(self, rschema, ttype, role):
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   756
        """yield inline form views for already related entities through the
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   757
        given relation
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   758
        """
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   759
        entity = self.edited_entity
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   760
        related = entity.has_eid() and entity.related(rschema, role)
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   761
        if related:
3524
a3431f4e2f40 backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3505 3521
diff changeset
   762
            vvreg = self._cw.vreg['views']
3518
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   763
            # display inline-edition view for all existing related entities
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   764
            for i, relentity in enumerate(related.entities()):
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   765
                if relentity.has_perm('update'):
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   766
                    yield vvreg.select('inline-edition', self._cw,
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   767
                                       rset=related, row=i, col=0,
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   768
                                       etype=ttype, rtype=rschema, role=role,
3518
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   769
                                       peid=entity.eid, pform=self)
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   770
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   771
    def inline_creation_form_view(self, rschema, ttype, role):
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   772
        """yield inline form views to a newly related (hence created) entity
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   773
        through the given relation
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   774
        """
3524
a3431f4e2f40 backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3505 3521
diff changeset
   775
        yield self._cw.vreg['views'].select('inline-creation', self._cw,
a3431f4e2f40 backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3505 3521
diff changeset
   776
                                            etype=ttype, rtype=rschema, role=role,
4629
1eeef3cbf528 fix 4626:c26b4df9fc90 (#703911): use can't rely on peid since it's not an actual eid when we're creating the parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4626
diff changeset
   777
                                            peid=self.edited_entity.eid,
1eeef3cbf528 fix 4626:c26b4df9fc90 (#703911): use can't rely on peid since it's not an actual eid when we're creating the parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4626
diff changeset
   778
                                            petype=self.edited_entity.e_schema,
1eeef3cbf528 fix 4626:c26b4df9fc90 (#703911): use can't rely on peid since it's not an actual eid when we're creating the parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4626
diff changeset
   779
                                            pform=self)
2652
3753f3a07ca1 [refactoring] moved rtags specification in web/views
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2143
diff changeset
   780
3753f3a07ca1 [refactoring] moved rtags specification in web/views
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2143
diff changeset
   781
3753f3a07ca1 [refactoring] moved rtags specification in web/views
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2143
diff changeset
   782
## default form ui configuration ##############################################
3753f3a07ca1 [refactoring] moved rtags specification in web/views
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2143
diff changeset
   783
3753f3a07ca1 [refactoring] moved rtags specification in web/views
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2143
diff changeset
   784
# use primary and not generated for eid since it has to be an hidden
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   785
_AFS.tag_attribute(('*', 'eid'), 'main', 'attributes')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   786
_AFS.tag_attribute(('*', 'eid'), 'muledit', 'attributes')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   787
_AFS.tag_attribute(('*', 'description'), 'main', 'attributes')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   788
_AFS.tag_attribute(('*', 'creation_date'), 'main', 'metadata')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   789
_AFS.tag_attribute(('*', 'modification_date'), 'main', 'metadata')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   790
_AFS.tag_attribute(('*', 'cwuri'), 'main', 'metadata')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   791
_AFS.tag_attribute(('*', 'has_text'), 'main', 'hidden')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   792
_AFS.tag_subject_of(('*', 'in_state', '*'), 'main', 'hidden')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   793
_AFS.tag_subject_of(('*', 'owned_by', '*'), 'main', 'metadata')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   794
_AFS.tag_subject_of(('*', 'created_by', '*'), 'main', 'metadata')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   795
_AFS.tag_subject_of(('*', 'require_permission', '*'), 'main', 'hidden')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   796
_AFS.tag_subject_of(('*', 'by_transition', '*'), 'main', 'attributes')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   797
_AFS.tag_subject_of(('*', 'by_transition', '*'), 'muledit', 'attributes')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   798
_AFS.tag_object_of(('*', 'by_transition', '*'), 'main', 'hidden')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   799
_AFS.tag_object_of(('*', 'from_state', '*'), 'main', 'hidden')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   800
_AFS.tag_object_of(('*', 'to_state', '*'), 'main', 'hidden')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   801
_AFS.tag_subject_of(('*', 'wf_info_for', '*'), 'main', 'attributes')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   802
_AFS.tag_subject_of(('*', 'wf_info_for', '*'), 'muledit', 'attributes')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   803
_AFS.tag_object_of(('*', 'wf_info_for', '*'), 'main', 'hidden')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   804
_AFS.tag_subject_of(('CWPermission', 'require_group', '*'), 'main', 'attributes')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   805
_AFS.tag_subject_of(('CWPermission', 'require_group', '*'), 'muledit', 'attributes')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   806
_AFS.tag_attribute(('CWEType', 'final'), 'main', 'hidden')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   807
_AFS.tag_attribute(('CWRType', 'final'), 'main', 'hidden')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   808
_AFS.tag_attribute(('CWUser', 'firstname'), 'main', 'attributes')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   809
_AFS.tag_attribute(('CWUser', 'surname'), 'main', 'attributes')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   810
_AFS.tag_attribute(('CWUser', 'last_login_time'), 'main', 'metadata')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   811
_AFS.tag_subject_of(('CWUser', 'in_group', '*'), 'main', 'attributes')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   812
_AFS.tag_subject_of(('CWUser', 'in_group', '*'), 'muledit', 'attributes')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   813
_AFS.tag_subject_of(('*', 'primary_email', '*'), 'main', 'relations')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   814
_AFS.tag_subject_of(('*', 'use_email', '*'), 'main', 'inlined')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   815
_AFS.tag_subject_of(('CWRelation', 'relation_type', '*'), 'main', 'inlined')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   816
_AFS.tag_subject_of(('CWRelation', 'from_entity', '*'), 'main', 'inlined')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   817
_AFS.tag_subject_of(('CWRelation', 'to_entity', '*'), 'main', 'inlined')
2652
3753f3a07ca1 [refactoring] moved rtags specification in web/views
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2143
diff changeset
   818
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   819
_AFFK.tag_attribute(('RQLExpression', 'expression'),
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   820
                    {'widget': fw.TextInput})
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   821
_AFFK.tag_subject_of(('TrInfo', 'wf_info_for', '*'),
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   822
                     {'widget': fw.HiddenInput})
2652
3753f3a07ca1 [refactoring] moved rtags specification in web/views
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2143
diff changeset
   823
4105
de31c3afe975 fix 3.6 bug
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4083
diff changeset
   824
def registration_callback(vreg):
de31c3afe975 fix 3.6 bug
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4083
diff changeset
   825
    global etype_relation_field
de31c3afe975 fix 3.6 bug
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4083
diff changeset
   826
de31c3afe975 fix 3.6 bug
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4083
diff changeset
   827
    def etype_relation_field(etype, rtype, role='subject'):
de31c3afe975 fix 3.6 bug
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4083
diff changeset
   828
        eschema = vreg.schema.eschema(etype)
de31c3afe975 fix 3.6 bug
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4083
diff changeset
   829
        return AutomaticEntityForm.field_by_name(rtype, role, eschema)
4110
8728d8c95985 [mq]: fix_for_forms
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 4105
diff changeset
   830
8728d8c95985 [mq]: fix_for_forms
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 4105
diff changeset
   831
    vreg.register_all(globals().values(), __name__)