web/views/autoform.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 01 Jul 2010 17:06:37 +0200
changeset 5849 9db65b381028
parent 5774 0d792bceb25d
parent 5835 4125a8021956
child 5940 0e3ae19b181a
permissions -rw-r--r--
backport stable
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
     1
# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
     2
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
     3
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
     4
# This file is part of CubicWeb.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
     5
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
     6
# CubicWeb is free software: you can redistribute it and/or modify it under the
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
     7
# terms of the GNU Lesser General Public License as published by the Free
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
     8
# Software Foundation, either version 2.1 of the License, or (at your option)
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
     9
# any later version.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
    10
#
5424
8ecbcbff9777 replace logilab-common by CubicWeb in disclaimer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5421
diff changeset
    11
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
    12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
    13
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
    14
# details.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
    15
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
    16
# You should have received a copy of the GNU Lesser General Public License along
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5389
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    18
"""
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    19
.. autodocstring:: cubicweb.web.views.autoform::AutomaticEntityForm
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    20
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    21
Configuration through uicfg
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    22
```````````````````````````
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    23
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    24
It is possible to manage which and how an entity's attributes and relations
5463
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5426
diff changeset
    25
will be edited in the various contexts where the automatic entity form is used
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    26
by using proper uicfg tags.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    27
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    28
The details of the uicfg syntax can be found in the :ref:`uicfg` chapter.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    29
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    30
Possible relation tags that apply to entity forms are detailled below.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    31
They are all in the :mod:`cubicweb.web.uicfg` module.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    32
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    33
Attributes/relations display location
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    34
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    35
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    36
``autoform_section`` specifies where to display a relation in form for a given
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    37
form type.  :meth:`tag_attribute`, :meth:`tag_subject_of` and
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    38
:meth:`tag_object_of` methods for this relation tag expect two arguments
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    39
additionally to the relation key: a `formtype` and a `section`.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    40
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    41
`formtype` may be one of:
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    42
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    43
* 'main', the main entity form (e.g. the one you get when creating or editing an
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    44
  entity)
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    45
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    46
* 'inlined', the form for an entity inlined into another form
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    47
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    48
* 'muledit', the table form when editing multiple entities of the same type
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    49
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    50
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    51
section may be one of:
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    52
5463
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5426
diff changeset
    53
* 'hidden', don't display (not even in a hidden input)
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    54
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    55
* 'attributes', display in the attributes section
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    56
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    57
* 'relations', display in the relations section, using the generic relation
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    58
  selector combobox (available in main form only, and not usable for attributes)
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    59
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    60
* 'inlined', display target entity of the relation into an inlined form
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    61
  (available in main form only, and not for attributes)
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
    62
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    63
By default, mandatory relations are displayed in the 'attributes' section,
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    64
others in 'relations' section.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    65
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    66
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    67
Change default fields
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    68
^^^^^^^^^^^^^^^^^^^^^
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    69
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    70
Use ``autoform_field`` to replace the default field class to use for a relation
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    71
or attribute. You can put either a field class or instance as value (put a class
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    72
whenether it's possible).
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    73
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    74
.. Warning::
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    75
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    76
   `autoform_field_kwargs` should usually be used instead of
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    77
   `autoform_field`. If you put a field instance into `autoform_field`,
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    78
   `autoform_field_kwargs` values for this relation will be ignored.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    79
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    80
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    81
Customize field options
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    82
^^^^^^^^^^^^^^^^^^^^^^^
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    83
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    84
In order to customize field options (see :class:`~cubicweb.web.formfields.Field`
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    85
for a detailed list of options), use `autoform_field_kwargs`. This rtag takes
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    86
a dictionary as arguments, that will be given to the field's contructor.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    87
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    88
You can then put in that dictionary any arguments supported by the field
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    89
class. For instance:
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    90
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    91
.. sourcecode:: python
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    92
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    93
   # Change the content of the combobox. Here `ticket_done_in_choices` is a
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    94
   # function which returns a list of elements to populate the combobox
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    95
   autoform_field_kwargs.tag_subject_of(('Ticket', 'done_in', '*'),
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    96
                                        {'sort': False,
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    97
                                         'choices': ticket_done_in_choices})
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    98
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
    99
   # Force usage of a TextInput widget for the expression attribute of
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
   100
   # RQLExpression entities
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
   101
   autoform_field_kwargs.tag_attribute(('RQLExpression', 'expression'),
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
   102
                                       {'widget': fw.TextInput})
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
   103
5463
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5426
diff changeset
   104
.. note::
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
   105
5463
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5426
diff changeset
   106
   the widget argument can be either a class or an instance (the later
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5426
diff changeset
   107
   case being convenient to pass the Widget specific initialisation
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5426
diff changeset
   108
   options)
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
   109
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
   110
Overriding permissions
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
   111
^^^^^^^^^^^^^^^^^^^^^^
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
   112
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
   113
The `autoform_permissions_overrides` rtag provides a way to by-pass security
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
   114
checking for dark-corner case where it can't be verified properly.
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
   115
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
   116
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
   117
.. More about inlined forms
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
   118
.. Controlling the generic relation fields
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   119
"""
4160
3fbdeef9a610 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4110
diff changeset
   120
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   121
__docformat__ = "restructuredtext en"
1702
312310ed8a2f cleanup
sylvain.thenault@logilab.fr
parents: 1607
diff changeset
   122
