web/box.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Mon, 25 Jan 2010 19:27:30 +0100
changeset 4342 b4e186da08f2
parent 4252 6c4f109c2b03
child 4345 06a34ff6b49a
permissions -rw-r--r--
handle lgc.adbh api changes within regards of backup/restore: * new backup_commands method instead of backup_command * some backend still return command as string as expected by os.system, not subprocess.call
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     1
"""abstract box classes for CubicWeb web client
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     2
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     3
:organization: Logilab
4212
ab6573088b4a update copyright: welcome 2010
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4205
diff changeset
     4
:copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     5
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
1977
606923dff11b big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1885
diff changeset
     6
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     7
"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     8
__docformat__ = "restructuredtext en"
2159
0ca23d0eace2 move up
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
     9
_ = unicode
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    10
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2159
diff changeset
    11
from logilab.mtconverter import xml_escape
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    12
1149
1e19b6ef53a1 pylint cleanup
sylvain.thenault@logilab.fr
parents: 838
diff changeset
    13
from cubicweb import Unauthorized, role as get_role, target as get_target
2710
40789c3044f3 [web.box] remove deprecation warnings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2381
diff changeset
    14
from cubicweb.schema import display_name
652
603c782dc092 various SyntaxErrors / missing import fixes + reorganization of the `registered` classmethod
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 640
diff changeset
    15
from cubicweb.selectors import (one_line_rset,  primary_view,
2819
b864288fd316 remove more 3.2 deprecated code, reintroduce checkbox used by formrenderers
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2799
diff changeset
    16
                                match_context_prop, partial_has_related_entities)
816
9cd49a910fce kill Template class and 'templates' registry
sylvain.thenault@logilab.fr
parents: 809
diff changeset
    17
from cubicweb.view import View, ReloadableMixIn
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    18
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
from cubicweb.web.htmlwidgets import (BoxLink, BoxWidget, SideBoxWidget,
250
7fd7a0d387d7 new RelatedEntityBoxTemplate base class
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 237
diff changeset
    20
                                      RawBoxItem, BoxSeparator)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    21
from cubicweb.web.action import UnregisteredAction
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    22
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    23
816
9cd49a910fce kill Template class and 'templates' registry
sylvain.thenault@logilab.fr
parents: 809
diff changeset
    24
class BoxTemplate(View):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    25
    """base template for boxes, usually a (contextual) list of possible
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
    26
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    27
    actions. Various classes attributes may be used to control the box
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    28
    rendering.
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
    29
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    30
    You may override on of the formatting callbacks is this is not necessary
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    31
    for your custom box.
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
    32
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    33
    Classes inheriting from this class usually only have to override call
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    34
    to fetch desired actions, and then to do something like  ::
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    35
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    36
        box.render(self.w)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    37
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    38
    __registry__ = 'boxes'
809
31962f99770b fix box selectors
sylvain.thenault@logilab.fr
parents: 782
diff changeset
    39
    __select__ = match_context_prop()
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
    40
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    41
    categories_in_order = ()
