web/views/autoform.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 15 Sep 2011 18:39:55 +0200
changeset 7797 a71618a75b53
parent 7782 40a49f4350a5
child 7845 2172978be237
permissions -rw-r--r--
backport stable
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7411
238da9684f99 cleanup and update some copyright
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7063
diff changeset
     1
# copyright 2003-2011 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
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   130
from cubicweb import typed_eid, neg_role, uilib
5695
85bafafc1f22 [autoform] fix vreg module name
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5693
diff changeset
   131
from cubicweb.vregistry import classid
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   132
from cubicweb.schema import display_name
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   133
from cubicweb.view import EntityView
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   134
from cubicweb.selectors import (
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   135
    match_kwargs, match_form_params, non_final_entity,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   136
    specified_etype_implements)
5940
0e3ae19b181a [uilib] refactor json_dumps code organization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   137
from cubicweb.utils import json_dumps
0e3ae19b181a [uilib] refactor json_dumps code organization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   138
from cubicweb.web import (stdmsgs, uicfg, eid_param,
0e3ae19b181a [uilib] refactor json_dumps code organization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5849
diff changeset
   139
                          form as f, formwidgets as fw, formfields as ff)
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   140
from cubicweb.web.views import forms
1528
864ae7c15ef5 other fixlets
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 1498
diff changeset
   141
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   142
_AFS = uicfg.autoform_section
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   143
_AFFK = uicfg.autoform_field_kwargs
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   144
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   145
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   146
# inlined form handling ########################################################
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   147
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   148
class InlinedFormField(ff.Field):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   149
    def __init__(self, view=None, **kwargs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   150
        kwargs.setdefault('label', None)
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,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   152
                                               eidparam=True, **kwargs)
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
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   201
    def __init__(self, *args, **kwargs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   202
        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
   203
            # 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
   204
            # 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
   205
            # 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
   206
            setattr(self, attr, kwargs.get(attr))
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   207
        super(InlineEntityEditionFormView, self).__init__(*args, **kwargs)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   208
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   209
    def _entity(self):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   210
        assert self.cw_row is not None, self
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   211
        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
   212
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   213
    @property
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   214
    @cached
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   215
    def form(self):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   216
        entity = self._entity()
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   217
        form = self._cw.vreg['forms'].select('edition', self._cw,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   218
                                             entity=entity,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   219
                                             formtype='inlined',
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   220
                                             form_renderer_id='inline',
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   221
                                             copy_nav_params=False,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   222
                                             mainform=False,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   223
                                             parent_form=self.pform,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   224
                                             **self.cw_extra_kwargs)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   225
        if self.pform is None:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   226
            form.restore_previous_post(form.session_key())
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   227
        #assert form.parent_form
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   228
        self.add_hiddens(form, entity)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   229
        return form
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   230
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   231
    def cell_call(self, row, col, i18nctx, **kwargs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   232
        """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   233
        :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
   234
        :param rtype: the relation bridging `etype` and `peid`
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   235
        :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
   236
        """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   237
        entity = self._entity()
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   238
        divonclick = "restoreInlinedEntity('%s', '%s', '%s')" % (
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   239
            self.peid, self.rtype, entity.eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   240
        self.render_form(i18nctx, divonclick=divonclick, **kwargs)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   241
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
   242
    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
   243
        """
4125a8021956 [#969169] don't display remove link in edition forms if the cardinality is 1
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 5769
diff changeset
   244
        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
   245
        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
   246
        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
   247
        """
4125a8021956 [#969169] don't display remove link in edition forms if the cardinality is 1
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 5769
diff changeset
   248
        entity = self._entity()
4125a8021956 [#969169] don't display remove link in edition forms if the cardinality is 1
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 5769
diff changeset
   249
        if isinstance(self.peid, int):
4125a8021956 [#969169] don't display remove link in edition forms if the cardinality is 1
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 5769
diff changeset
   250
            pentity = self._cw.entity_from_eid(self.peid)
4125a8021956 [#969169] don't display remove link in edition forms if the cardinality is 1
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 5769
diff changeset
   251
            petype = pentity.e_schema.type
4125a8021956 [#969169] don't display remove link in edition forms if the cardinality is 1
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 5769
diff changeset
   252
            rdef = entity.e_schema.rdef(self.rtype, neg_role(self.role), petype)
4125a8021956 [#969169] don't display remove link in edition forms if the cardinality is 1
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 5769
diff changeset
   253
            card= rdef.role_cardinality(self.role)
4125a8021956 [#969169] don't display remove link in edition forms if the cardinality is 1
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 5769
diff changeset
   254
            if card == '1': # don't display remove link
4125a8021956 [#969169] don't display remove link in edition forms if the cardinality is 1
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 5769
diff changeset
   255
                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
   256
        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
   257
            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
   258
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   259
    def render_form(self, i18nctx, **kwargs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   260
        """fetch and render the form"""
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   261
        entity = self._entity()
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   262
        divid = '%s-%s-%s' % (self.peid, self.rtype, entity.eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   263
        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
   264
        removejs = self._get_removejs()
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   265
        countkey = '%s_count' % self.rtype
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   266
        try:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   267
            self._cw.data[countkey] += 1
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   268
        except KeyError:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   269
            self._cw.data[countkey] = 1
6576
481249ecdc4f [3.10] remove a deprecation warning
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6427
diff changeset
   270
        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
   271
                         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
   272
                         **kwargs)
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   273
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   274
    def form_title(self, entity, i18nctx):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   275
        return self._cw.pgettext(i18nctx, entity.__regid__)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   276
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   277
    def add_hiddens(self, form, entity):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   278
        """to ease overriding (see cubes.vcsfile.views.forms for instance)"""
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   279
        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
   280
        #  * str(self.rtype) in case it's a schema object
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   281
        #  * 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
   282
        #    of the inlined entity
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   283
        form.add_hidden(name=str(self.rtype), value=self.peid,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   284
                        role=neg_role(self.role), eidparam=True, id=iid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   285
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   286
    def keep_entity(self, form, entity):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   287
        if not entity.has_eid():
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   288
            return True
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   289
        # are we regenerating form because of a validation error ?
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   290
        if form.form_previous_values:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   291
            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
   292
                                                form.form_previous_values)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   293
            if unicode(entity.eid) not in cdvalues:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   294
                return False
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   295
        return True
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   296
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   297
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   298
class InlineEntityCreationFormView(InlineEntityEditionFormView):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   299
    """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   300
    :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
   301
    """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   302
    __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
   303
    __select__ = (match_kwargs('peid', 'petype', 'rtype')
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   304
                  & 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
   305
    _select_attrs = InlineEntityEditionFormView._select_attrs + ('petype',)
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   306
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   307
    @property
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   308
    def removejs(self):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   309
        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
   310
        rdef = entity.e_schema.rdef(self.rtype, neg_role(self.role), self.petype)
4626
c26b4df9fc90 [forms/inline] fix #703911: add new link disappears if inline box removed. Since we've the information, we must specify the target type else we get random cardinality on ambiguous relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4625
diff changeset
   311
        card= rdef.role_cardinality(self.role)
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   312
        # 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
   313
        # 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
   314
        # 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
   315
        # 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
   316
        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
   317
            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
   318
            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
   319
                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
   320
        elif card in '+*':
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   321
            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
   322
        # don't do anything for card == '1'
4387
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
    @cached
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   325
    def _entity(self):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   326
        try:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   327
            cls = self._cw.vreg['etypes'].etype_class(self.etype)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   328
        except:
5693
8af6623f3d4e [pylint] fix detected name errors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5656
diff changeset
   329
            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
   330
            return
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   331
        entity = cls(self._cw)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   332
        entity.eid = self._cw.varmaker.next()
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   333
        return entity
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   334
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   335
    def call(self, i18nctx, **kwargs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   336
        self.render_form(i18nctx, **kwargs)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   337
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   338
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   339
class InlineAddNewLinkView(InlineEntityCreationFormView):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   340
    """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   341
    :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
   342
    """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   343
    __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
   344
    __select__ = (match_kwargs('peid', 'petype', 'rtype')
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   345
                  & specified_etype_implements('Any'))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   346
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   347
    _select_attrs = InlineEntityCreationFormView._select_attrs + ('card',)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   348
    form = None # no actual form wrapped
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   349
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   350
    def call(self, i18nctx, **kwargs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   351
        self._cw.set_varmaker()
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   352
        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
   353
        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
   354
          % 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
   355
        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
   356
            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
   357
        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
   358
            js = "toggleVisibility('%s'); %s" % (divid, js)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   359
        __ = self._cw.pgettext
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   360
        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
   361
          % (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
   362
        self.w(u'</div>')
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
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   365
# generic relations handling ##################################################
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   366
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   367
def relation_id(eid, rtype, role, reid):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   368
    """return an identifier for a relation between two entities"""
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   369
    if role == 'subject':
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   370
        return u'%s:%s:%s' % (eid, rtype, reid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   371
    return u'%s:%s:%s' % (reid, rtype, eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   372
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   373
def toggleable_relation_link(eid, nodeid, label='x'):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   374
    """return javascript snippet to delete/undelete a relation between two
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   375
    entities
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   376
    """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   377
    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
   378
        nodeid, xml_escape(json_dumps(eid)))
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   379
    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
   380
        js, nodeid, label)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   381
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   382
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   383
def get_pending_inserts(req, eid=None):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   384
    """shortcut to access req's pending_insert entry
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   385
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   386
    This is where are stored relations being added while editing
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   387
    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
   388
    """
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
   389
    pending = req.session.data.get('pending_insert', ())
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   390
    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
   391
            if eid is None or eid in (subj, obj)]
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 get_pending_deletes(req, eid=None):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   394
    """shortcut to access req's pending_delete entry
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   395
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   396
    This is where are stored relations being removed while editing
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   397
    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
   398
    """
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
   399
    pending = req.session.data.get('pending_delete', ())
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   400
    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
   401
            if eid is None or eid in (subj, obj)]
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
def parse_relations_descr(rdescr):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   404
    """parse a string describing some relations, in the form
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   405
    subjeids:rtype:objeids
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   406
    where subjeids and objeids are eids separeted by a underscore
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
    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
   409
    """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   410
    for rstr in rdescr:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   411
        subjs, rtype, objs = rstr.split(':')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   412
        for subj in subjs.split('_'):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   413
            for obj in objs.split('_'):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   414
                yield typed_eid(subj), rtype, typed_eid(obj)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   415
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   416
def delete_relations(req, rdefs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   417
    """delete relations from the repository"""
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   418
    # FIXME convert to using the syntax subject:relation:eids
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   419
    execute = req.execute
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   420
    for subj, rtype, obj in parse_relations_descr(rdefs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   421
        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
   422
        execute(rql, {'x': subj, 'y': obj})
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   423
    req.set_message(req._('relations deleted'))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   424
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   425
def insert_relations(req, rdefs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   426
    """insert relations into the repository"""
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   427
    execute = req.execute
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   428
    for subj, rtype, obj in parse_relations_descr(rdefs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   429
        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
   430
        execute(rql, {'x': subj, 'y': obj})
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   431
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   432
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   433
class GenericRelationsWidget(fw.FieldWidget):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   434
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   435
    def render(self, form, field, renderer):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   436
        stream = []
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   437
        w = stream.append
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   438
        req = form._cw
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   439
        _ = req._
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   440
        __ = _
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   441
        eid = form.edited_entity.eid
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   442
        w(u'<table id="relatedEntities">')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   443
        for rschema, role, related in field.relations_table(form):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   444
            # already linked entities
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   445
            if related:
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
   446
                label = rschema.display_name(req, role, context=form.edited_entity.__regid__)
5f6a60ea8544 [relations in ui] provide context information when computing label for a relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5940
diff changeset
   447
                w(u'<tr><th class="labelCol">%s</th>' % label)
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   448
                w(u'<td>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   449
                w(u'<ul>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   450
                for viewparams in related:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   451
                    w(u'<li class="invisible">%s<div id="span%s" class="%s">%s</div></li>'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   452
                      % (viewparams[1], viewparams[0], viewparams[2], viewparams[3]))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   453
                if not form.force_display and form.maxrelitems < len(related):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   454
                    link = (u'<span class="invisible">'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   455
                            '[<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
   456
                            '</span>' % _('view all'))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   457
                    w(u'<li class="invisible">%s</li>' % link)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   458
                w(u'</ul>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   459
                w(u'</td>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   460
                w(u'</tr>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   461
        pendings = list(field.restore_pending_inserts(form))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   462
        if not pendings:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   463
            w(u'<tr><th>&#160;</th><td>&#160;</td></tr>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   464
        else:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   465
            for row in pendings:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   466
                # soon to be linked to entities
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   467
                w(u'<tr id="tr%s">' % row[1])
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   468
                w(u'<th>%s</th>' % row[3])
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   469
                w(u'<td>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   470
                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
   471
                  (_('cancel this insert'), row[2]))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   472
                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
   473
                  % (row[1], row[4], xml_escape(row[5])))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   474
                w(u'</td>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   475
                w(u'</tr>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   476
        w(u'<tr id="relationSelectorRow_%s" class="separator">' % eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   477
        w(u'<th class="labelCol">')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   478
        w(u'<select id="relationSelector_%s" tabindex="%s" '
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   479
          '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
   480
          % (eid, req.next_tabindex(), xml_escape(json_dumps(eid))))
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   481
        w(u'<option value="">%s</option>' % _('select a relation'))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   482
        for i18nrtype, rschema, role in field.relations:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   483
            # more entities to link to
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   484
            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
   485
        w(u'</select>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   486
        w(u'</th>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   487
        w(u'<td id="unrelatedDivs_%s"></td>' % eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   488
        w(u'</tr>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   489
        w(u'</table>')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   490
        return '\n'.join(stream)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   491
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   492
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   493
class GenericRelationsField(ff.Field):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   494
    widget = GenericRelationsWidget
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   495
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   496
    def __init__(self, relations, name='_cw_generic_field', **kwargs):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   497
        assert relations
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   498
        kwargs['eidparam'] = True
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   499
        super(GenericRelationsField, self).__init__(name, **kwargs)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   500
        self.relations = relations
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   501
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   502
    def process_posted(self, form):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   503
        todelete = get_pending_deletes(form._cw)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   504
        if todelete:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   505
            delete_relations(form._cw, todelete)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   506
        toinsert = get_pending_inserts(form._cw)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   507
        if toinsert:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   508
            insert_relations(form._cw, toinsert)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   509
        return ()
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   510
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   511
    def relations_table(self, form):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   512
        """yiels 3-tuples (rtype, role, related_list)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   513
        where <related_list> itself a list of :
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   514
          - node_id (will be the entity element's DOM id)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   515
          - appropriate javascript's togglePendingDelete() function call
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   516
          - status 'pendingdelete' or ''
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   517
          - oneline view of related entity
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   518
        """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   519
        entity = form.edited_entity
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   520
        pending_deletes = get_pending_deletes(form._cw, entity.eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   521
        for label, rschema, role in self.relations:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   522
            related = []
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   523
            if entity.has_eid():
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   524
                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
   525
                if role == 'subject':
19d73051eb57 [autoform] we should consider role when checking delete permission
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   526
                    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
   527
                else:
19d73051eb57 [autoform] we should consider role when checking delete permission
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   528
                    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
   529
                if rschema.has_perm(form._cw, 'delete', **haspermkwargs):
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   530
                    toggleable_rel_link_func = toggleable_relation_link
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   531
                else:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   532
                    toggleable_rel_link_func = lambda x, y, z: u''
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   533
                for row in xrange(rset.rowcount):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   534
                    nodeid = relation_id(entity.eid, rschema, role,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   535
                                         rset[row][0])
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   536
                    if nodeid in pending_deletes:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   537
                        status, label = u'pendingDelete', '+'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   538
                    else:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   539
                        status, label = u'', 'x'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   540
                    dellink = toggleable_rel_link_func(entity.eid, nodeid, label)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   541
                    eview = form._cw.view('oneline', rset, row=row)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   542
                    related.append((nodeid, dellink, status, eview))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   543
            yield (rschema, role, related)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   544
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   545
    def restore_pending_inserts(self, form):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   546
        """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
   547
        'search for <some entity type>'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   548
        """
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   549
        entity = form.edited_entity
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   550
        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
   551
        for pendingid in pending_inserts:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   552
            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
   553
            pendingid = 'id' + pendingid
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   554
            if typed_eid(eidfrom) == entity.eid: # subject
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   555
                label = display_name(form._cw, rtype, 'subject',
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   556
                                     entity.__regid__)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   557
                reid = eidto
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   558
            else:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   559
                label = display_name(form._cw, rtype, 'object',
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   560
                                     entity.__regid__)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   561
                reid = eidfrom
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   562
            jscall = "javascript: cancelPendingInsert('%s', 'tr', null, %s);" \
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   563
                     % (pendingid, entity.eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   564
            rset = form._cw.eid_rset(reid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   565
            eview = form._cw.view('text', rset, row=0)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   566
            yield rtype, pendingid, jscall, label, reid, eview
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   567
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
class UnrelatedDivs(EntityView):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   570
    __regid__ = 'unrelateddivs'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   571
    __select__ = match_form_params('relation')
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 cell_call(self, row, col):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   574
        entity = self.cw_rset.get_entity(row, col)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   575
        relname, role = self._cw.form.get('relation').rsplit('_', 1)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   576
        rschema = self._cw.vreg.schema.rschema(relname)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   577
        hidden = 'hidden' in self._cw.form
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   578
        is_cell = 'is_cell' in self._cw.form
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   579
        self.w(self.build_unrelated_select_div(entity, rschema, role,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   580
                                               is_cell=is_cell, hidden=hidden))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   581
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   582
    def build_unrelated_select_div(self, entity, rschema, role,
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   583
                                   is_cell=False, hidden=True):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   584
        options = []
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   585
        divid = 'div%s_%s_%s' % (rschema.type, role, entity.eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   586
        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
   587
        if rschema.symmetric or role == 'subject':
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   588
            targettypes = rschema.objects(entity.e_schema)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   589
            etypes = '/'.join(sorted(etype.display_name(self._cw) for etype in targettypes))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   590
        else:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   591
            targettypes = rschema.subjects(entity.e_schema)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   592
            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
   593
        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
   594
        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
   595
        options += self._get_select_options(entity, rschema, role)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   596
        options += self._get_search_options(entity, rschema, role, targettypes)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   597
        relname, role = self._cw.form.get('relation').rsplit('_', 1)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   598
        return u"""\
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   599
<div class="%s" id="%s">
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   600
  <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
   601
    %s
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   602
  </select>
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   603
</div>
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   604
""" % (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
   605
       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
   606
       '\n'.join(options))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   607
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   608
    def _get_select_options(self, entity, rschema, role):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   609
        """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
   610
        options = []
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   611
        pending_inserts = get_pending_inserts(self._cw, entity.eid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   612
        rtype = rschema.type
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   613
        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
   614
        field = form.field_by_name(rschema, role, entity.e_schema)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   615
        limit = self._cw.property_value('navigation.combobox-limit')
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   616
        # NOTE: expect 'limit' arg on choices method of relation field
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   617
        for eview, reid in field.vocabulary(form, limit=limit):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   618
            if reid is None:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   619
                if eview: # skip blank value
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   620
                    options.append('<option class="separator">-- %s --</option>'
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   621
                                   % xml_escape(eview))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   622
            elif reid != ff.INTERNAL_FIELD_VALUE:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   623
                optionid = relation_id(entity.eid, rtype, role, reid)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   624
                if optionid not in pending_inserts:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   625
                    # 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
   626
                    options.append('<option id="id%s" value="%s">%s</option>' %
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   627
                                   (optionid, reid, xml_escape(eview)))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   628
        return options
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   629
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   630
    def _get_search_options(self, entity, rschema, role, targettypes):
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   631
        """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
   632
        options = []
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   633
        _ = self._cw._
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   634
        for eschema in targettypes:
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   635
            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
   636
            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
   637
                                 __mode=mode)
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   638
            options.append((eschema.display_name(self._cw),
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   639
                            '<option value="%s">%s %s</option>' % (
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   640
                xml_escape(url), _('Search for'), eschema.display_name(self._cw))))
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   641
        return [o for l, o in sorted(options)]
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   642
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   643
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   644
# The automatic entity form ####################################################
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   645
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
   646
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
   647
    """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
   648
    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
   649
    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
   650
5368
d321e4b62a10 [book] start documenting the HTML form system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4932
diff changeset
   651
    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
   652
    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
   653
    adding/removing fields in selected instances.
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   654
    """
3408
c92170fca813 [api] use __regid__ instead of deprecated id
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3360
diff changeset
   655
    __regid__ = 'edition'
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   656
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   657
    cwtarget = 'eformframe'
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   658
    cssclass = 'entityForm'
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   659
    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
   660
    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
   661
                    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
   662
                    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
   663
    # 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
   664
    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
   665
    # 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
   666
    # 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
   667
    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
   668
    # 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
   669
    _default_form_action_path = 'validateform'
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   670
5592
41ad8ca3047e [form] fix bw compat issue introduced by 5588:377c9adfe81e
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5588
diff changeset
   671
    # pre 3.8.3 compat
41ad8ca3047e [form] fix bw compat issue introduced by 5588:377c9adfe81e
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5588
diff changeset
   672
    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
   673
        self._action = action
41ad8ca3047e [form] fix bw compat issue introduced by 5588:377c9adfe81e
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5588
diff changeset
   674
    def get_action(self):
41ad8ca3047e [form] fix bw compat issue introduced by 5588:377c9adfe81e
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5588
diff changeset
   675
        try:
41ad8ca3047e [form] fix bw compat issue introduced by 5588:377c9adfe81e
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5588
diff changeset
   676
            return self._action
41ad8ca3047e [form] fix bw compat issue introduced by 5588:377c9adfe81e
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5588
diff changeset
   677
        except AttributeError:
41ad8ca3047e [form] fix bw compat issue introduced by 5588:377c9adfe81e
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5588
diff changeset
   678
            return self._cw.build_url(self._default_form_action_path)
5656
abe97430b3f5 [form] avoid spurious warning subsequent for form's action refactoring w/ autoforms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5612
diff changeset
   679
    action = property(deprecated('[3.9] use form.form_action()')(get_action),
abe97430b3f5 [form] avoid spurious warning subsequent for form's action refactoring w/ autoforms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5612
diff changeset
   680
                      set_action)
5592
41ad8ca3047e [form] fix bw compat issue introduced by 5588:377c9adfe81e
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5588
diff changeset
   681
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
   682
    @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
   683
    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
   684
        """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
   685
        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
   686
        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
   687
        """
35cd057339b2 turn all the stuff used to handle 'generic relations' in forms into proper
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   688
        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
   689
            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
   690
        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
   691
            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
   692
                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
   693
            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
   694
3360
b02df886eb3e cleanup, reorganize
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3358
diff changeset
   695
    # base automatic entity form methods #######################################
b02df886eb3e cleanup, reorganize
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3358
diff changeset
   696
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   697
    def __init__(self, *args, **kwargs):
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   698
        super(AutomaticEntityForm, self).__init__(*args, **kwargs)
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   699
        entity = self.edited_entity
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   700
        if entity.has_eid():
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   701
            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
   702
        for rtype, role in self.editable_attributes():
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   703
            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
   704
                self.field_by_name(str(rtype), role)
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   705
                continue # explicitly specified
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   706
            except f.FieldNotFound:
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   707
                # has to be guessed
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   708
                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
   709
                    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
   710
                                               eschema=entity.e_schema)
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   711
                    self.fields.append(field)
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   712
                except f.FieldNotFound:
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   713
                    # meta attribute such as <attr>_format
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   714
                    continue
4642
606364845c34 [auto/inline forms] reallow nested inline forms #703910
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4629
diff changeset
   715
        if self.fieldsets_in_order:
606364845c34 [auto/inline forms] reallow nested inline forms #703910
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4629
diff changeset
   716
            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
   717
        else:
606364845c34 [auto/inline forms] reallow nested inline forms #703910
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4629
diff changeset
   718
            fsio = [None]
606364845c34 [auto/inline forms] reallow nested inline forms #703910
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4629
diff changeset
   719
        self.fieldsets_in_order = fsio
606364845c34 [auto/inline forms] reallow nested inline forms #703910
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4629
diff changeset
   720
        # 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
   721
        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
   722
            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
   723
            self.fields.append(field)
606364845c34 [auto/inline forms] reallow nested inline forms #703910
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4629
diff changeset
   724
            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
   725
                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
   726
        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
   727
            # 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
   728
            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
   729
                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
   730
                '_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
   731
                try:
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   732
                    field = self.field_by_name('_cw_generic_field')
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   733
                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
   734
                    # 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
   735
                    pass
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   736
                else:
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   737
                    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
   738
                    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
   739
                        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
   740
        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
   741
        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
   742
        fnum = len(self.fields)
7d0d4a6be046 [formfields] allow fields ordering with autoform_field_kwargs
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3689
diff changeset
   743
        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
   744
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   745
    @property
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   746
    def related_limit(self):
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   747
        if self.force_display:
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   748
            return None
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   749
        return self.maxrelitems + 1
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   750
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   751
    # 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
   752
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   753
    def _generic_relations_field(self):
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   754
        try:
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   755
            srels_by_cat = self.srelations_by_category('generic', 'add', strict=True)
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   756
            warn('[3.6] %s: srelations_by_category is deprecated, use uicfg or '
5693
8af6623f3d4e [pylint] fix detected name errors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5656
diff changeset
   757
                 'override editable_relations instead' % classid(self),
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   758
                 DeprecationWarning)
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   759
        except AttributeError:
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   760
            srels_by_cat = self.editable_relations()
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   761
        if not srels_by_cat:
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   762
            raise f.FieldNotFound('_cw_generic_field')
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   763
        fieldset = u'%s :' % self._cw.__('This %s' % self.edited_entity.e_schema)
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   764
        fieldset = fieldset.capitalize()
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   765
        return GenericRelationsField(self.editable_relations(),
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   766
                                     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
   767
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   768
    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
   769
        # XXX allow more customization
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   770
        kwargs = _AFFK.etype_get(self.edited_entity.e_schema, view.rtype,
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   771
                                 view.role, view.etype)
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   772
        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
   773
            kwargs = {}
4387
4aacd6492ef4 reorganize code:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4379
diff changeset
   774
        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
   775
3360
b02df886eb3e cleanup, reorganize
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3358
diff changeset
   776
    # methods mapping edited entity relations to fields in the form ############
b02df886eb3e cleanup, reorganize
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3358
diff changeset
   777
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
   778
    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
   779
        """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
   780
        given category(ies) and permission
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   781
        """
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   782
        return _AFS.relations_by_section(
3476
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   783
            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
   784
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   785
    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
   786
        """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
   787
        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
   788
            schema = self._cw.vreg.schema
b07ee816bffb fix editable_attributes bug (closes #1534802)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6725
diff changeset
   789
            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
   790
        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
   791
            return []
3476
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   792
        # XXX we should simply put eid in the generated section, no?
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   793
        return [(rtype, role) for rtype, _, role in self._relations_by_section(
4758
0efdcf0fa4c7 fix code and tests broken by 4744:13a5d3a7410e (proper permission on eid/has_text/identity relations)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4642
diff changeset
   794
            'attributes', 'update', strict)]
3476
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   795
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   796
    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
   797
        """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
   798
        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
   799
        """
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
   800
        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
   801
        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
   802
                                                           strict=True):
3505
c0c7a944c00d fix dumb name error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
   803
            result.append( (rschema.display_name(self.edited_entity._cw, role,
c0c7a944c00d fix dumb name error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3503
diff changeset
   804
                                                 self.edited_entity.__regid__),
3476
6e927b729ae1 [uicfg, autoform] more consistent/powerful autoform_section rtags by using formtype/section; deprecates autoform_is_inlined; refactor automatci form and renderer thanks to this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3468
diff changeset
   805
                            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
   806
        return sorted(result)
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   807
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   808
    def inlined_relations(self):
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   809
        """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
   810
        given category(ies) and permission
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   811
        """
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
   812
        return self._relations_by_section('inlined')
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   813
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   814
    # inlined forms control ####################################################
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   815
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
   816
    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
   817
        """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
   818
        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
   819
        """
3593
987232bd79cd fix inlined forms initialization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3586
diff changeset
   820
        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
   821
        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
   822
        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
   823
            # 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
   824
            # 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
   825
            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
   826
                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
   827
                             '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
   828
                             '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
   829
                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
   830
            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
   831
            ttype = tschema.type
6394
eb9a5bd778bc [forms] remove dead code and simplify inlineviews creation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6101
diff changeset
   832
            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
   833
            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
   834
            # 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
   835
            # 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
   836
            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
   837
                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
   838
            # 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
   839
            # to add new related entities
eb9a5bd778bc [forms] remove dead code and simplify inlineviews creation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6101
diff changeset
   840
            if self.should_display_add_new_relation_link(rschema, formviews, card):
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
   841
                rdef = entity.e_schema.rdef(rschema, role, ttype)
6630
f516ee1ef36c [inline form] ensure entity has an actual eid before using it to check perms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6577
diff changeset
   842
                if entity.has_eid():
f516ee1ef36c [inline form] ensure entity has an actual eid before using it to check perms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6577
diff changeset
   843
                    if role == 'subject':
f516ee1ef36c [inline form] ensure entity has an actual eid before using it to check perms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6577
diff changeset
   844
                        rdefkwargs = {'fromeid': entity.eid}
f516ee1ef36c [inline form] ensure entity has an actual eid before using it to check perms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6577
diff changeset
   845
                    else:
f516ee1ef36c [inline form] ensure entity has an actual eid before using it to check perms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6577
diff changeset
   846
                        rdefkwargs = {'toeid': entity.eid}
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
   847
                else:
6630
f516ee1ef36c [inline form] ensure entity has an actual eid before using it to check perms
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6577
diff changeset
   848
                    rdefkwargs = {}
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
   849
                if (tschema.has_perm(self._cw, 'add')
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
   850
                    and rdef.has_perm(self._cw, 'add', **rdefkwargs)):
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
   851
                    addnewlink = self._cw.vreg['views'].select(
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
   852
                        'inline-addnew-link', self._cw,
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
   853
                        etype=ttype, rtype=rschema, role=role, card=card,
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
   854
                        peid=self.edited_entity.eid,
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
   855
                        petype=self.edited_entity.e_schema, pform=self)
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
   856
                    formviews.append(addnewlink)
6394
eb9a5bd778bc [forms] remove dead code and simplify inlineviews creation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6101
diff changeset
   857
            allformviews += formviews
3593
987232bd79cd fix inlined forms initialization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3586
diff changeset
   858
        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
   859
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   860
    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
   861
        """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
   862
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   863
        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
   864
        """
6394
eb9a5bd778bc [forms] remove dead code and simplify inlineviews creation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6101
diff changeset
   865
        return not existant and card in '1+'
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   866
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   867
    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
   868
        """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
   869
        (through ajax call)
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   870
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   871
        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
   872
        multiple cardinality
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   873
        """
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
   874
        return not existant or card in '+*'
1491
742aff97dbf7 move AutomaticEntityForm and PrimaryView into their own module
sylvain.thenault@logilab.fr
parents:
diff changeset
   875
3332
91cff87c368f introduced to ease overriding for fancy stuff...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3293
diff changeset
   876
    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
   877
        """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
   878
        link should be hidden
91cff87c368f introduced to ease overriding for fancy stuff...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3293
diff changeset
   879
91cff87c368f introduced to ease overriding for fancy stuff...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3293
diff changeset
   880
        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
   881
        """
91cff87c368f introduced to ease overriding for fancy stuff...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3293
diff changeset
   882
        return card in '1?'
91cff87c368f introduced to ease overriding for fancy stuff...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3293
diff changeset
   883
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
   884
    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
   885
        """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
   886
        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
   887
        """
11ce4682187d [form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3470
diff changeset
   888
        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
   889
        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
   890
        if related:
3524
a3431f4e2f40 backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3505 3521
diff changeset
   891
            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
   892
            # 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
   893
            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
   894
                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
   895
                    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
   896
                                       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
   897
                                       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
   898
                                       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
   899
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
   900
    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
   901
        """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
   902
        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
   903
        """
3524
a3431f4e2f40 backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3505 3521
diff changeset
   904
        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
   905
                                            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
   906
                                            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
   907
                                            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
   908
                                            pform=self)
2652
3753f3a07ca1 [refactoring] moved rtags specification in web/views
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2143
diff changeset
   909
3753f3a07ca1 [refactoring] moved rtags specification in web/views
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2143
diff changeset
   910
3753f3a07ca1 [refactoring] moved rtags specification in web/views
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2143
diff changeset
   911
## default form ui configuration ##############################################
3753f3a07ca1 [refactoring] moved rtags specification in web/views
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2143
diff changeset
   912
3753f3a07ca1 [refactoring] moved rtags specification in web/views
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2143
diff changeset
   913
# use primary and not generated for eid since it has to be an hidden
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   914
_AFS.tag_attribute(('*', 'eid'), 'main', 'attributes')
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   915
_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
   916
_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
   917
_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
   918
_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
   919
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
   920
              '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
   921
    _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
   922
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   923
_AFS.tag_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
   924
_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
   925
_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
   926
_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
   927
_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
   928
_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
   929
_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
   930
_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
   931
_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
   932
_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
   933
_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
   934
_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
   935
_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
   936
_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
   937
_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
   938
_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
   939
_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
   940
_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
   941
_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
   942
_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
   943
4378
785c56bdacc6 [forms] the last touch: handle inlined relation forms as fields
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4360
diff changeset
   944
_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
   945
                    {'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
   946
_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
   947
                     {'widget': fw.HiddenInput})
2652
3753f3a07ca1 [refactoring] moved rtags specification in web/views
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2143
diff changeset
   948
4105
de31c3afe975 fix 3.6 bug
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4083
diff changeset
   949
def registration_callback(vreg):
de31c3afe975 fix 3.6 bug
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4083
diff changeset
   950
    global etype_relation_field
de31c3afe975 fix 3.6 bug
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4083
diff changeset
   951
de31c3afe975 fix 3.6 bug
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4083
diff changeset
   952
    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
   953
        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
   954
            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
   955
            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
   956
        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
   957
            # 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
   958
            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
   959
            return None
4110
8728d8c95985 [mq]: fix_for_forms
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 4105
diff changeset
   960
8728d8c95985 [mq]: fix_for_forms
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 4105
diff changeset
   961
    vreg.register_all(globals().values(), __name__)