_ = unicode
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   123
4932
dce5ebe5d598 add missing warn imports
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4758
diff changeset
   124
from warnings import warn
dce5ebe5d598 add missing warn imports
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4758
diff changeset
   125
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   126
from logilab.mtconverter import xml_escape
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   127
from logilab.common.decorators import iclassmethod, cached
5592
41ad8ca3047e [form] fix bw compat issue introduced by 5588:377c9adfe81e
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5588
diff changeset
   128
from logilab.common.deprecation import deprecated
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   129
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   130
from cubicweb import typed_eid, neg_role, uilib
5695
85bafafc1f22 [autoform] fix vreg module name
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5693
diff changeset
   131
from cubicweb.vregistry import classid
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   132
from cubicweb.schema import display_name
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   133
from cubicweb.view import EntityView
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   134
from cubicweb.selectors import (
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   135
    match_kwargs, match_form_params, non_final_entity,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   136
    specified_etype_implements)
5389
809d3b5b3d31 [python2.6] careful: json-py provides a json package. We don't want that.
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5377
diff changeset
   137
from cubicweb.web import stdmsgs, uicfg, eid_param, dumps, \
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   138
     form as f, formwidgets as fw, formfields as ff
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   139
from cubicweb.web.views import forms
1528
864ae7c15ef5 other fixlets
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1498
diff changeset
   140
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   141
_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
   142