2799
b703639614e7 refactor property handling to avoid name conflicts
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2789
diff changeset
    42
    cw_property_defs = {
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    43
        _('visible'): dict(type='Boolean', default=True,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    44
                           help=_('display the box or not')),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    45
        _('order'):   dict(type='Int', default=99,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    46
                           help=_('display order of the box')),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    47
        # XXX 'incontext' boxes are handled by the default primary view
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    48
        _('context'): dict(type='String', default='left',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    49
                           vocabulary=(_('left'), _('incontext'), _('right')),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    50
                           help=_('context where this box should be displayed')),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    51
        }
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    52
    context = 'left'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    53
    htmlitemclass = 'boxItem'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    54
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    55
    def sort_actions(self, actions):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    56
        """return a list of (category, actions_sorted_by_title)"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    57
        result = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    58
        actions_by_cat = {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    59
        for action in actions:
3220
11b6016e3970 cleanup, futur warning fixes :)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2757
diff changeset
    60
            actions_by_cat.setdefault(action.category, []).append(
11b6016e3970 cleanup, futur warning fixes :)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2757
diff changeset
    61
                (action.title, action) )
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    62
        for key, values in actions_by_cat.items():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    63
            actions_by_cat[key] = [act for title, act in sorted(values)]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    64
        for cat in self.categories_in_order:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    65
            if cat in actions_by_cat:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    66
                result.append( (cat, actions_by_cat[cat]) )
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    67
        for item in sorted(actions_by_cat.items()):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    68
            result.append(item)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    69
        return result
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    70
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    71
    def mk_action(self, title, path, escape=True, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    72
        """factory function to create dummy actions compatible with the
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    73
        .format_actions method
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    74
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    75
        if escape:
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2159
diff changeset
    76
            title = xml_escape(title)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    77
        return self.box_action(self._action(title, path, **kwargs))
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
    78
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    79
    def _action(self, title, path, **kwargs):
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3230
diff changeset
    80
        return UnregisteredAction(self._cw, self.cw_rset, title, path, **kwargs)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    81
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    82
    # formating callbacks
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    83
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    84
    def boxitem_link_tooltip(self, action):
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3230
diff changeset
    85
        if action.__regid__:
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3230
diff changeset
    86
            return u'keyword: %s' % action.__regid__
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    87
        return u''
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    88
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    89
    def box_action(self, action):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    90
        cls = getattr(action, 'html_class', lambda: None)() or self.htmlitemclass
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3230
diff changeset
    91
        return BoxLink(action.url(), self._cw._(action.title),
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    92
                       cls, self.boxitem_link_tooltip(action))
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
    93
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    94
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    95
class RQLBoxTemplate(BoxTemplate):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    96
    """abstract box for boxes displaying the content of a rql query not
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    97
    related to the current result set.
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
    98
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    99
    It rely on etype, rtype (both optional, usable to control registration
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   100
    according to application schema and display according to connected
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   101
    user's rights) and rql attributes
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   102
    """
640
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 526
diff changeset
   103
