web/box.py
author Nicolas Chauvat <nicolas.chauvat@logilab.fr>
Thu, 04 Jun 2009 17:21:29 +0200
changeset 2039 6c036e4d9ad4
parent 1977 606923dff11b
child 2058 7ef12c03447c
child 2159 0ca23d0eace2
permissions -rw-r--r--
Added tag cubicweb-debian-version-3_3_0-1 for changeset 07214e923e75
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
1977
606923dff11b big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1885
diff changeset
     4
:copyright: 2001-2009 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"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     9
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    10
from logilab.mtconverter import html_escape
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    11
1149
1e19b6ef53a1 pylint cleanup
sylvain.thenault@logilab.fr
parents: 838
diff changeset
    12
from cubicweb import Unauthorized, role as get_role, target as get_target
652
603c782dc092 various SyntaxErrors / missing import fixes + reorganization of the `registered` classmethod
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 640
diff changeset
    13
from cubicweb.selectors import (one_line_rset,  primary_view,
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 816
diff changeset
    14
                                match_context_prop, partial_has_related_entities,
816
9cd49a910fce kill Template class and 'templates' registry
sylvain.thenault@logilab.fr
parents: 809
diff changeset
    15
                                accepts_compat, has_relation_compat,
9cd49a910fce kill Template class and 'templates' registry
sylvain.thenault@logilab.fr
parents: 809
diff changeset
    16
                                condition_compat, require_group_compat)
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
_ = unicode
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    24
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    25
816
9cd49a910fce kill Template class and 'templates' registry
sylvain.thenault@logilab.fr
parents: 809
diff changeset
    26
