web/views/autoform.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Wed, 08 Apr 2015 09:27:26 +0200
changeset 10519 0019b7888dd7
parent 10229 512ba8f37bd4
child 10522 1660a0fa4f43
child 10634 06a43f727601
permissions -rw-r--r--
[forms] don't display 'remove' link of inlined form for the first entity related using a '+' cardinality to its parent entity Closes #5227394
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
9179
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8900
diff changeset
     1
# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
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
     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
8748
f5027f8d2478 drop typed_eid() in favour of int() (closes #2742462)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8696
diff changeset
   130
from cubicweb import neg_role, uilib
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   131
from cubicweb.schema import display_name
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   132
from cubicweb.view import EntityView
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8128
diff changeset
   133
from cubicweb.predicates import (
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   134
    match_kwargs, match_form_params, non_final_entity,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   135
    specified_etype_implements)
8253
df7d6c57a6c8 [reledit, autoform] move reledit_form definition in reledit.py
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 8190
diff changeset
   136
from cubicweb.utils import json_dumps
8665
e65af61bde7d [uicfg] uicfg.py moves from web/ to web/views/ (prepares #2406609)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8253
diff changeset
   137
from cubicweb.web import (stdmsgs, eid_param,
5940
0e3ae19b181a [uilib] refactor json_dumps code organization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   138
                          form as f, formwidgets as fw, formfields as ff)
8665
e65af61bde7d [uicfg] uicfg.py moves from web/ to web/views/ (prepares #2406609)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8253
diff changeset
   139
from cubicweb.web.views import uicfg, forms
8128
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   140
from cubicweb.web.views.ajaxcontroller import ajaxfunc
1528
864ae7c15ef5 other fixlets
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1498
diff changeset
   141
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   142
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   143
# inlined form handling ########################################################
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   144
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   145
class InlinedFormField(ff.Field):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   146
    def __init__(self, view=None, **kwargs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   147
        kwargs.setdefault('label', None)
9179
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8900
diff changeset
   148
        # don't add eidparam=True since this field doesn't actually hold the
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8900
diff changeset
   149
        # relation value (the subform does) hence should not be listed in
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8900
diff changeset
   150
        # _cw_entity_fields
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   151
        super(InlinedFormField, self).__init__(name=view.rtype, role=view.role,
9179
570208f74a84 [editcontrollers] Ensure entities are created in an order satisfying schema constraints. Closes #3031719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8900
diff changeset
   152
                                               **kwargs)
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   153
        self.view = view
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   154
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   155
    def render(self, form, renderer):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   156
        """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
   157
        renderer
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   158
        """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   159
        view = self.view
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   160
        i18nctx = 'inlined:%s.%s.%s' % (form.edited_entity.e_schema,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   161
                                        view.rtype, view.role)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   162
        return u'<div class="inline-%s-%s-slot">%s</div>' % (
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   163
            view.rtype, view.role,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   164
            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
   165
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   166
    def form_init(self, form):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   167
        """method called before by build_context to trigger potential field
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   168
        initialization requiring the form instance
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   169
        """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   170
        if self.view.form:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   171
            self.view.form.build_context(form.formvalues)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   172
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   173
    @property
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   174
    def needs_multipart(self):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   175
        if self.view.form:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   176
            # 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
   177
            # multipart handling.
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   178
            return self.view.form.needs_multipart
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   179
        return False
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   180
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   181
    def has_been_modified(self, form):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   182
        return False
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   183
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   184
    def process_posted(self, form):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   185
        pass # handled by the subform
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
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   188
class InlineEntityEditionFormView(f.FormViewMixIn, EntityView):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   189
    """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   190
    :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
   191
    :attr rtype: the relation bridging `etype` and `peid`
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   192
    :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
   193
    :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
   194
    """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   195
    __regid__ = 'inline-edition'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   196
    __select__ = non_final_entity() & match_kwargs('peid', 'rtype')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   197
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   198
    _select_attrs = ('peid', 'rtype', 'role', 'pform', 'etype')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   199
    removejs = "removeInlinedEntity('%s', '%s', '%s')"
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   200
7879
9aae456abab5 [pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7815
diff changeset
   201
    # make pylint happy
9aae456abab5 [pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7815
diff changeset
   202
    peid = rtype = role = pform = etype = None
9aae456abab5 [pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7815
diff changeset
   203
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   204
    def __init__(self, *args, **kwargs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   205
        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
   206
            # 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
   207
            # 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
   208
            # 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
   209
            setattr(self, attr, kwargs.get(attr))
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   210
        super(InlineEntityEditionFormView, self).__init__(*args, **kwargs)
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
    def _entity(self):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   213
        assert self.cw_row is not None, self
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   214
        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
   215
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   216
    @property
10519
0019b7888dd7 [forms] don't display 'remove' link of inlined form for the first entity related using a '+' cardinality to its parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10229
diff changeset
   217
    def petype(self):
0019b7888dd7 [forms] don't display 'remove' link of inlined form for the first entity related using a '+' cardinality to its parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10229
diff changeset
   218
        assert isinstance(self.peid, int)
0019b7888dd7 [forms] don't display 'remove' link of inlined form for the first entity related using a '+' cardinality to its parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10229
diff changeset
   219
        pentity = self._cw.entity_from_eid(self.peid)
0019b7888dd7 [forms] don't display 'remove' link of inlined form for the first entity related using a '+' cardinality to its parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10229
diff changeset
   220
        return pentity.e_schema.type
0019b7888dd7 [forms] don't display 'remove' link of inlined form for the first entity related using a '+' cardinality to its parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10229
diff changeset
   221
0019b7888dd7 [forms] don't display 'remove' link of inlined form for the first entity related using a '+' cardinality to its parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10229
diff changeset
   222
    @property
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   223
    @cached
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   224
    def form(self):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   225
        entity = self._entity()
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   226
        form = self._cw.vreg['forms'].select('edition', self._cw,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   227
                                             entity=entity,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   228
                                             formtype='inlined',
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   229
                                             form_renderer_id='inline',
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   230
                                             copy_nav_params=False,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   231
                                             mainform=False,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   232
                                             parent_form=self.pform,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   233
                                             **self.cw_extra_kwargs)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   234
        if self.pform is None:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   235
            form.restore_previous_post(form.session_key())
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   236
        #assert form.parent_form
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   237
        self.add_hiddens(form, entity)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   238
        return form
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   239
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   240
    def cell_call(self, row, col, i18nctx, **kwargs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   241
        """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   242
        :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
   243
        :param rtype: the relation bridging `etype` and `peid`
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   244
        :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
   245
        """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   246
        entity = self._entity()
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   247
        divonclick = "restoreInlinedEntity('%s', '%s', '%s')" % (
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   248
            self.peid, self.rtype, entity.eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   249
        self.render_form(i18nctx, divonclick=divonclick, **kwargs)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   250
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
   251
    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
   252
        """
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
        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
   254
        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
   255
        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
   256
        """
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
        entity = self._entity()
10519
0019b7888dd7 [forms] don't display 'remove' link of inlined form for the first entity related using a '+' cardinality to its parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10229
diff changeset
   258
        rdef = entity.e_schema.rdef(self.rtype, neg_role(self.role), self.petype)
0019b7888dd7 [forms] don't display 'remove' link of inlined form for the first entity related using a '+' cardinality to its parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10229
diff changeset
   259
        card = rdef.role_cardinality(self.role)
0019b7888dd7 [forms] don't display 'remove' link of inlined form for the first entity related using a '+' cardinality to its parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10229
diff changeset
   260
        if card == '1': # don't display remove link
0019b7888dd7 [forms] don't display 'remove' link of inlined form for the first entity related using a '+' cardinality to its parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10229
diff changeset
   261
            return None
0019b7888dd7 [forms] don't display 'remove' link of inlined form for the first entity related using a '+' cardinality to its parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10229
diff changeset
   262
        # if cardinality is 1..n (+), dont display link to remove an inlined form for the first form
0019b7888dd7 [forms] don't display 'remove' link of inlined form for the first entity related using a '+' cardinality to its parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10229
diff changeset
   263
        # allowing to edit the relation. To detect so:
0019b7888dd7 [forms] don't display 'remove' link of inlined form for the first entity related using a '+' cardinality to its parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10229
diff changeset
   264
        #
0019b7888dd7 [forms] don't display 'remove' link of inlined form for the first entity related using a '+' cardinality to its parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10229
diff changeset
   265
        # * if parent form (pform) is None, we're generated through an ajax call and so we know this
0019b7888dd7 [forms] don't display 'remove' link of inlined form for the first entity related using a '+' cardinality to its parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10229
diff changeset
   266
        #   is not the first form
0019b7888dd7 [forms] don't display 'remove' link of inlined form for the first entity related using a '+' cardinality to its parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10229
diff changeset
   267
        #
0019b7888dd7 [forms] don't display 'remove' link of inlined form for the first entity related using a '+' cardinality to its parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10229
diff changeset
   268
        # * if parent form is not None, look for previous InlinedFormField in the parent's form
0019b7888dd7 [forms] don't display 'remove' link of inlined form for the first entity related using a '+' cardinality to its parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10229
diff changeset
   269
        #   fields
0019b7888dd7 [forms] don't display 'remove' link of inlined form for the first entity related using a '+' cardinality to its parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10229
diff changeset
   270
        if card == '+' and self.pform is not None:
0019b7888dd7 [forms] don't display 'remove' link of inlined form for the first entity related using a '+' cardinality to its parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10229
diff changeset
   271
            # retrieve all field'views handling this relation and return None if we're the first of
0019b7888dd7 [forms] don't display 'remove' link of inlined form for the first entity related using a '+' cardinality to its parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10229
diff changeset
   272
            # them
0019b7888dd7 [forms] don't display 'remove' link of inlined form for the first entity related using a '+' cardinality to its parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10229
diff changeset
   273
            first_view = next(iter((f.view for f in self.pform.fields
0019b7888dd7 [forms] don't display 'remove' link of inlined form for the first entity related using a '+' cardinality to its parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10229
diff changeset
   274
                                    if isinstance(f, InlinedFormField)
0019b7888dd7 [forms] don't display 'remove' link of inlined form for the first entity related using a '+' cardinality to its parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10229
diff changeset
   275
                                    and f.view.rtype == self.rtype and f.view.role == self.role)))
0019b7888dd7 [forms] don't display 'remove' link of inlined form for the first entity related using a '+' cardinality to its parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10229
diff changeset
   276
            if self == first_view:
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
   277
                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
   278
        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
   279
            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
   280
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   281
    def render_form(self, i18nctx, **kwargs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   282
        """fetch and render the form"""
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   283
        entity = self._entity()
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   284
        divid = '%s-%s-%s' % (self.peid, self.rtype, entity.eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   285
        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
   286
        removejs = self._get_removejs()
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   287
        countkey = '%s_count' % self.rtype
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   288
        try:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   289
            self._cw.data[countkey] += 1
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   290
        except KeyError:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   291
            self._cw.data[countkey] = 1
6576
481249ecdc4f [3.10] remove a deprecation warning
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6427
diff changeset
   292
        self.form.render(w=self.w, divid=divid, title=title, removejs=removejs,
481249ecdc4f [3.10] remove a deprecation warning
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6427
diff changeset
   293
                         i18nctx=i18nctx, counter=self._cw.data[countkey] ,
481249ecdc4f [3.10] remove a deprecation warning
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6427
diff changeset
   294
                         **kwargs)
4387
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
    def form_title(self, entity, i18nctx):
8900
010a59e12d89 use cw_etype instead of __regid__
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8748
diff changeset
   297
        return self._cw.pgettext(i18nctx, entity.cw_etype)
4387
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
    def add_hiddens(self, form, entity):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   300
        """to ease overriding (see cubes.vcsfile.views.forms for instance)"""
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   301
        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
   302
        #  * str(self.rtype) in case it's a schema object
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   303
        #  * 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
   304
        #    of the inlined entity
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   305
        form.add_hidden(name=str(self.rtype), value=self.peid,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   306
                        role=neg_role(self.role), eidparam=True, id=iid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   307
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   308
    def keep_entity(self, form, entity):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   309
        if not entity.has_eid():
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   310
            return True
9492
c7fc56eecd1a English typography
Dimitri Papadopoulos <dimitri.papadopoulos@cea.fr>
parents: 9376
diff changeset
   311
        # are we regenerating form because of a validation error?
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   312
        if form.form_previous_values:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   313
            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
   314
                                                form.form_previous_values)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   315
            if unicode(entity.eid) not in cdvalues:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   316
                return False
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   317
        return True
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   318
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   319
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   320
class InlineEntityCreationFormView(InlineEntityEditionFormView):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   321
    """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   322
    :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
   323
    """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   324
    __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
   325
    __select__ = (match_kwargs('peid', 'petype', 'rtype')
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   326
                  & 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
   327
    _select_attrs = InlineEntityEditionFormView._select_attrs + ('petype',)
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   328
7879
9aae456abab5 [pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7815
diff changeset
   329
    # make pylint happy
9aae456abab5 [pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7815
diff changeset
   330
    petype = None
9aae456abab5 [pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7815
diff changeset
   331
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   332
    @property
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   333
    def removejs(self):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   334
        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
   335
        rdef = entity.e_schema.rdef(self.rtype, neg_role(self.role), self.petype)
10519
0019b7888dd7 [forms] don't display 'remove' link of inlined form for the first entity related using a '+' cardinality to its parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10229
diff changeset
   336
        card = rdef.role_cardinality(self.role)
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   337
        # 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
   338
        # 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
   339
        # 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
   340
        # 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
   341
        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
   342
            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
   343
            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
   344
                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
   345
        elif card in '+*':
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   346
            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
   347
        # don't do anything for card == '1'
4387
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
    @cached
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   350
    def _entity(self):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   351
        try:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   352
            cls = self._cw.vreg['etypes'].etype_class(self.etype)
7815
2a164a9cf81c [exceptions] stop catching any exception in various places (closes #1942716)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7782
diff changeset
   353
        except Exception:
5693
8af6623f3d4e [pylint] fix detected name errors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5656
diff changeset
   354
            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
   355
            return
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   356
        entity = cls(self._cw)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   357
        entity.eid = self._cw.varmaker.next()
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   358
        return entity
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   359
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   360
    def call(self, i18nctx, **kwargs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   361
        self.render_form(i18nctx, **kwargs)
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
class InlineAddNewLinkView(InlineEntityCreationFormView):
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
    :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
   367
    """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   368
    __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
   369
    __select__ = (match_kwargs('peid', 'petype', 'rtype')
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   370
                  & specified_etype_implements('Any'))
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
    _select_attrs = InlineEntityCreationFormView._select_attrs + ('card',)
7879
9aae456abab5 [pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7815
diff changeset
   373
    card = None # make pylint happy
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   374
    form = None # no actual form wrapped
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
    def call(self, i18nctx, **kwargs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   377
        self._cw.set_varmaker()
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   378
        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
   379
        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
   380
          % 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
   381
        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
   382
            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
   383
        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
   384
            js = "toggleVisibility('%s'); %s" % (divid, js)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   385
        __ = self._cw.pgettext
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   386
        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
   387
          % (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
   388
        self.w(u'</div>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   389
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   390
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   391
# generic relations handling ##################################################
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   392
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   393
def relation_id(eid, rtype, role, reid):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   394
    """return an identifier for a relation between two entities"""
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   395
    if role == 'subject':
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   396
        return u'%s:%s:%s' % (eid, rtype, reid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   397
    return u'%s:%s:%s' % (reid, rtype, eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   398
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   399
def toggleable_relation_link(eid, nodeid, label='x'):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   400
    """return javascript snippet to delete/undelete a relation between two
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   401
    entities
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   402
    """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   403
    js = u"javascript: togglePendingDelete('%s', %s);" % (
5940
0e3ae19b181a [uilib] refactor json_dumps code organization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   404
        nodeid, xml_escape(json_dumps(eid)))
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   405
    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
   406
        js, nodeid, label)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   407
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
def get_pending_inserts(req, eid=None):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   410
    """shortcut to access req's pending_insert entry
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   411
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   412
    This is where are stored relations being added while editing
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   413
    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
   414
    """
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
   415
    pending = req.session.data.get('pending_insert', ())
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   416
    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
   417
            if eid is None or eid in (subj, obj)]
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   418
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   419
def get_pending_deletes(req, eid=None):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   420
    """shortcut to access req's pending_delete entry
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   421
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   422
    This is where are stored relations being removed while editing
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   423
    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
   424
    """
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
   425
    pending = req.session.data.get('pending_delete', ())
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   426
    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
   427
            if eid is None or eid in (subj, obj)]
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   428
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   429
def parse_relations_descr(rdescr):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   430
    """parse a string describing some relations, in the form
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   431
    subjeids:rtype:objeids
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   432
    where subjeids and objeids are eids separeted by a underscore
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
    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
   435
    """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   436
    for rstr in rdescr:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   437
        subjs, rtype, objs = rstr.split(':')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   438
        for subj in subjs.split('_'):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   439
            for obj in objs.split('_'):
8748
f5027f8d2478 drop typed_eid() in favour of int() (closes #2742462)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8696
diff changeset
   440
                yield int(subj), rtype, int(obj)
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   441
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   442
def delete_relations(req, rdefs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   443
    """delete relations from the repository"""
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   444
    # FIXME convert to using the syntax subject:relation:eids
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   445
    execute = req.execute
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   446
    for subj, rtype, obj in parse_relations_descr(rdefs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   447
        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
   448
        execute(rql, {'x': subj, 'y': obj})
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   449
    req.set_message(req._('relations deleted'))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   450
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   451
def insert_relations(req, rdefs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   452
    """insert relations into the repository"""
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   453
    execute = req.execute
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   454
    for subj, rtype, obj in parse_relations_descr(rdefs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   455
        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
   456
        execute(rql, {'x': subj, 'y': obj})
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   457
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   458
8128
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   459
# ajax edition helpers ########################################################
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   460
@ajaxfunc(output_type='xhtml', check_pageid=True)
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   461
def inline_creation_form(self, peid, petype, ttype, rtype, role, i18nctx):
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   462
    view = self._cw.vreg['views'].select('inline-creation', self._cw,
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   463
                                         etype=ttype, rtype=rtype, role=role,
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   464
                                         peid=peid, petype=petype)
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   465
    return self._call_view(view, i18nctx=i18nctx)
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   466
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   467
@ajaxfunc(output_type='json')
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   468
def validate_form(self, action, names, values):
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   469
    return self.validate_form(action, names, values)
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   470
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   471
@ajaxfunc
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   472
def cancel_edition(self, errorurl):
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   473
    """cancelling edition from javascript
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   474
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   475
    We need to clear associated req's data :
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   476
      - errorurl
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   477
      - pending insertions / deletions
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   478
    """
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   479
    self._cw.cancel_edition(errorurl)
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   480
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   481
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   482
def _add_pending(req, eidfrom, rel, eidto, kind):
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   483
    key = 'pending_%s' % kind
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   484
    pendings = req.session.data.setdefault(key, set())
8748
f5027f8d2478 drop typed_eid() in favour of int() (closes #2742462)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8696
diff changeset
   485
    pendings.add( (int(eidfrom), rel, int(eidto)) )
8128
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   486
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   487
def _remove_pending(req, eidfrom, rel, eidto, kind):
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   488
    key = 'pending_%s' % kind
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   489
    pendings = req.session.data[key]
8748
f5027f8d2478 drop typed_eid() in favour of int() (closes #2742462)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8696
diff changeset
   490
    pendings.remove( (int(eidfrom), rel, int(eidto)) )
8128
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   491
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   492
@ajaxfunc(output_type='json')
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   493
def remove_pending_insert(self, (eidfrom, rel, eidto)):
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   494
    _remove_pending(self._cw, eidfrom, rel, eidto, 'insert')
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   495
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   496
@ajaxfunc(output_type='json')
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   497
def add_pending_inserts(self, tripletlist):
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   498
    for eidfrom, rel, eidto in tripletlist:
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   499
        _add_pending(self._cw, eidfrom, rel, eidto, 'insert')
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   500
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   501
@ajaxfunc(output_type='json')
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   502
def remove_pending_delete(self, (eidfrom, rel, eidto)):
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   503
    _remove_pending(self._cw, eidfrom, rel, eidto, 'delete')
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   504
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   505
@ajaxfunc(output_type='json')
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   506
def add_pending_delete(self, (eidfrom, rel, eidto)):
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   507
    _add_pending(self._cw, eidfrom, rel, eidto, 'delete')
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   508
0a927fe4541b [controllers] deprecate JSonController and implement AjaxController / ajax-func registry (closes #2110265)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   509
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   510
class GenericRelationsWidget(fw.FieldWidget):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   511
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   512
    def render(self, form, field, renderer):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   513
        stream = []
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   514
        w = stream.append
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   515
        req = form._cw
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   516
        _ = req._
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   517
        __ = _
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   518
        eid = form.edited_entity.eid
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   519
        w(u'<table id="relatedEntities">')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   520
        for rschema, role, related in field.relations_table(form):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   521
            # already linked entities
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   522
            if related:
8900
010a59e12d89 use cw_etype instead of __regid__
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8748
diff changeset
   523
                label = rschema.display_name(req, role, context=form.edited_entity.cw_etype)
6017
5f6a60ea8544 [relations in ui] provide context information when computing label for a relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5940
diff changeset
   524
                w(u'<tr><th class="labelCol">%s</th>' % label)
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   525
                w(u'<td>')
9870
d30ff49d4a94 [views] Replace poorly named "invisible" class with "list-unstyled"
Rémi Cardona <remi.cardona@logilab.fr>
parents: 9869
diff changeset
   526
                w(u'<ul class="list-unstyled">')
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   527
                for viewparams in related:
9870
d30ff49d4a94 [views] Replace poorly named "invisible" class with "list-unstyled"
Rémi Cardona <remi.cardona@logilab.fr>
parents: 9869
diff changeset
   528
                    w(u'<li>%s<span id="span%s" class="%s">%s</span></li>'
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   529
                      % (viewparams[1], viewparams[0], viewparams[2], viewparams[3]))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   530
                if not form.force_display and form.maxrelitems < len(related):
9870
d30ff49d4a94 [views] Replace poorly named "invisible" class with "list-unstyled"
Rémi Cardona <remi.cardona@logilab.fr>
parents: 9869
diff changeset
   531
                    link = (u'<span>'
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   532
                            '[<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
   533
                            '</span>' % _('view all'))
9870
d30ff49d4a94 [views] Replace poorly named "invisible" class with "list-unstyled"
Rémi Cardona <remi.cardona@logilab.fr>
parents: 9869
diff changeset
   534
                    w(u'<li>%s</li>' % link)
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   535
                w(u'</ul>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   536
                w(u'</td>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   537
                w(u'</tr>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   538
        pendings = list(field.restore_pending_inserts(form))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   539
        if not pendings:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   540
            w(u'<tr><th>&#160;</th><td>&#160;</td></tr>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   541
        else:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   542
            for row in pendings:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   543
                # soon to be linked to entities
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   544
                w(u'<tr id="tr%s">' % row[1])
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   545
                w(u'<th>%s</th>' % row[3])
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   546
                w(u'<td>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   547
                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
   548
                  (_('cancel this insert'), row[2]))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   549
                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
   550
                  % (row[1], row[4], xml_escape(row[5])))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   551
                w(u'</td>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   552
                w(u'</tr>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   553
        w(u'<tr id="relationSelectorRow_%s" class="separator">' % eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   554
        w(u'<th class="labelCol">')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   555
        w(u'<select id="relationSelector_%s" tabindex="%s" '
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   556
          'onchange="javascript:showMatchingSelect(this.options[this.selectedIndex].value,%s);">'
5940
0e3ae19b181a [uilib] refactor json_dumps code organization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   557
          % (eid, req.next_tabindex(), xml_escape(json_dumps(eid))))
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   558
        w(u'<option value="">%s</option>' % _('select a relation'))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   559
        for i18nrtype, rschema, role in field.relations:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   560
            # more entities to link to
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   561
            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
   562
        w(u'</select>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   563
        w(u'</th>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   564
        w(u'<td id="unrelatedDivs_%s"></td>' % eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   565
        w(u'</tr>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   566
        w(u'</table>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   567
        return '\n'.join(stream)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   568
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
class GenericRelationsField(ff.Field):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   571
    widget = GenericRelationsWidget
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   572
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   573
    def __init__(self, relations, name='_cw_generic_field', **kwargs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   574
        assert relations
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   575
        kwargs['eidparam'] = True
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   576
        super(GenericRelationsField, self).__init__(name, **kwargs)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   577
        self.relations = relations
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 process_posted(self, form):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   580
        todelete = get_pending_deletes(form._cw)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   581
        if todelete:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   582
            delete_relations(form._cw, todelete)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   583
        toinsert = get_pending_inserts(form._cw)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   584
        if toinsert:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   585
            insert_relations(form._cw, toinsert)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   586
        return ()
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   587
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   588
    def relations_table(self, form):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   589
        """yiels 3-tuples (rtype, role, related_list)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   590
        where <related_list> itself a list of :
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   591
          - node_id (will be the entity element's DOM id)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   592
          - appropriate javascript's togglePendingDelete() function call
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   593
          - status 'pendingdelete' or ''
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   594
          - oneline view of related entity
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   595
        """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   596
        entity = form.edited_entity
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   597
        pending_deletes = get_pending_deletes(form._cw, entity.eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   598
        for label, rschema, role in self.relations:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   599
            related = []
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   600
            if entity.has_eid():
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   601
                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
   602
                if role == 'subject':
19d73051eb57 [autoform] we should consider role when checking delete permission
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   603
                    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
   604
                else:
19d73051eb57 [autoform] we should consider role when checking delete permission
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   605
                    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
   606
                if rschema.has_perm(form._cw, 'delete', **haspermkwargs):
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   607
                    toggleable_rel_link_func = toggleable_relation_link
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   608
                else:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   609
                    toggleable_rel_link_func = lambda x, y, z: u''
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   610
                for row in xrange(rset.rowcount):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   611
                    nodeid = relation_id(entity.eid, rschema, role,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   612
                                         rset[row][0])
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   613
                    if nodeid in pending_deletes:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   614
                        status, label = u'pendingDelete', '+'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   615
                    else:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   616
                        status, label = u'', 'x'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   617
                    dellink = toggleable_rel_link_func(entity.eid, nodeid, label)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   618
                    eview = form._cw.view('oneline', rset, row=row)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   619
                    related.append((nodeid, dellink, status, eview))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   620
            yield (rschema, role, related)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   621
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   622
    def restore_pending_inserts(self, form):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   623
        """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
   624
        'search for <some entity type>'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   625
        """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   626
        entity = form.edited_entity
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   627
        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
   628
        for pendingid in pending_inserts:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   629
            eidfrom, rtype, eidto = pendingid.split(':')
6725
6e6d1d19f341 [autoform] fix restoration of pending generic relation: inconsistent id was generated (eg different from the one generated by javascript
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6630
diff changeset
   630
            pendingid = 'id' + pendingid
8748
f5027f8d2478 drop typed_eid() in favour of int() (closes #2742462)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8696
diff changeset
   631
            if int(eidfrom) == entity.eid: # subject
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   632
                label = display_name(form._cw, rtype, 'subject',
8900
010a59e12d89 use cw_etype instead of __regid__
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8748
diff changeset
   633
                                     entity.cw_etype)
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   634
                reid = eidto
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   635
            else:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   636
                label = display_name(form._cw, rtype, 'object',
8900
010a59e12d89 use cw_etype instead of __regid__
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8748
diff changeset
   637
                                     entity.cw_etype)
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   638
                reid = eidfrom
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   639
            jscall = "javascript: cancelPendingInsert('%s', 'tr', null, %s);" \
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   640
                     % (pendingid, entity.eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   641
            rset = form._cw.eid_rset(reid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   642
            eview = form._cw.view('text', rset, row=0)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   643
            yield rtype, pendingid, jscall, label, reid, eview
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   644
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   645
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   646
class UnrelatedDivs(EntityView):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   647
    __regid__ = 'unrelateddivs'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   648
    __select__ = match_form_params('relation')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   649
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   650
    def cell_call(self, row, col):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   651
        entity = self.cw_rset.get_entity(row, col)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   652
        relname, role = self._cw.form.get('relation').rsplit('_', 1)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   653
        rschema = self._cw.vreg.schema.rschema(relname)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   654
        hidden = 'hidden' in self._cw.form
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   655
        is_cell = 'is_cell' in self._cw.form
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   656
        self.w(self.build_unrelated_select_div(entity, rschema, role,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   657
                                               is_cell=is_cell, hidden=hidden))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   658
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   659
    def build_unrelated_select_div(self, entity, rschema, role,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   660
                                   is_cell=False, hidden=True):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   661
        options = []
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   662
        divid = 'div%s_%s_%s' % (rschema.type, role, entity.eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   663
        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
   664
        if rschema.symmetric or role == 'subject':
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   665
            targettypes = rschema.objects(entity.e_schema)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   666
            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
   667
        else:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   668
            targettypes = rschema.subjects(entity.e_schema)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   669
            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
   670
        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
   671
        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
   672
        options += self._get_select_options(entity, rschema, role)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   673
        options += self._get_search_options(entity, rschema, role, targettypes)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   674
        relname, role = self._cw.form.get('relation').rsplit('_', 1)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   675
        return u"""\
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   676
<div class="%s" id="%s">
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   677
  <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
   678
    %s
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   679
  </select>
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   680
</div>
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   681
""" % (hidden and 'hidden' or '', divid, selectid,
5940
0e3ae19b181a [uilib] refactor json_dumps code organization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   682
       xml_escape(json_dumps(entity.eid)), is_cell and 'true' or 'null', relname,
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   683
       '\n'.join(options))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   684
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   685
    def _get_select_options(self, entity, rschema, role):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   686
        """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
   687
        options = []
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   688
        pending_inserts = get_pending_inserts(self._cw, entity.eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   689
        rtype = rschema.type
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   690
        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
   691
        field = form.field_by_name(rschema, role, entity.e_schema)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   692
        limit = self._cw.property_value('navigation.combobox-limit')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   693
        # NOTE: expect 'limit' arg on choices method of relation field
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   694
        for eview, reid in field.vocabulary(form, limit=limit):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   695
            if reid is None:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   696
                if eview: # skip blank value
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   697
                    options.append('<option class="separator">-- %s --</option>'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   698
                                   % xml_escape(eview))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   699
            elif reid != ff.INTERNAL_FIELD_VALUE:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   700
                optionid = relation_id(entity.eid, rtype, role, reid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   701
                if optionid not in pending_inserts:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   702
                    # 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
   703
                    options.append('<option id="id%s" value="%s">%s</option>' %
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   704
                                   (optionid, reid, xml_escape(eview)))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   705
        return options
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   706
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   707
    def _get_search_options(self, entity, rschema, role, targettypes):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   708
        """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
   709
        options = []
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   710
        _ = self._cw._
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   711
        for eschema in targettypes:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   712
            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
   713
            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
   714
                                 __mode=mode)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   715
            options.append((eschema.display_name(self._cw),
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   716
                            '<option value="%s">%s %s</option>' % (
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   717
                xml_escape(url), _('Search for'), eschema.display_name(self._cw))))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   718
        return [o for l, o in sorted(options)]
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   719
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   720
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   721
# The automatic entity form ####################################################
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   722
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
   723
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
   724
    """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
   725
    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
   726
    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
   727
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
   728
    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
   729
    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
   730
    adding/removing fields in selected instances.
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   731
    """
3408
c92170fca813 [api] use __regid__ instead of deprecated id
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3360
diff changeset
   732
    __regid__ = 'edition'
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   733
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   734
    cwtarget = 'eformframe'
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   735
    cssclass = 'entityForm'
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   736
    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
   737
    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
   738
                    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
   739
                    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
   740
    # 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
   741
    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
   742
    # 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
   743
    # 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
   744
    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
   745
    # 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
   746
    _default_form_action_path = 'validateform'
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   747
9257
ce338133c92c remove cw 3.9 bw compat (bw compat other than the interface -> adapter changes)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9179
diff changeset
   748
    @deprecated('[3.18] you should override form_action()')
5592
41ad8ca3047e [form] fix bw compat issue introduced by 5588:377c9adfe81e
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5588
diff changeset
   749
    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
   750
        self._action = action
9257
ce338133c92c remove cw 3.9 bw compat (bw compat other than the interface -> adapter changes)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9179
diff changeset
   751
ce338133c92c remove cw 3.9 bw compat (bw compat other than the interface -> adapter changes)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9179
diff changeset
   752
    @deprecated('[3.18] use form_action()')
5592
41ad8ca3047e [form] fix bw compat issue introduced by 5588:377c9adfe81e
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5588
diff changeset
   753
    def get_action(self):
10223
fbb370195199 [web/views] Honor 'action' attribute on AutomaticEntityForm, closes #4943392
Rémi Cardona <remi.cardona@logilab.fr>
parents: 9976
diff changeset
   754
        return self._action
9257
ce338133c92c remove cw 3.9 bw compat (bw compat other than the interface -> adapter changes)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9179
diff changeset
   755
5592
41ad8ca3047e [form] fix bw compat issue introduced by 5588:377c9adfe81e
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5588
diff changeset
   756
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
   757
    @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
   758
    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
   759
        """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
   760
        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
   761
        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
   762
        """
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
   763
        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
   764
            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
   765
        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
   766
            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
   767
                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
   768
            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
   769
3360
b02df886eb3e cleanup, reorganize
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3358
diff changeset
   770
    # base automatic entity form methods #######################################
b02df886eb3e cleanup, reorganize
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3358
diff changeset
   771
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   772
    def __init__(self, *args, **kwargs):
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   773
        super(AutomaticEntityForm, self).__init__(*args, **kwargs)
8666
1dd655788ece make ui configurations selectable (closes #2406609)
Florent Cayré <florent.cayre@logilab.fr>
parents: 8665
diff changeset
   774
        self.uicfg_afs = self._cw.vreg['uicfg'].select(
1dd655788ece make ui configurations selectable (closes #2406609)
Florent Cayré <florent.cayre@logilab.fr>
parents: 8665
diff changeset
   775
            'autoform_section', self._cw, entity=self.edited_entity)
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   776
        entity = self.edited_entity
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   777
        if entity.has_eid():
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   778
            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
   779
        for rtype, role in self.editable_attributes():
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   780
            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
   781
                self.field_by_name(str(rtype), role)
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   782
                continue # explicitly specified
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   783
            except f.FieldNotFound:
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   784
                # has to be guessed
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   785
                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
   786
                    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
   787
                                               eschema=entity.e_schema)
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   788
                    self.fields.append(field)
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   789
                except f.FieldNotFound:
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   790
                    # meta attribute such as <attr>_format
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   791
                    continue
4642
606364845c34 [auto/inline forms] reallow nested inline forms #703910
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4629
diff changeset
   792
        if self.fieldsets_in_order:
606364845c34 [auto/inline forms] reallow nested inline forms #703910
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4629
diff changeset
   793
            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
   794
        else:
606364845c34 [auto/inline forms] reallow nested inline forms #703910
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4629
diff changeset
   795
            fsio = [None]
606364845c34 [auto/inline forms] reallow nested inline forms #703910
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4629
diff changeset
   796
        self.fieldsets_in_order = fsio
606364845c34 [auto/inline forms] reallow nested inline forms #703910
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4629
diff changeset
   797
        # 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
   798
        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
   799
            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
   800
            self.fields.append(field)
606364845c34 [auto/inline forms] reallow nested inline forms #703910
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4629
diff changeset
   801
            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
   802
                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
   803
        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
   804
            # 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
   805
            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
   806
                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
   807
                '_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
   808
                try:
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   809
                    field = self.field_by_name('_cw_generic_field')
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   810
                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
   811
                    # 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
   812
                    pass
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   813
                else:
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   814
                    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
   815
                    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
   816
                        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
   817
        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
   818
        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
   819
        fnum = len(self.fields)
7d0d4a6be046 [formfields] allow fields ordering with autoform_field_kwargs
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3689
diff changeset
   820
        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
   821
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   822
    @property
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   823
    def related_limit(self):
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   824
        if self.force_display:
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   825
            return None
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   826
        return self.maxrelitems + 1
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   827
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   828
    # 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
   829
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   830
    def _generic_relations_field(self):
7990
a673d1d9a738 [diet] drop pre 3.6 API compatibility (but attempt to keep data cmopatibility). Closes #2017916
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7894
diff changeset
   831
        srels_by_cat = self.editable_relations()
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   832
        if not srels_by_cat:
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   833
            raise f.FieldNotFound('_cw_generic_field')
10163
4001cfe2f44d [web/views] Stop mishandling the fieldset name in the default form renderer
Rémi Cardona <remi.cardona@logilab.fr>
parents: 9990
diff changeset
   834
        fieldset = 'This %s:' % self.edited_entity.e_schema
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   835
        return GenericRelationsField(self.editable_relations(),
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   836
                                     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
   837
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   838
    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
   839
        # XXX allow more customization
8666
1dd655788ece make ui configurations selectable (closes #2406609)
Florent Cayré <florent.cayre@logilab.fr>
parents: 8665
diff changeset
   840
        kwargs = self.uicfg_affk.etype_get(self.edited_entity.e_schema,
1dd655788ece make ui configurations selectable (closes #2406609)
Florent Cayré <florent.cayre@logilab.fr>
parents: 8665
diff changeset
   841
                                           view.rtype, view.role, view.etype)
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   842
        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
   843
            kwargs = {}
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   844
        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
   845
3360
b02df886eb3e cleanup, reorganize
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3358
diff changeset
   846
    # methods mapping edited entity relations to fields in the form ############
b02df886eb3e cleanup, reorganize
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3358
diff changeset
   847
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
   848
    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
   849
        """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
   850
        given category(ies) and permission
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   851
        """
8666
1dd655788ece make ui configurations selectable (closes #2406609)
Florent Cayré <florent.cayre@logilab.fr>
parents: 8665
diff changeset
   852
        return self.uicfg_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
   853
            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
   854
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
   855
    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
   856
        """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
   857
        if self.display_fields is not None:
7063
b07ee816bffb fix editable_attributes bug (closes #1534802)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6725
diff changeset
   858
            schema = self._cw.vreg.schema
b07ee816bffb fix editable_attributes bug (closes #1534802)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6725
diff changeset
   859
            return [(schema[rtype], role) for rtype, role in self.display_fields]
5557
1a534c596bff [entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5464
diff changeset
   860
        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
   861
            return []
9976
457efde98629 [views] Display attributes in entity creation form based on "add" permission
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9893
diff changeset
   862
        action = 'update' if self.edited_entity.has_eid() else 'add'
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
   863
        return [(rtype, role) for rtype, _, role in self._relations_by_section(
9976
457efde98629 [views] Display attributes in entity creation form based on "add" permission
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9893
diff changeset
   864
            'attributes', action, 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
   865
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
   866
    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
   867
        """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
   868
        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
   869
        """
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
   870
        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
   871
        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
   872
                                                           strict=True):
3505
c0c7a944c00d fix dumb name error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
   873
            result.append( (rschema.display_name(self.edited_entity._cw, role,
8900
010a59e12d89 use cw_etype instead of __regid__
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8748
diff changeset
   874
                                                 self.edited_entity.cw_etype),
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
   875
                            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
   876
        return sorted(result)
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   877
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   878
    def inlined_relations(self):
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   879
        """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
   880
        given category(ies) and permission
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   881
        """
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
   882
        return self._relations_by_section('inlined')
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   883
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   884
    # inlined forms control ####################################################
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   885
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
   886
    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
   887
        """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
   888
        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
   889
        """
3593
987232bd79cd fix inlined forms initialization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3586
diff changeset
   890
        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
   891
        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
   892
        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
   893
            # 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
   894
            # 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
   895
            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
   896
                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
   897
                             '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
   898
                             '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
   899
                continue
6577
0d9ea7f93065 [inline forms] check for permission to add relation/target type before to add the 'add new' link (else we get a NoSelectableObject exception)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6576
diff changeset
   900
            tschema = ttypes[0]
0d9ea7f93065 [inline forms] check for permission to add relation/target type before to add the 'add new' link (else we get a NoSelectableObject exception)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6576
diff changeset
   901
            ttype = tschema.type
6394
eb9a5bd778bc [forms] remove dead code and simplify inlineviews creation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6101
diff changeset
   902
            formviews = list(self.inline_edition_form_view(rschema, ttype, role))
eb9a5bd778bc [forms] remove dead code and simplify inlineviews creation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6101
diff changeset
   903
            card = rschema.role_rdef(entity.e_schema, ttype, role).role_cardinality(role)
eb9a5bd778bc [forms] remove dead code and simplify inlineviews creation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6101
diff changeset
   904
            # there is no related entity and we need at least one: we need to
eb9a5bd778bc [forms] remove dead code and simplify inlineviews creation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6101
diff changeset
   905
            # display one explicit inline-creation view
eb9a5bd778bc [forms] remove dead code and simplify inlineviews creation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6101
diff changeset
   906
            if self.should_display_inline_creation_form(rschema, formviews, card):
eb9a5bd778bc [forms] remove dead code and simplify inlineviews creation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6101
diff changeset
   907
                formviews += self.inline_creation_form_view(rschema, ttype, role)
eb9a5bd778bc [forms] remove dead code and simplify inlineviews creation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6101
diff changeset
   908
            # we can create more than one related entity, we thus display a link
eb9a5bd778bc [forms] remove dead code and simplify inlineviews creation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6101
diff changeset
   909
            # to add new related entities
9376
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   910
            if self.must_display_add_new_relation_link(rschema, role, tschema,
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   911
                                                       ttype, formviews, card):
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   912
                addnewlink = self._cw.vreg['views'].select(
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   913
                    'inline-addnew-link', self._cw,
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   914
                    etype=ttype, rtype=rschema, role=role, card=card,
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   915
                    peid=self.edited_entity.eid,
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   916
                    petype=self.edited_entity.e_schema, pform=self)
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   917
                formviews.append(addnewlink)
6394
eb9a5bd778bc [forms] remove dead code and simplify inlineviews creation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6101
diff changeset
   918
            allformviews += formviews
3593
987232bd79cd fix inlined forms initialization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3586
diff changeset
   919
        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
   920
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   921
    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
   922
        """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
   923
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   924
        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
   925
        """
6394
eb9a5bd778bc [forms] remove dead code and simplify inlineviews creation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6101
diff changeset
   926
        return not existant and card in '1+'
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   927
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   928
    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
   929
        """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
   930
        (through ajax call)
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   931
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   932
        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
   933
        multiple cardinality
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   934
        """
6577
0d9ea7f93065 [inline forms] check for permission to add relation/target type before to add the 'add new' link (else we get a NoSelectableObject exception)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6576
diff changeset
   935
        return not existant or card in '+*'
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   936
9376
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   937
    def must_display_add_new_relation_link(self, rschema, role, tschema,
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   938
                                           ttype, existant, card):
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   939
        """return true if we must add a link to add a new creation form
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   940
        (through ajax call)
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   941
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   942
        by default true if there is no related entity or if the relation has
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   943
        multiple cardinality and it is permitted to add the inlined object and
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   944
        relation.
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   945
        """
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   946
        return (self.should_display_add_new_relation_link(
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   947
                    rschema, existant, card) and
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   948
                self.check_inlined_rdef_permissions(
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   949
                    rschema, role, tschema, ttype))
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   950
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   951
    def check_inlined_rdef_permissions(self, rschema, role, tschema, ttype):
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   952
        """return true if permissions are granted on the inlined object and
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   953
        relation"""
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   954
        entity = self.edited_entity
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   955
        rdef = entity.e_schema.rdef(rschema, role, ttype)
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   956
        if entity.has_eid():
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   957
            if role == 'subject':
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   958
                rdefkwargs = {'fromeid': entity.eid}
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   959
            else:
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   960
                rdefkwargs = {'toeid': entity.eid}
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   961
        else:
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   962
            rdefkwargs = {}
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   963
        return (tschema.has_perm(self._cw, 'add')
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   964
                and rdef.has_perm(self._cw, 'add', **rdefkwargs))
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   965
2ed0d091e9b1 [autoform] Allow overridding of permissions checks
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9257
diff changeset
   966
3332
91cff87c368f introduced to ease overriding for fancy stuff...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3293
diff changeset
   967
    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
   968
        """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
   969
        link should be hidden
91cff87c368f introduced to ease overriding for fancy stuff...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3293
diff changeset
   970
91cff87c368f introduced to ease overriding for fancy stuff...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3293
diff changeset
   971
        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
   972
        """
91cff87c368f introduced to ease overriding for fancy stuff...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3293
diff changeset
   973
        return card in '1?'
91cff87c368f introduced to ease overriding for fancy stuff...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3293
diff changeset
   974
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
   975
    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
   976
        """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
   977
        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
   978
        """
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
   979
        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
   980
        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
   981
        if related:
3524
a3431f4e2f40 backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3505 3521
diff changeset
   982
            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
   983
            # 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
   984
            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
   985
                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
   986
                    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
   987
                                       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
   988
                                       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
   989
                                       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
   990
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
   991
    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
   992
        """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
   993
        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
   994
        """
3524
a3431f4e2f40 backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3505 3521
diff changeset
   995
        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
   996
                                            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
   997
                                            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
   998
                                            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
   999
                                            pform=self)
2652
3753f3a07ca1 [refactoring] moved rtags specification in web/views
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2143
diff changeset
  1000
3753f3a07ca1 [refactoring] moved rtags specification in web/views
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2143
diff changeset
  1001
3753f3a07ca1 [refactoring] moved rtags specification in web/views
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2143
diff changeset
  1002
## default form ui configuration ##############################################
3753f3a07ca1 [refactoring] moved rtags specification in web/views
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2143
diff changeset
  1003
8666
1dd655788ece make ui configurations selectable (closes #2406609)
Florent Cayré <florent.cayre@logilab.fr>
parents: 8665
diff changeset
  1004
_AFS = uicfg.autoform_section
2652
3753f3a07ca1 [refactoring] moved rtags specification in web/views
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2143
diff changeset
  1005
# use primary and not generated for eid since it has to be an hidden
9976
457efde98629 [views] Display attributes in entity creation form based on "add" permission
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9893
diff changeset
  1006
_AFS.tag_attribute(('*', 'eid'), 'main', 'hidden')
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
  1007
_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
  1008
_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
  1009
_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
  1010
_AFS.tag_subject_of(('*', 'in_state', '*'), 'main', 'hidden')
6427
c8a5ac2d1eaa [schema / sources] store data sources as cubicweb entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6401
diff changeset
  1011
for rtype in ('creation_date', 'modification_date', 'cwuri',
c8a5ac2d1eaa [schema / sources] store data sources as cubicweb entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6401
diff changeset
  1012
              'owned_by', 'created_by', 'cw_source'):
c8a5ac2d1eaa [schema / sources] store data sources as cubicweb entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6401
diff changeset
  1013
    _AFS.tag_subject_of(('*', rtype, '*'), 'main', 'metadata')
c8a5ac2d1eaa [schema / sources] store data sources as cubicweb entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6401
diff changeset
  1014
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
  1015
_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
  1016
_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
  1017
_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
  1018
_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
  1019
_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
  1020
_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
  1021
_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
  1022
_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
  1023
_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
  1024
_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
  1025
_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
  1026
_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
  1027
_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
  1028
_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
  1029
_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
  1030
_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
  1031
_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
  1032
_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
  1033
_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
  1034
_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
  1035
8666
1dd655788ece make ui configurations selectable (closes #2406609)
Florent Cayré <florent.cayre@logilab.fr>
parents: 8665
diff changeset
  1036
_AFFK = uicfg.autoform_field_kwargs
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
  1037
_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
  1038
                    {'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
  1039
_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
  1040
                     {'widget': fw.HiddenInput})
2652
3753f3a07ca1 [refactoring] moved rtags specification in web/views
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2143
diff changeset
  1041
4105
de31c3afe975 fix 3.6 bug
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4083
diff changeset
  1042
def registration_callback(vreg):
de31c3afe975 fix 3.6 bug
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4083
diff changeset
  1043
    global etype_relation_field
de31c3afe975 fix 3.6 bug
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4083
diff changeset
  1044
de31c3afe975 fix 3.6 bug
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4083
diff changeset
  1045
    def etype_relation_field(etype, rtype, role='subject'):
6101
1aff7367a20c [form, migration] etype_relation_field should not raise error, it may block migration if used for a non yet existing field
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
  1046
        try:
6392
faee4c380e50 [forms] catching KeyError closes #961831: migration failure when defining form fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6101
diff changeset
  1047
            eschema = vreg.schema.eschema(etype)
6101
1aff7367a20c [form, migration] etype_relation_field should not raise error, it may block migration if used for a non yet existing field
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
  1048
            return AutomaticEntityForm.field_by_name(rtype, role, eschema)
6392
faee4c380e50 [forms] catching KeyError closes #961831: migration failure when defining form fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6101
diff changeset
  1049
        except (KeyError, f.FieldNotFound):
faee4c380e50 [forms] catching KeyError closes #961831: migration failure when defining form fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6101
diff changeset
  1050
            # catch KeyError raised when etype/rtype not found in schema
6101
1aff7367a20c [form, migration] etype_relation_field should not raise error, it may block migration if used for a non yet existing field
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
  1051
            AutomaticEntityForm.error('field for %s %s may not be found in schema' % (rtype, role))
1aff7367a20c [form, migration] etype_relation_field should not raise error, it may block migration if used for a non yet existing field
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
  1052
            return None
4110
8728d8c95985 [mq]: fix_for_forms
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 4105
diff changeset
  1053
8696
0bb18407c053 [toward py3k] rewrite dict.keys() and dict.values() (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8666
diff changeset
  1054
    vreg.register_all(globals().itervalues(), __name__)