#XXX    __selectors__ = BoxTemplate.__selectors__ + (etype_rtype_selector,)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   104
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   105
    rql  = None
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
   106
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   107
    def to_display_rql(self):
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3230
diff changeset
   108
        assert self.rql is not None, self.__regid__
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   109
        return (self.rql,)
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
   110
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   111
    def call(self, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   112
        try:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3230
diff changeset
   113
            rset = self._cw.execute(*self.to_display_rql())
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   114
        except Unauthorized:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   115
            # can't access to something in the query, forget this box
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   116
            return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   117
        if len(rset) == 0:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   118
            return
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3230
diff changeset
   119
        box = BoxWidget(self._cw._(self.title), self.__regid__)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   120
        for i, (teid, tname) in enumerate(rset):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   121
            entity = rset.get_entity(i, 0)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   122
            box.append(self.mk_action(tname, entity.absolute_url()))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   123
        box.render(w=self.w)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   124
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
   125
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   126
class UserRQLBoxTemplate(RQLBoxTemplate):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   127
    """same as rql box template but the rql is build using the eid of the
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   128
    request's user
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   129
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   130
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   131
    def to_display_rql(self):
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3230
diff changeset
   132
        assert self.rql is not None, self.__regid__
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3230
diff changeset
   133
        return (self.rql, {'x': self._cw.user.eid}, 'x')
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
   134
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   135
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   136
class EntityBoxTemplate(BoxTemplate):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   137
    """base class for boxes related to a single entity"""
809
31962f99770b fix box selectors
sylvain.thenault@logilab.fr
parents: 782
diff changeset
   138
    __select__ = BoxTemplate.__select__ & one_line_rset() & primary_view()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   139
    context = 'incontext'
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
   140
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   141
    def call(self, row=0, col=0, **kwargs):
526
sylvain.thenault@logilab.fr
parents: 455
diff changeset
   142
        """classes inheriting from EntityBoxTemplate should define cell_call"""
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   143
        self.cell_call(row, col, **kwargs)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   144
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   145
250
7fd7a0d387d7 new RelatedEntityBoxTemplate base class
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 237
diff changeset
   146
class RelatedEntityBoxTemplate(EntityBoxTemplate):
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 816
diff changeset
   147
    __select__ = EntityBoxTemplate.__select__ & partial_has_related_entities()
742
99115e029dca replaced most of __selectors__ assignments with __select__
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 670
diff changeset
   148
250
7fd7a0d387d7 new RelatedEntityBoxTemplate base class
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 237
diff changeset
   149
    def cell_call(self, row, col, **kwargs):
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3230
diff changeset
   150
        entity = self.cw_rset.get_entity(row, col)
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3230
diff changeset
   151
        limit = self._cw.property_value('navigation.related-limit') + 1
250
7fd7a0d387d7 new RelatedEntityBoxTemplate base class
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 237
diff changeset
   152
        role = get_role(self)
1885
c2011d238e98 replace sideRelated with sideBox
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 1696
diff changeset
   153
        self.w(u'<div class="sideBox">')
250
7fd7a0d387d7 new RelatedEntityBoxTemplate base class
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 237
diff changeset
   154
        self.wview('sidebox', entity.related(self.rtype, role, limit=limit),
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3230
diff changeset
   155
                   title=display_name(self._cw, self.rtype, role))
250
7fd7a0d387d7 new RelatedEntityBoxTemplate base class
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 237
diff changeset
   156
        self.w(u'</div>')
7fd7a0d387d7 new RelatedEntityBoxTemplate base class
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 237
diff changeset
   157
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   158
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   159
class EditRelationBoxTemplate(ReloadableMixIn, EntityBoxTemplate):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   160
    """base class for boxes which let add or remove entities linked
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   161
    by a given relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   162
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   163
    subclasses should define at least id, rtype and target
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   164
    class attributes.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   165
    """
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
   166
1624
baf484a182cd should take arbitrary arguments
sylvain.thenault@logilab.fr
parents: 1493
diff changeset
   167
    def cell_call(self, row, col, view=None, **kwargs):
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3230
diff changeset
   168
        self._cw.add_js('cubicweb.ajax.js')
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3230
diff changeset
   169
        entity = self.cw_rset.get_entity(row, col)
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3230
diff changeset
   170
        box = SideBoxWidget(display_name(self._cw, self.rtype), self.__regid__)
2757
c8e28e1754f0 B [web.box] fix EditRelationBoxTemplate in case neither related nor unrelated
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2710
diff changeset
   171
        related = self.related_boxitems(entity)
c8e28e1754f0 B [web.box] fix EditRelationBoxTemplate in case neither related nor unrelated
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2710
diff changeset
   172
        unrelated = self.unrelated_boxitems(entity)
c8e28e1754f0 B [web.box] fix EditRelationBoxTemplate in case neither related nor unrelated
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2710
diff changeset
   173
        box.extend(related)
c8e28e1754f0 B [web.box] fix EditRelationBoxTemplate in case neither related nor unrelated
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2710
diff changeset
   174
        if related and unrelated:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   175
            box.append(BoxSeparator())
2757
c8e28e1754f0 B [web.box] fix EditRelationBoxTemplate in case neither related nor unrelated
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2710
diff changeset
   176
        box.extend(unrelated)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   177
        box.render(self.w)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   178
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   179
    def div_id(self):
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3230
diff changeset
   180
        return self.__regid__
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
   181
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   182
    def box_item(self, entity, etarget, rql, label):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   183
        """builds HTML link to edit relation between `entity` and `etarget`
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   184
        """
1149
1e19b6ef53a1 pylint cleanup
sylvain.thenault@logilab.fr
parents: 838
diff changeset
   185
        role, target = get_role(self), get_target(self)
1e19b6ef53a1 pylint cleanup
sylvain.thenault@logilab.fr
parents: 838
diff changeset
   186
        args = {role[0] : entity.eid, target[0] : etarget.eid}
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   187
        url = self.user_rql_callback((rql, args))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   188
        # for each target, provide a link to edit the relation
4205
4458c7cc193b must escape user_rql_callback
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3220
diff changeset
   189
        label = u'[<a href="%s">%s</a>] %s' % (xml_escape(url), label,
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   190
                                               etarget.view('incontext'))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   191
        return RawBoxItem(label, liclass=u'invisible')
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
   192
2757
c8e28e1754f0 B [web.box] fix EditRelationBoxTemplate in case neither related nor unrelated
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2710
diff changeset
   193
    def related_boxitems(self, entity):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   194
        rql = 'DELETE S %s O WHERE S eid %%(s)s, O eid %%(o)s' % self.rtype
2757
c8e28e1754f0 B [web.box] fix EditRelationBoxTemplate in case neither related nor unrelated
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2710
diff changeset
   195
        related = []
c8e28e1754f0 B [web.box] fix EditRelationBoxTemplate in case neither related nor unrelated
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2710
diff changeset
   196
        for etarget in self.related_entities(entity):
c8e28e1754f0 B [web.box] fix EditRelationBoxTemplate in case neither related nor unrelated
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2710
diff changeset
   197
            related.append(self.box_item(entity, etarget, rql, u'-'))
c8e28e1754f0 B [web.box] fix EditRelationBoxTemplate in case neither related nor unrelated
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2710
diff changeset
   198
        return related
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
   199
2757
c8e28e1754f0 B [web.box] fix EditRelationBoxTemplate in case neither related nor unrelated
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2710
diff changeset
   200
    def unrelated_boxitems(self, entity):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   201
        rql = 'SET S %s O WHERE S eid %%(s)s, O eid %%(o)s' % self.rtype
2757
c8e28e1754f0 B [web.box] fix EditRelationBoxTemplate in case neither related nor unrelated
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2710
diff changeset
   202
        unrelated = []
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   203
        for etarget in self.unrelated_entities(entity):
2757
c8e28e1754f0 B [web.box] fix EditRelationBoxTemplate in case neither related nor unrelated
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2710
diff changeset
   204
            unrelated.append(self.box_item(entity, etarget, rql, u'+'))
c8e28e1754f0 B [web.box] fix EditRelationBoxTemplate in case neither related nor unrelated
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2710
diff changeset
   205
        return unrelated
c8e28e1754f0 B [web.box] fix EditRelationBoxTemplate in case neither related nor unrelated
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2710
diff changeset
   206
c8e28e1754f0 B [web.box] fix EditRelationBoxTemplate in case neither related nor unrelated
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2710
diff changeset
   207
    def related_entities(self, entity):
c8e28e1754f0 B [web.box] fix EditRelationBoxTemplate in case neither related nor unrelated
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2710
diff changeset
   208
        return entity.related(self.rtype, get_role(self), entities=True)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   209
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   210
    def unrelated_entities(self, entity):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   211
        """returns the list of unrelated entities
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   212
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   213
        if etype is not defined on the Box's class, the default
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   214
        behaviour is to use the entity's appropraite vocabulary function
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   215
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   216
        # use entity.unrelated if we've been asked for a particular etype
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   217
        if hasattr(self, 'etype'):
1149
1e19b6ef53a1 pylint cleanup
sylvain.thenault@logilab.fr
parents: 838
diff changeset
   218
            return entity.unrelated(self.rtype, self.etype, get_role(self)).entities()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   219
        # in other cases, use vocabulary functions
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   220
        entities = []
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3230
diff changeset
   221
        form = self.vreg['forms'].select('edition', self._cw, rset=self.cw_rset,
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3230
diff changeset
   222
                                         row=self.cw_row or 0)
1695
9a9822f3cb6c update implementation to get vocab from form instead of entity
sylvain.thenault@logilab.fr
parents: 1624
diff changeset
   223
        field = form.field_by_name(self.rtype, get_role(self), entity.e_schema)
4161
4273f5094651 refactor vocabulary handling to avoid having to define methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4094
diff changeset
   224
        for _, eid in field.choices(form):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   225
            if eid is not None:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3230
diff changeset
   226
                rset = self._cw.eid_rset(eid)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   227
                entities.append(rset.get_entity(0, 0))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   228
        return entities
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
   229