class BoxTemplate(View):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    27
    """base template for boxes, usually a (contextual) list of possible
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
    28
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    29
    actions. Various classes attributes may be used to control the box
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    30
    rendering.
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
    31
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    32
    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
    33
    for your custom box.
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
    34
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    35
    Classes inheriting from this class usually only have to override call
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    36
    to fetch desired actions, and then to do something like  ::
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
        box.render(self.w)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    39
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    40
    __registry__ = 'boxes'
809
31962f99770b fix box selectors
sylvain.thenault@logilab.fr
parents: 782
diff changeset
    41
    __select__ = match_context_prop()
1181
620ec8e6ae19 cleanup, various fix to get something working
sylvain.thenault@logilab.fr
parents: 1149
diff changeset
    42
    registered = classmethod(require_group_compat(View.registered))
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
    43
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    44
    categories_in_order = ()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    45
    property_defs = {
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    46
        _('visible'): dict(type='Boolean', default=True,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    47
                           help=_('display the box or not')),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    48
        _('order'):   dict(type='Int', default=99,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    49
                           help=_('display order of the box')),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    50
        # XXX 'incontext' boxes are handled by the default primary view
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    51
        _('context'): dict(type='String', default='left',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    52
                           vocabulary=(_('left'), _('incontext'), _('right')),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    53
                           help=_('context where this box should be displayed')),
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
    context = 'left'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    56
    htmlitemclass = 'boxItem'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    57
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    58
    def sort_actions(self, actions):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    59
        """return a list of (category, actions_sorted_by_title)"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    60
        result = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    61
        actions_by_cat = {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    62
        for action in actions:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    63
            actions_by_cat.setdefault(action.category, []).append((action.title, action))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    64
        for key, values in actions_by_cat.items():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    65
            actions_by_cat[key] = [act for title, act in sorted(values)]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    66
        for cat in self.categories_in_order:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    67
            if cat in actions_by_cat:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    68
                result.append( (cat, actions_by_cat[cat]) )
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    69
        for item in sorted(actions_by_cat.items()):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    70
            result.append(item)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    71
        return result
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    72
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    73
    def mk_action(self, title, path, escape=True, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    74
        """factory function to create dummy actions compatible with the
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    75
        .format_actions method
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    76
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    77
        if escape:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    78
            title = html_escape(title)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    79
        return self.box_action(self._action(title, path, **kwargs))
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
    80
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    81
    def _action(self, title, path, **kwargs):
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
    82
        return UnregisteredAction(self.req, self.rset, title, path, **kwargs)
0
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
    # formating callbacks
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    85
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    86
    def boxitem_link_tooltip(self, action):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    87
        if action.id:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    88
            return u'keyword: %s' % action.id
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    89
        return u''
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    90
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    91
    def box_action(self, action):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    92
        cls = getattr(action, 'html_class', lambda: None)() or self.htmlitemclass
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    93
        return BoxLink(action.url(), self.req._(action.title),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    94
                       cls, self.boxitem_link_tooltip(action))
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
    95
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    96
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    97
class RQLBoxTemplate(BoxTemplate):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    98
    """abstract box for boxes displaying the content of a rql query not
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    99
    related to the current result set.
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
   100
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   101
    It rely on etype, rtype (both optional, usable to control registration
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   102
    according to application schema and display according to connected
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   103
    user's rights) and rql attributes
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   104
    """
640
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 526
diff changeset
   105
#XXX    __selectors__ = BoxTemplate.__selectors__ + (etype_rtype_selector,)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   106
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   107
    rql  = None
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
   108
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   109
    def to_display_rql(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   110
        assert self.rql is not None, self.id
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   111
        return (self.rql,)
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
   112
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   113
    def call(self, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   114
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   115
            rset = self.req.execute(*self.to_display_rql())
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   116
        except Unauthorized:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   117
            # can't access to something in the query, forget this box
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   118
            return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   119
        if len(rset) == 0:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   120
            return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   121
        box = BoxWidget(self.req._(self.title), self.id)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   122
        for i, (teid, tname) in enumerate(rset):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   123
            entity = rset.get_entity(i, 0)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   124
            box.append(self.mk_action(tname, entity.absolute_url()))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   125
        box.render(w=self.w)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   126
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
   127
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   128
class UserRQLBoxTemplate(RQLBoxTemplate):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   129
    """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
   130
    request's user
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   131
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   132
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   133
    def to_display_rql(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   134
        assert self.rql is not None, self.id
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   135
        return (self.rql, {'x': self.req.user.eid}, 'x')
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
   136
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   137
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   138
class EntityBoxTemplate(BoxTemplate):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   139
    """base class for boxes related to a single entity"""
809
31962f99770b fix box selectors
sylvain.thenault@logilab.fr
parents: 782
diff changeset
   140
    __select__ = BoxTemplate.__select__ & one_line_rset() & primary_view()
773
eb846103be71 add rtype compat
sylvain.thenault@logilab.fr
parents: 742
diff changeset
   141
    registered = accepts_compat(has_relation_compat(condition_compat(BoxTemplate.registered)))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   142
    context = 'incontext'
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
   143
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   144
    def call(self, row=0, col=0, **kwargs):
526
sylvain.thenault@logilab.fr
parents: 455
diff changeset
   145
        """classes inheriting from EntityBoxTemplate should define cell_call"""
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   146
        self.cell_call(row, col, **kwargs)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   147
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   148
250
7fd7a0d387d7 new RelatedEntityBoxTemplate base class
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 237
diff changeset
   149
class RelatedEntityBoxTemplate(EntityBoxTemplate):
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 816
diff changeset
   150
    __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
   151
250
7fd7a0d387d7 new RelatedEntityBoxTemplate base class
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 237
diff changeset
   152
    def cell_call(self, row, col, **kwargs):
7fd7a0d387d7 new RelatedEntityBoxTemplate base class
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 237
diff changeset
   153
        entity = self.entity(row, col)
7fd7a0d387d7 new RelatedEntityBoxTemplate base class
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 237
diff changeset
   154
        limit = self.req.property_value('navigation.related-limit') + 1
7fd7a0d387d7 new RelatedEntityBoxTemplate base class
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 237
diff changeset
   155
        role = get_role(self)
1885
c2011d238e98 replace sideRelated with sideBox
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 1696
diff changeset
   156
        self.w(u'<div class="sideBox">')
250
7fd7a0d387d7 new RelatedEntityBoxTemplate base class
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 237
diff changeset
   157
        self.wview('sidebox', entity.related(self.rtype, role, limit=limit),
7fd7a0d387d7 new RelatedEntityBoxTemplate base class
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 237
diff changeset
   158
                   title=display_name(self.req, self.rtype, role))
7fd7a0d387d7 new RelatedEntityBoxTemplate base class
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 237
diff changeset
   159
        self.w(u'</div>')
7fd7a0d387d7 new RelatedEntityBoxTemplate base class
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 237
diff changeset
   160
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   161
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   162
class EditRelationBoxTemplate(ReloadableMixIn, EntityBoxTemplate):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   163
    """base class for boxes which let add or remove entities linked
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   164
    by a given relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   165
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   166
    subclasses should define at least id, rtype and target
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   167
    class attributes.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   168
    """
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
   169
1624
baf484a182cd should take arbitrary arguments
sylvain.thenault@logilab.fr
parents: 1493
diff changeset
   170
    def cell_call(self, row, col, view=None, **kwargs):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   171
        self.req.add_js('cubicweb.ajax.js')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   172
        entity = self.entity(row, col)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   173
        box = SideBoxWidget(display_name(self.req, self.rtype), self.id)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   174
        count = self.w_related(box, entity)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   175
        if count:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   176
            box.append(BoxSeparator())
1696
ee0bea49e0e1 fix implementation to avoid separator with nothing following
sylvain.thenault@logilab.fr
parents: 1695
diff changeset
   177
        if not self.w_unrelated(box, entity):
ee0bea49e0e1 fix implementation to avoid separator with nothing following
sylvain.thenault@logilab.fr
parents: 1695
diff changeset
   178
            del box.items[-1] # remove useless separator
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   179
        box.render(self.w)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   180
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   181
    def div_id(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   182
        return self.id
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
   183
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   184
    def box_item(self, entity, etarget, rql, label):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   185
        """builds HTML link to edit relation between `entity` and `etarget`
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   186
        """
1149
1e19b6ef53a1 pylint cleanup
sylvain.thenault@logilab.fr
parents: 838
diff changeset
   187
        role, target = get_role(self), get_target(self)
1e19b6ef53a1 pylint cleanup
sylvain.thenault@logilab.fr
parents: 838
diff changeset
   188
        args = {role[0] : entity.eid, target[0] : etarget.eid}
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   189
        url = self.user_rql_callback((rql, args))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   190
        # for each target, provide a link to edit the relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   191
        label = u'[<a href="%s">%s</a>] %s' % (url, label,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   192
                                               etarget.view('incontext'))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   193
        return RawBoxItem(label, liclass=u'invisible')
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
   194
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   195
    def w_related(self, box, entity):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   196
        """appends existing relations to the `box`"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   197
        rql = 'DELETE S %s O WHERE S eid %%(s)s, O eid %%(o)s' % self.rtype
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   198
        related = self.related_entities(entity)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   199
        for etarget in related:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   200
            box.append(self.box_item(entity, etarget, rql, u'-'))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   201
        return len(related)
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
   202
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   203
    def w_unrelated(self, box, entity):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   204
        """appends unrelated entities to the `box`"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   205
        rql = 'SET S %s O WHERE S eid %%(s)s, O eid %%(o)s' % self.rtype
1696
ee0bea49e0e1 fix implementation to avoid separator with nothing following
sylvain.thenault@logilab.fr
parents: 1695
diff changeset
   206
        i = 0
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   207
        for etarget in self.unrelated_entities(entity):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   208
            box.append(self.box_item(entity, etarget, rql, u'+'))
1696
ee0bea49e0e1 fix implementation to avoid separator with nothing following
sylvain.thenault@logilab.fr
parents: 1695
diff changeset
   209
            i += 1
ee0bea49e0e1 fix implementation to avoid separator with nothing following
sylvain.thenault@logilab.fr
parents: 1695
diff changeset
   210
        return i
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   211
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   212
    def unrelated_entities(self, entity):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   213
        """returns the list of unrelated entities
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   214
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   215
        if etype is not defined on the Box's class, the default
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   216
        behaviour is to use the entity's appropraite vocabulary function
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   217
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   218
        # use entity.unrelated if we've been asked for a particular etype
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   219
        if hasattr(self, 'etype'):
1149
1e19b6ef53a1 pylint cleanup
sylvain.thenault@logilab.fr
parents: 838
diff changeset
   220
            return entity.unrelated(self.rtype, self.etype, get_role(self)).entities()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   221
        # in other cases, use vocabulary functions
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   222
        entities = []
1695
9a9822f3cb6c update implementation to get vocab from form instead of entity
sylvain.thenault@logilab.fr
parents: 1624
diff changeset
   223
        form = self.vreg.select_object('forms', 'edition', self.req, self.rset,
9a9822f3cb6c update implementation to get vocab from form instead of entity
sylvain.thenault@logilab.fr
parents: 1624
diff changeset
   224
                                       row=self.row or 0)
9a9822f3cb6c update implementation to get vocab from form instead of entity
sylvain.thenault@logilab.fr
parents: 1624
diff changeset
   225
        field = form.field_by_name(self.rtype, get_role(self), entity.e_schema)
9a9822f3cb6c update implementation to get vocab from form instead of entity
sylvain.thenault@logilab.fr
parents: 1624
diff changeset
   226
        for _, eid in form.form_field_vocabulary(field):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   227
            if eid is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   228
                rset = self.req.eid_rset(eid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   229
                entities.append(rset.get_entity(0, 0))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   230
        return entities
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
   231
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   232
    def related_entities(self, entity):
1149
1e19b6ef53a1 pylint cleanup
sylvain.thenault@logilab.fr
parents: 838
diff changeset
   233
        return entity.related(self.rtype, get_role(self), entities=True)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   234