_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
   143
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   144
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   145
# inlined form handling ########################################################
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   146
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   147
class InlinedFormField(ff.Field):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   148
    def __init__(self, view=None, **kwargs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   149
        kwargs.setdefault('label', None)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   150
        super(InlinedFormField, self).__init__(name=view.rtype, role=view.role,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   151
                                               eidparam=True, **kwargs)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   152
        self.view = view
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   153
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   154
    def render(self, form, renderer):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   155
        """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
   156
        renderer
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   157
        """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   158
        view = self.view
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   159
        i18nctx = 'inlined:%s.%s.%s' % (form.edited_entity.e_schema,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   160
                                        view.rtype, view.role)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   161
        return u'<div class="inline-%s-%s-slot">%s</div>' % (
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   162
            view.rtype, view.role,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   163
            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
   164
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   165
    def form_init(self, form):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   166
        """method called before by build_context to trigger potential field
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   167
        initialization requiring the form instance
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
        if self.view.form:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   170
            self.view.form.build_context(form.formvalues)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   171
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   172
    @property
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   173
    def needs_multipart(self):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   174
        if self.view.form:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   175
            # 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
   176
            # multipart handling.
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   177
            return self.view.form.needs_multipart
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   178
        return False
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   179
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   180
    def has_been_modified(self, form):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   181
        return False
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   182
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   183
    def process_posted(self, form):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   184
        pass # handled by the subform
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   185
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   186
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   187
class InlineEntityEditionFormView(f.FormViewMixIn, EntityView):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   188
    """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   189
    :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
   190
    :attr rtype: the relation bridging `etype` and `peid`
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   191
    :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
   192
    :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
   193
    """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   194
    __regid__ = 'inline-edition'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   195
    __select__ = non_final_entity() & match_kwargs('peid', 'rtype')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   196
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   197
    _select_attrs = ('peid', 'rtype', 'role', 'pform', 'etype')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   198
    removejs = "removeInlinedEntity('%s', '%s', '%s')"
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   199
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   200
    def __init__(self, *args, **kwargs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   201
        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
   202
            # 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
   203
            # 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
   204
            # 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
   205
            setattr(self, attr, kwargs.get(attr))
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   206
        super(InlineEntityEditionFormView, self).__init__(*args, **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
    def _entity(self):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   209
        assert self.cw_row is not None, self
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   210
        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
   211
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   212
    @property
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   213
    @cached
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   214
    def form(self):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   215
        entity = self._entity()
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   216
        form = self._cw.vreg['forms'].select('edition', self._cw,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   217
                                             entity=entity,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   218
                                             formtype='inlined',
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   219
                                             form_renderer_id='inline',
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   220
                                             copy_nav_params=False,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   221
                                             mainform=False,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   222
                                             parent_form=self.pform,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   223
                                             **self.cw_extra_kwargs)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   224
        if self.pform is None:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   225
            form.restore_previous_post(form.session_key())
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   226
        #assert form.parent_form
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   227
        self.add_hiddens(form, entity)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   228
        return form
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   229
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   230
    def cell_call(self, row, col, i18nctx, **kwargs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   231
        """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   232
        :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
   233
        :param rtype: the relation bridging `etype` and `peid`
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   234
        :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
   235
        """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   236
        entity = self._entity()
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   237
        divonclick = "restoreInlinedEntity('%s', '%s', '%s')" % (
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   238
            self.peid, self.rtype, entity.eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   239
        self.render_form(i18nctx, divonclick=divonclick, **kwargs)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   240
5835
4125a8021956 [#969169] don't display remove link in edition forms if the cardinality is 1
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 5769
diff changeset
   241
    def _get_removejs(self):
4125a8021956 [#969169] don't display remove link in edition forms if the cardinality is 1
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 5769
diff changeset
   242
        """
4125a8021956 [#969169] don't display remove link in edition forms if the cardinality is 1
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 5769
diff changeset
   243
        Don't display the remove link in edition form if the
4125a8021956 [#969169] don't display remove link in edition forms if the cardinality is 1
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 5769
diff changeset
   244
        cardinality is 1. Handled in InlineEntityCreationFormView for
4125a8021956 [#969169] don't display remove link in edition forms if the cardinality is 1
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 5769
diff changeset
   245
        creation form.
4125a8021956 [#969169] don't display remove link in edition forms if the cardinality is 1
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 5769
diff changeset
   246
        """
4125a8021956 [#969169] don't display remove link in edition forms if the cardinality is 1
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 5769
diff changeset
   247
        entity = self._entity()
4125a8021956 [#969169] don't display remove link in edition forms if the cardinality is 1
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 5769
diff changeset
   248
        if isinstance(self.peid, int):
4125a8021956 [#969169] don't display remove link in edition forms if the cardinality is 1
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 5769
diff changeset
   249
            pentity = self._cw.entity_from_eid(self.peid)
4125a8021956 [#969169] don't display remove link in edition forms if the cardinality is 1
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 5769
diff changeset
   250
            petype = pentity.e_schema.type
4125a8021956 [#969169] don't display remove link in edition forms if the cardinality is 1
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 5769
diff changeset
   251
            rdef = entity.e_schema.rdef(self.rtype, neg_role(self.role), petype)
4125a8021956 [#969169] don't display remove link in edition forms if the cardinality is 1
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 5769
diff changeset
   252
            card= rdef.role_cardinality(self.role)
4125a8021956 [#969169] don't display remove link in edition forms if the cardinality is 1
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 5769
diff changeset
   253
            if card == '1': # don't display remove link
4125a8021956 [#969169] don't display remove link in edition forms if the cardinality is 1
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 5769
diff changeset
   254
                return None
4125a8021956 [#969169] don't display remove link in edition forms if the cardinality is 1
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 5769
diff changeset
   255
        return self.removejs and self.removejs % (
4125a8021956 [#969169] don't display remove link in edition forms if the cardinality is 1
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 5769
diff changeset
   256
            self.peid, self.rtype, entity.eid)
4125a8021956 [#969169] don't display remove link in edition forms if the cardinality is 1
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 5769
diff changeset
   257
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   258
    def render_form(self, i18nctx, **kwargs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   259
        """fetch and render the form"""
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   260
        entity = self._entity()
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   261
        divid = '%s-%s-%s' % (self.peid, self.rtype, entity.eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   262
        title = self.form_title(entity, i18nctx)
5835
4125a8021956 [#969169] don't display remove link in edition forms if the cardinality is 1
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 5769
diff changeset
   263
        removejs = self._get_removejs()
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   264
        countkey = '%s_count' % self.rtype
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   265
        try:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   266
            self._cw.data[countkey] += 1
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   267
        except KeyError:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   268
            self._cw.data[countkey] = 1
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   269
        self.w(self.form.render(
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   270
            divid=divid, title=title, removejs=removejs, i18nctx=i18nctx,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   271
            counter=self._cw.data[countkey] , **kwargs))
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 form_title(self, entity, i18nctx):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   274
        return self._cw.pgettext(i18nctx, entity.__regid__)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   275
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   276
    def add_hiddens(self, form, entity):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   277
        """to ease overriding (see cubes.vcsfile.views.forms for instance)"""
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   278
        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
   279
        #  * str(self.rtype) in case it's a schema object
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   280
        #  * 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
   281
        #    of the inlined entity
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   282
        form.add_hidden(name=str(self.rtype), value=self.peid,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   283
                        role=neg_role(self.role), eidparam=True, id=iid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   284
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   285
    def keep_entity(self, form, entity):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   286
        if not entity.has_eid():
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   287
            return True
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   288
        # are we regenerating form because of a validation error ?
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   289
        if form.form_previous_values:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   290
            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
   291
                                                form.form_previous_values)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   292
            if unicode(entity.eid) not in cdvalues:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   293
                return False
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   294
        return True
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   295
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   296
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   297
class InlineEntityCreationFormView(InlineEntityEditionFormView):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   298
    """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   299
    :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
   300
    """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   301
    __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
   302
    __select__ = (match_kwargs('peid', 'petype', 'rtype')
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   303
                  & 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
   304
    _select_attrs = InlineEntityEditionFormView._select_attrs + ('petype',)
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   305
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   306
    @property
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   307
    def removejs(self):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   308
        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
   309
        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
   310
        card= rdef.role_cardinality(self.role)
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   311
        # 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
   312
        # 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
   313
        # 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
   314
        # id to removeInlineForm.
5769
b3b48e0b8e3b [autoform] do not show remove link for inline form if card == 1
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5695
diff changeset
   315
        if card == '?':
b3b48e0b8e3b [autoform] do not show remove link for inline form if card == 1
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5695
diff changeset
   316
            divid = "addNew%s%s%s:%s" % (self.etype, self.rtype, self.role, self.peid)
b3b48e0b8e3b [autoform] do not show remove link for inline form if card == 1
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5695
diff changeset
   317
            return "removeInlineForm('%%s', '%%s', '%s', '%%s', '%s')" % (
b3b48e0b8e3b [autoform] do not show remove link for inline form if card == 1
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5695
diff changeset
   318
                self.role, divid)
b3b48e0b8e3b [autoform] do not show remove link for inline form if card == 1
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5695
diff changeset
   319
        elif card in '+*':
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   320
            return "removeInlineForm('%%s', '%%s', '%s', '%%s')" % self.role
5769
b3b48e0b8e3b [autoform] do not show remove link for inline form if card == 1
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5695
diff changeset
   321
        # don't do anything for card == '1'
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   322
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   323
    @cached
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   324
    def _entity(self):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   325
        try:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   326
            cls = self._cw.vreg['etypes'].etype_class(self.etype)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   327
        except:
5693
8af6623f3d4e [pylint] fix detected name errors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5656
diff changeset
   328
            self.w(self._cw._('no such entity type %s') % self.etype)
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   329
            return
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   330
        entity = cls(self._cw)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   331
        entity.eid = self._cw.varmaker.next()
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   332
        return entity
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   333
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   334
    def call(self, i18nctx, **kwargs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   335
        self.render_form(i18nctx, **kwargs)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   336
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   337
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   338
class InlineAddNewLinkView(InlineEntityCreationFormView):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   339
    """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   340
    :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
   341
    """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   342
    __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
   343
    __select__ = (match_kwargs('peid', 'petype', 'rtype')
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   344
                  & specified_etype_implements('Any'))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   345
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   346
    _select_attrs = InlineEntityCreationFormView._select_attrs + ('card',)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   347
    form = None # no actual form wrapped
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   348
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   349
    def call(self, i18nctx, **kwargs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   350
        self._cw.set_varmaker()
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   351
        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
   352
        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
   353
          % 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
   354
        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
   355
            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
   356
        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
   357
            js = "toggleVisibility('%s'); %s" % (divid, js)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   358
        __ = self._cw.pgettext
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   359
        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
   360
          % (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
   361
        self.w(u'</div>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   362
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   363
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   364
# generic relations handling ##################################################
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   365
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   366
def relation_id(eid, rtype, role, reid):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   367
    """return an identifier for a relation between two entities"""
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   368
    if role == 'subject':
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   369
        return u'%s:%s:%s' % (eid, rtype, reid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   370
    return u'%s:%s:%s' % (reid, rtype, eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   371
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   372
def toggleable_relation_link(eid, nodeid, label='x'):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   373
    """return javascript snippet to delete/undelete a relation between two
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   374
    entities
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   375
    """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   376
    js = u"javascript: togglePendingDelete('%s', %s);" % (
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   377
        nodeid, xml_escape(dumps(eid)))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   378
    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
   379
        js, nodeid, label)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   380
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   381
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   382
def get_pending_inserts(req, eid=None):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   383
    """shortcut to access req's pending_insert entry
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   384
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   385
    This is where are stored relations being added while editing
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   386
    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
   387
    """
5223
6abd6e3599f4 #773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5174
diff changeset
   388
    pending = req.session.data.get('pending_insert', ())
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   389
    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
   390
            if eid is None or eid in (subj, obj)]
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   391
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   392
def get_pending_deletes(req, eid=None):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   393
    """shortcut to access req's pending_delete entry
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   394
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   395
    This is where are stored relations being removed while editing
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   396
    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
   397
    """
5223
6abd6e3599f4 #773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5174
diff changeset
   398
    pending = req.session.data.get('pending_delete', ())
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   399
    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
   400
            if eid is None or eid in (subj, obj)]
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   401
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   402
def parse_relations_descr(rdescr):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   403
    """parse a string describing some relations, in the form
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   404
    subjeids:rtype:objeids
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   405
    where subjeids and objeids are eids separeted by a underscore
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   406
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   407
    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
   408
    """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   409
    for rstr in rdescr:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   410
        subjs, rtype, objs = rstr.split(':')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   411
        for subj in subjs.split('_'):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   412
            for obj in objs.split('_'):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   413
                yield typed_eid(subj), rtype, typed_eid(obj)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   414
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   415
def delete_relations(req, rdefs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   416
    """delete relations from the repository"""
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   417
    # FIXME convert to using the syntax subject:relation:eids
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   418
    execute = req.execute
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   419
    for subj, rtype, obj in parse_relations_descr(rdefs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   420
        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
   421
        execute(rql, {'x': subj, 'y': obj})
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   422
    req.set_message(req._('relations deleted'))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   423
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   424
def insert_relations(req, rdefs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   425
    """insert relations into the repository"""
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   426
    execute = req.execute
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   427
    for subj, rtype, obj in parse_relations_descr(rdefs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   428
        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
   429
        execute(rql, {'x': subj, 'y': obj})
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   430
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   431
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   432
class GenericRelationsWidget(fw.FieldWidget):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   433
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   434
    def render(self, form, field, renderer):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   435
        stream = []
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   436
        w = stream.append
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   437
        req = form._cw
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   438
        _ = req._
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   439
        __ = _
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   440
        eid = form.edited_entity.eid
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   441
        w(u'<table id="relatedEntities">')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   442
        for rschema, role, related in field.relations_table(form):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   443
            # already linked entities
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   444
            if related:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   445
                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
   446
                w(u'<td>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   447
                w(u'<ul>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   448
                for viewparams in related:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   449
                    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
   450
                      % (viewparams[1], viewparams[0], viewparams[2], viewparams[3]))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   451
                if not form.force_display and form.maxrelitems < len(related):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   452
                    link = (u'<span class="invisible">'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   453
                            '[<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
   454
                            '</span>' % _('view all'))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   455
                    w(u'<li class="invisible">%s</li>' % link)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   456
                w(u'</ul>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   457
                w(u'</td>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   458
                w(u'</tr>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   459
        pendings = list(field.restore_pending_inserts(form))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   460
        if not pendings:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   461
            w(u'<tr><th>&#160;</th><td>&#160;</td></tr>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   462
        else:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   463
            for row in pendings:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   464
                # soon to be linked to entities
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   465
                w(u'<tr id="tr%s">' % row[1])
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   466
                w(u'<th>%s</th>' % row[3])
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   467
                w(u'<td>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   468
                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
   469
                  (_('cancel this insert'), row[2]))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   470
                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
   471
                  % (row[1], row[4], xml_escape(row[5])))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   472
                w(u'</td>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   473
                w(u'</tr>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   474
        w(u'<tr id="relationSelectorRow_%s" class="separator">' % eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   475
        w(u'<th class="labelCol">')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   476
        w(u'<select id="relationSelector_%s" tabindex="%s" '
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   477
          'onchange="javascript:showMatchingSelect(this.options[this.selectedIndex].value,%s);">'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   478
          % (eid, req.next_tabindex(), xml_escape(dumps(eid))))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   479
        w(u'<option value="">%s</option>' % _('select a relation'))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   480
        for i18nrtype, rschema, role in field.relations:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   481
            # more entities to link to
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   482
            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
   483
        w(u'</select>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   484
        w(u'</th>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   485
        w(u'<td id="unrelatedDivs_%s"></td>' % eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   486
        w(u'</tr>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   487
        w(u'</table>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   488
        return '\n'.join(stream)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   489
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   490
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   491
class GenericRelationsField(ff.Field):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   492
    widget = GenericRelationsWidget
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   493
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   494
    def __init__(self, relations, name='_cw_generic_field', **kwargs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   495
        assert relations
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   496
        kwargs['eidparam'] = True
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   497
        super(GenericRelationsField, self).__init__(name, **kwargs)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   498
        self.relations = relations
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   499
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   500
    def process_posted(self, form):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   501
        todelete = get_pending_deletes(form._cw)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   502
        if todelete:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   503
            delete_relations(form._cw, todelete)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   504
        toinsert = get_pending_inserts(form._cw)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   505
        if toinsert:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   506
            insert_relations(form._cw, toinsert)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   507
        return ()
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   508
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   509
    def relations_table(self, form):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   510
        """yiels 3-tuples (rtype, role, related_list)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   511
        where <related_list> itself a list of :
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   512
          - node_id (will be the entity element's DOM id)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   513
          - appropriate javascript's togglePendingDelete() function call
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   514
          - status 'pendingdelete' or ''
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   515
          - oneline view of related entity
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   516
        """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   517
        entity = form.edited_entity
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   518
        pending_deletes = get_pending_deletes(form._cw, entity.eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   519
        for label, rschema, role in self.relations:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   520
            related = []
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   521
            if entity.has_eid():
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   522
                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
   523
                if role == 'subject':
19d73051eb57 [autoform] we should consider role when checking delete permission
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   524
                    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
   525
                else:
19d73051eb57 [autoform] we should consider role when checking delete permission
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   526
                    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
   527
                if rschema.has_perm(form._cw, 'delete', **haspermkwargs):
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   528
                    toggleable_rel_link_func = toggleable_relation_link
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   529
                else:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   530
                    toggleable_rel_link_func = lambda x, y, z: u''
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   531
                for row in xrange(rset.rowcount):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   532
                    nodeid = relation_id(entity.eid, rschema, role,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   533
                                         rset[row][0])
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   534
                    if nodeid in pending_deletes:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   535
                        status, label = u'pendingDelete', '+'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   536
                    else:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   537
                        status, label = u'', 'x'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   538
                    dellink = toggleable_rel_link_func(entity.eid, nodeid, label)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   539
                    eview = form._cw.view('oneline', rset, row=row)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   540
                    related.append((nodeid, dellink, status, eview))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   541
            yield (rschema, role, related)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   542
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   543
    def restore_pending_inserts(self, form):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   544
        """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
   545
        'search for <some entity type>'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   546
        """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   547
        entity = form.edited_entity
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   548
        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
   549
        for pendingid in pending_inserts:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   550
            eidfrom, rtype, eidto = pendingid.split(':')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   551
            if typed_eid(eidfrom) == entity.eid: # subject
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   552
                label = display_name(form._cw, rtype, 'subject',
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   553
                                     entity.__regid__)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   554
                reid = eidto
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   555
            else:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   556
                label = display_name(form._cw, rtype, 'object',
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   557
                                     entity.__regid__)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   558
                reid = eidfrom
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   559
            jscall = "javascript: cancelPendingInsert('%s', 'tr', null, %s);" \
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   560
                     % (pendingid, entity.eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   561
            rset = form._cw.eid_rset(reid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   562
            eview = form._cw.view('text', rset, row=0)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   563
            yield rtype, pendingid, jscall, label, reid, eview
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   564
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   565
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   566
class UnrelatedDivs(EntityView):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   567
    __regid__ = 'unrelateddivs'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   568
    __select__ = match_form_params('relation')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   569
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   570
    def cell_call(self, row, col):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   571
        entity = self.cw_rset.get_entity(row, col)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   572
        relname, role = self._cw.form.get('relation').rsplit('_', 1)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   573
        rschema = self._cw.vreg.schema.rschema(relname)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   574
        hidden = 'hidden' in self._cw.form
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   575
        is_cell = 'is_cell' in self._cw.form
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   576
        self.w(self.build_unrelated_select_div(entity, rschema, role,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   577
                                               is_cell=is_cell, hidden=hidden))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   578
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   579
    def build_unrelated_select_div(self, entity, rschema, role,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   580
                                   is_cell=False, hidden=True):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   581
        options = []
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   582
        divid = 'div%s_%s_%s' % (rschema.type, role, entity.eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   583
        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
   584
        if rschema.symmetric or role == 'subject':
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   585
            targettypes = rschema.objects(entity.e_schema)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   586
            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
   587
        else:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   588
            targettypes = rschema.subjects(entity.e_schema)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   589
            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
   590
        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
   591
        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
   592
        options += self._get_select_options(entity, rschema, role)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   593
        options += self._get_search_options(entity, rschema, role, targettypes)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   594
        relname, role = self._cw.form.get('relation').rsplit('_', 1)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   595
        return u"""\
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   596
<div class="%s" id="%s">
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   597
  <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
   598
    %s
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   599
  </select>
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   600
</div>
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   601
""" % (hidden and 'hidden' or '', divid, selectid,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   602
       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
   603
       '\n'.join(options))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   604
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   605
    def _get_select_options(self, entity, rschema, role):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   606
        """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
   607
        options = []
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   608
        pending_inserts = get_pending_inserts(self._cw, entity.eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   609
        rtype = rschema.type
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   610
        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
   611
        field = form.field_by_name(rschema, role, entity.e_schema)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   612
        limit = self._cw.property_value('navigation.combobox-limit')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   613
        # NOTE: expect 'limit' arg on choices method of relation field
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   614
        for eview, reid in field.vocabulary(form, limit=limit):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   615
            if reid is None:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   616
                if eview: # skip blank value
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   617
                    options.append('<option class="separator">-- %s --</option>'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   618
                                   % xml_escape(eview))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   619
            elif reid != ff.INTERNAL_FIELD_VALUE:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   620
                optionid = relation_id(entity.eid, rtype, role, reid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   621
                if optionid not in pending_inserts:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   622
                    # 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
   623
                    options.append('<option id="id%s" value="%s">%s</option>' %
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   624
                                   (optionid, reid, xml_escape(eview)))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   625
        return options
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   626
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   627
    def _get_search_options(self, entity, rschema, role, targettypes):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   628
        """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
   629
        options = []
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   630
        _ = self._cw._
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   631
        for eschema in targettypes:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   632
            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
   633
            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
   634
                                 __mode=mode)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   635
            options.append((eschema.display_name(self._cw),
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   636
                            '<option value="%s">%s %s</option>' % (
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   637
                xml_escape(url), _('Search for'), eschema.display_name(self._cw))))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   638
        return [o for l, o in sorted(options)]
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   639
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   640
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   641
# The automatic entity form ####################################################
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   642
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
   643
class AutomaticEntityForm(forms.EntityFieldsForm):
5463
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5426
diff changeset
   644
    """AutomaticEntityForm is an automagic form to edit any entity. It
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5426
diff changeset
   645
    is designed to be fully generated from schema but highly
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5426
diff changeset
   646
    configurable through uicfg.
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
   647
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
   648
    Of course, as for other forms, you can also customise it by specifying
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
   649
    various standard form parameters on selection, overriding, or
5463
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5426
diff changeset
   650
    adding/removing fields in selected instances.
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   651
    """
3408
c92170fca813 [api] use __regid__ instead of deprecated id
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3360
diff changeset
   652
    __regid__ = 'edition'
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   653
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   654
    cwtarget = 'eformframe'
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   655
    cssclass = 'entityForm'
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   656
    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
   657
    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
   658
                    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
   659
                    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
   660
    # 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
   661
    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
   662
    # 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
   663
    # 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
   664
    display_fields = None
5588
377c9adfe81e [forms] refactor action handling to ease overriding while keeping action overrideable by instance (closes #969167)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5464
diff changeset
   665
    # action on the form tag
377c9adfe81e [forms] refactor action handling to ease overriding while keeping action overrideable by instance (closes #969167)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5464
diff changeset
   666
    _default_form_action_path = 'validateform'
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   667
5592
41ad8ca3047e [form] fix bw compat issue introduced by 5588:377c9adfe81e
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5588
diff changeset
   668
    # pre 3.8.3 compat
41ad8ca3047e [form] fix bw compat issue introduced by 5588:377c9adfe81e
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5588
diff changeset
   669
    def set_action(self, action):
41ad8ca3047e [form] fix bw compat issue introduced by 5588:377c9adfe81e
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5588
diff changeset
   670
        self._action = action
41ad8ca3047e [form] fix bw compat issue introduced by 5588:377c9adfe81e
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5588
diff changeset
   671
    def get_action(self):
41ad8ca3047e [form] fix bw compat issue introduced by 5588:377c9adfe81e
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5588
diff changeset
   672
        try:
41ad8ca3047e [form] fix bw compat issue introduced by 5588:377c9adfe81e
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5588
diff changeset
   673
            return self._action
41ad8ca3047e [form] fix bw compat issue introduced by 5588:377c9adfe81e
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5588
diff changeset
   674
        except AttributeError:
41ad8ca3047e [form] fix bw compat issue introduced by 5588:377c9adfe81e
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5588
diff changeset
   675
            return self._cw.build_url(self._default_form_action_path)
5656
abe97430b3f5 [form] avoid spurious warning subsequent for form's action refactoring w/ autoforms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5612
diff changeset
   676
    action = property(deprecated('[3.9] use form.form_action()')(get_action),
abe97430b3f5 [form] avoid spurious warning subsequent for form's action refactoring w/ autoforms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5612
diff changeset
   677
                      set_action)
5592
41ad8ca3047e [form] fix bw compat issue introduced by 5588:377c9adfe81e
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5588
diff changeset
   678
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
   679
    @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
   680
    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
   681
        """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
   682
        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
   683
        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
   684
        """
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
   685
        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
   686
            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
   687
        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
   688
            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
   689
                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
   690
            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
   691
3360
b02df886eb3e cleanup, reorganize
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3358
diff changeset
   692
    # base automatic entity form methods #######################################
b02df886eb3e cleanup, reorganize
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3358
diff changeset
   693
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   694
    def __init__(self, *args, **kwargs):
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   695
        super(AutomaticEntityForm, self).__init__(*args, **kwargs)
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   696
        entity = self.edited_entity
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   697
        if entity.has_eid():
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   698
            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
   699
        for rtype, role in self.editable_attributes():
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   700
            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
   701
                self.field_by_name(str(rtype), role)
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   702
                continue # explicitly specified
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   703
            except f.FieldNotFound:
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   704
                # has to be guessed
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   705
                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
   706
                    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
   707
                                               eschema=entity.e_schema)
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   708
                    self.fields.append(field)
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   709
                except f.FieldNotFound:
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   710
                    # meta attribute such as <attr>_format
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   711
                    continue
4642
606364845c34 [auto/inline forms] reallow nested inline forms #703910
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4629
diff changeset
   712
        if self.fieldsets_in_order:
606364845c34 [auto/inline forms] reallow nested inline forms #703910
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4629
diff changeset
   713
            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
   714
        else:
606364845c34 [auto/inline forms] reallow nested inline forms #703910
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4629
diff changeset
   715
            fsio = [None]
606364845c34 [auto/inline forms] reallow nested inline forms #703910
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4629
diff changeset
   716
        self.fieldsets_in_order = fsio
606364845c34 [auto/inline forms] reallow nested inline forms #703910
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4629
diff changeset
   717
        # 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
   718
        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
   719
            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
   720
            self.fields.append(field)
606364845c34 [auto/inline forms] reallow nested inline forms #703910
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4629
diff changeset
   721
            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
   722
                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
   723
        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
   724
            # 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
   725
            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
   726
                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
   727
                '_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
   728
                try:
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   729
                    field = self.field_by_name('_cw_generic_field')
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   730
                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
   731
                    # 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
   732
                    pass
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   733
                else:
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   734
                    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
   735
                    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
   736
                        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
   737
        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
   738
        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
   739
        fnum = len(self.fields)
7d0d4a6be046 [formfields] allow fields ordering with autoform_field_kwargs
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3689
diff changeset
   740
        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
   741
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   742
    @property
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   743
    def related_limit(self):
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   744
        if self.force_display:
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   745
            return None
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   746
        return self.maxrelitems + 1
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   747
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   748
    # 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
   749
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   750
    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
   751
        try:
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   752
            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
   753
            warn('[3.6] %s: srelations_by_category is deprecated, use uicfg or '
5693
8af6623f3d4e [pylint] fix detected name errors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5656
diff changeset
   754
                 'override editable_relations instead' % classid(self),
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   755
                 DeprecationWarning)
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   756
        except AttributeError:
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   757
            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
   758
        if not srels_by_cat:
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   759
            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
   760
        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
   761
        fieldset = fieldset.capitalize()
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   762
        return GenericRelationsField(self.editable_relations(),
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   763
                                     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
   764
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   765
    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
   766
        # 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
   767
        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
   768
                                 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
   769
        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
   770
            kwargs = {}
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   771
        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
   772
3360
b02df886eb3e cleanup, reorganize
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3358
diff changeset
   773
    # methods mapping edited entity relations to fields in the form ############
b02df886eb3e cleanup, reorganize
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3358
diff changeset
   774
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
   775
    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
   776
        """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
   777
        given category(ies) and permission
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   778
        """
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   779
        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
   780
            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
   781
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
   782
    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
   783
        """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
   784
        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
   785
            return self.display_fields
5557
1a534c596bff [entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5464
diff changeset
   786
        if self.edited_entity.has_eid() and not self.edited_entity.cw_has_perm('update'):
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
   787
            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
   788
        # 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
   789
        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
   790
            '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
   791
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
   792
    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
   793
        """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
   794
        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
   795
        """
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
   796
        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
   797
        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
   798
                                                           strict=True):
3505
c0c7a944c00d fix dumb name error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
   799
            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
   800
                                                 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
   801
                            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
   802
        return sorted(result)
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   803
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   804
    def inlined_relations(self):
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   805
        """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
   806
        given category(ies) and permission
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   807
        """
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
   808
        return self._relations_by_section('inlined')
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   809
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   810
    # inlined forms control ####################################################
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   811
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
   812
    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
   813
        """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
   814
        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
   815
        """
3593
987232bd79cd fix inlined forms initialization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3586
diff changeset
   816
        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
   817
        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
   818
        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
   819
            # 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
   820
            # 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
   821
            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
   822
                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
   823
                             '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
   824
                             '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
   825
                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
   826
            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
   827
            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
   828
                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
   829
                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
   830
                # 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
   831
                # 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
   832
                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
   833
                    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
   834
                # 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
   835
                # 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
   836
                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
   837
                    addnewlink = self._cw.vreg['views'].select(
4082
c7117119e215 3.6 api update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4015
diff changeset
   838
                        '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
   839
                        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
   840
                        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
   841
                        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
   842
                    formviews.append(addnewlink)
3593
987232bd79cd fix inlined forms initialization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3586
diff changeset
   843
                allformviews += formviews
987232bd79cd fix inlined forms initialization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3586
diff changeset
   844
        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
   845
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   846
    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
   847
        """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
   848
        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
   849
feedfe5d4932 [autoform] no need to recheck inlined tag here
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3482
diff changeset
   850
        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
   851
        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
   852
        """
3595
b61f1c5e6c55 at this point we know this is true
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3594
diff changeset
   853
        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
   854
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   855
    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
   856
        """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
   857
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   858
        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
   859
        """
3418
7b49fa7e942d [api] use _cw, cw_row, cw_col, cw_rset etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3408
diff changeset
   860
        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
   861
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   862
    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
   863
        """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
   864
        (through ajax call)
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   865
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   866
        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
   867
        multiple cardinality
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   868
        """
4160
3fbdeef9a610 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4110
diff changeset
   869
        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
   870
3332
91cff87c368f introduced to ease overriding for fancy stuff...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3293
diff changeset
   871
    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
   872
        """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
   873
        link should be hidden
91cff87c368f introduced to ease overriding for fancy stuff...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3293
diff changeset
   874
91cff87c368f introduced to ease overriding for fancy stuff...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3293
diff changeset
   875
        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
   876
        """
91cff87c368f introduced to ease overriding for fancy stuff...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3293
diff changeset
   877
        return card in '1?'
91cff87c368f introduced to ease overriding for fancy stuff...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3293
diff changeset
   878
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
   879
    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
   880
        """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
   881
        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
   882
        """
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
   883
        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
   884
        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
   885
        if related:
3524
a3431f4e2f40 backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3505 3521
diff changeset
   886
            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
   887
            # 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
   888
            for i, relentity in enumerate(related.entities()):
5557
1a534c596bff [entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5464
diff changeset
   889
                if relentity.cw_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
   890
                    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
   891
                                       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
   892
                                       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
   893
                                       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
   894
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
   895
    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
   896
        """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
   897
        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
   898
        """
3524
a3431f4e2f40 backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3505 3521
diff changeset
   899
        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
   900
                                            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
   901
                                            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
   902
                                            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
   903
                                            pform=self)
2652
3753f3a07ca1 [refactoring] moved rtags specification in web/views
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2143
diff changeset
   904
3753f3a07ca1 [refactoring] moved rtags specification in web/views
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2143
diff changeset
   905
3753f3a07ca1 [refactoring] moved rtags specification in web/views
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2143
diff changeset
   906
## default form ui configuration ##############################################
3753f3a07ca1 [refactoring] moved rtags specification in web/views
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2143
diff changeset
   907
3753f3a07ca1 [refactoring] moved rtags specification in web/views
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2143
diff changeset
   908
# 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
   909
_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
   910
_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
   911
_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
   912
_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
   913
_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
   914
_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
   915
_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
   916
_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
   917
_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
   918
_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
   919
_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
   920
_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
   921
_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
   922
_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
   923
_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
   924
_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
   925
_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
   926
_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
   927
_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
   928
_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
   929
_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
   930
_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
   931
_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
   932
_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
   933
_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
   934
_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
   935
_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
   936
_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
   937
_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
   938
_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
   939
_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
   940
_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
   941
_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
   942
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   943
_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
   944
                    {'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
   945
_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
   946
                     {'widget': fw.HiddenInput})
2652
3753f3a07ca1 [refactoring] moved rtags specification in web/views
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2143
diff changeset
   947
4105
de31c3afe975 fix 3.6 bug
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4083
diff changeset
   948
def registration_callback(vreg):
de31c3afe975 fix 3.6 bug
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4083
diff changeset
   949
    global etype_relation_field
de31c3afe975 fix 3.6 bug
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4083
diff changeset
   950
de31c3afe975 fix 3.6 bug
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4083
diff changeset
   951
    def etype_relation_field(etype, rtype, role='subject'):
de31c3afe975 fix 3.6 bug
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4083
diff changeset
   952
        eschema = vreg.schema.eschema(etype)
de31c3afe975 fix 3.6 bug
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4083
diff changeset
   953
        return AutomaticEntityForm.field_by_name(rtype, role, eschema)
4110
8728d8c95985 [mq]: fix_for_forms
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 4105
diff changeset
   954
8728d8c95985 [mq]: fix_for_forms
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 4105
diff changeset
   955
    vreg.register_all(globals().values(), __name__)