web/box.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Wed, 25 Aug 2010 10:01:11 +0200
changeset 6140 65a619eb31c4
parent 6017 5f6a60ea8544
child 6141 b8287e54b528
permissions -rw-r--r--
[boxes] introduce new boxes system * separate box content generation from its layout * refactor css classes to allow moving boxes and still get consistent ui On the way to contentnavigation/boxes unification (in a later patch) * * * some fixes for the previous (default_new_boxes_system) patch * * * some fixes for the previous (default_new_boxes_system) patch
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4490
diff changeset
     1
# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4490
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: 4490
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: 4490
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: 4490
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: 4490
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: 4490
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: 4490
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: 4490
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: 4490
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: 4490
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: 4490
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: 4490
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: 4490
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: 4490
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: 4490
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
5949
2a273c896a38 [box] provide a new generic base box class to edit relation to simple entities, backported from the 'tag' cube
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5927
diff changeset
    18
"""abstract box classes for CubicWeb web client"""
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    20
__docformat__ = "restructuredtext en"
2159
0ca23d0eace2 move up
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    21
_ = unicode
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    22
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2159
diff changeset
    23
from logilab.mtconverter import xml_escape
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    24
from logilab.common.deprecation import class_deprecated, class_renamed
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    25
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    26
from cubicweb import Unauthorized, role as get_role, target as get_target, tags
2710
40789c3044f3 [web.box] remove deprecation warnings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2381
diff changeset
    27
from cubicweb.schema import display_name
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: 4490
diff changeset
    28
from cubicweb.selectors import (no_cnx, one_line_rset,  primary_view,
5949
2a273c896a38 [box] provide a new generic base box class to edit relation to simple entities, backported from the 'tag' cube
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5927
diff changeset
    29
                                match_context_prop, partial_relation_possible,
2a273c896a38 [box] provide a new generic base box class to edit relation to simple entities, backported from the 'tag' cube
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5927
diff changeset
    30
                                partial_has_related_entities)
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    31
from cubicweb.appobject import AppObject
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    32
from cubicweb.view import View, ReloadableMixIn, Component
5949
2a273c896a38 [box] provide a new generic base box class to edit relation to simple entities, backported from the 'tag' cube
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5927
diff changeset
    33
from cubicweb.uilib import domid, js
2a273c896a38 [box] provide a new generic base box class to edit relation to simple entities, backported from the 'tag' cube
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5927
diff changeset
    34
from cubicweb.web import INTERNAL_FIELD_VALUE, stdmsgs
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    35
from cubicweb.web.htmlwidgets import (BoxLink, BoxWidget, SideBoxWidget,
250
7fd7a0d387d7 new RelatedEntityBoxTemplate base class
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 237
diff changeset
    36
                                      RawBoxItem, BoxSeparator)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    37
from cubicweb.web.action import UnregisteredAction
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    38
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    39
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    40
def sort_by_category(actions, categories_in_order=None):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    41
    """return a list of (category, actions_sorted_by_title)"""
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    42
    result = []
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    43
    actions_by_cat = {}
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    44
    for action in actions:
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    45
        actions_by_cat.setdefault(action.category, []).append(
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    46
            (action.title, action) )
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    47
    for key, values in actions_by_cat.items():
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    48
        actions_by_cat[key] = [act for title, act in sorted(values)]
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    49
    if categories_in_order:
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    50
        for cat in categories_in_order:
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    51
            if cat in actions_by_cat:
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    52
                result.append( (cat, actions_by_cat[cat]) )
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    53
    for item in sorted(actions_by_cat.items()):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    54
        result.append(item)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    55
    return result
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    56
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
    57
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    58
class EditRelationMixIn(ReloadableMixIn):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    59
    def box_item(self, entity, etarget, rql, label):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    60
        """builds HTML link to edit relation between `entity` and `etarget`"""
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    61
        role, target = get_role(self), get_target(self)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    62
        args = {role[0] : entity.eid, target[0] : etarget.eid}
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    63
        url = self._cw.user_rql_callback((rql, args))
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    64
        # for each target, provide a link to edit the relation
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    65
        return u'[<a href="%s">%s</a>] %s' % (xml_escape(url), label,
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    66
                                              etarget.view('incontext'))
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    67
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    68
    def related_boxitems(self, entity):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    69
        rql = 'DELETE S %s O WHERE S eid %%(s)s, O eid %%(o)s' % self.rtype
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    70
        return [self.box_item(entity, etarget, rql, u'-')
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    71
                for etarget in self.related_entities(entity)]
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    72
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    73
    def related_entities(self, entity):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    74
        return entity.related(self.rtype, get_role(self), entities=True)
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
    75
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    76
    def unrelated_boxitems(self, entity):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    77
        rql = 'SET S %s O WHERE S eid %%(s)s, O eid %%(o)s' % self.rtype
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    78
        return [self.box_item(entity, etarget, rql, u'+')
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    79
                for etarget in self.unrelated_entities(entity)]
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
    80
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    81
    def unrelated_entities(self, entity):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    82
        """returns the list of unrelated entities, using the entity's
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    83
        appropriate vocabulary function
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    84
        """
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    85
        skip = set(unicode(e.eid) for e in entity.related(self.rtype, get_role(self),
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    86
                                                          entities=True))
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    87
        skip.add(None)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    88
        skip.add(INTERNAL_FIELD_VALUE)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    89
        filteretype = getattr(self, 'etype', None)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    90
        entities = []
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    91
        form = self._cw.vreg['forms'].select('edition', self._cw,
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    92
                                             rset=self.cw_rset,
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    93
                                             row=self.cw_row or 0)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    94
        field = form.field_by_name(self.rtype, get_role(self), entity.e_schema)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    95
        for _, eid in field.vocabulary(form):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    96
            if eid not in skip:
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    97
                entity = self._cw.entity_from_eid(eid)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    98
                if filteretype is None or entity.__regid__ == filteretype:
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
    99
                    entities.append(entity)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   100
        return entities
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   101
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   102
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   103
# generic classes for the new box system #######################################
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   104
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   105
from cubicweb.selectors import match_context, contextual
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   106
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   107
class EmptyComponent(Exception):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   108
    """some selectable component has actually no content and should not be
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   109
    rendered
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   110
    """
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   111
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   112
class Layout(Component):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   113
    __regid__ = 'layout'
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   114
    __abstract__ = True
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   115
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   116
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   117
class Box(AppObject): # XXX ContextComponent
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   118
    __registry__ = 'boxes'
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: 4490
diff changeset
   119
    __select__ = ~no_cnx() & match_context_prop()
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
   120
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   121
    categories_in_order = ()
2799
b703639614e7 refactor property handling to avoid name conflicts
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2789
diff changeset
   122
    cw_property_defs = {
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   123
        _('visible'): dict(type='Boolean', default=True,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   124
                           help=_('display the box or not')),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   125
        _('order'):   dict(type='Int', default=99,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   126
                           help=_('display order of the box')),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   127
        # XXX 'incontext' boxes are handled by the default primary view
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   128
        _('context'): dict(type='String', default='left',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   129
                           vocabulary=(_('left'), _('incontext'), _('right')),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   130
                           help=_('context where this box should be displayed')),
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
    context = 'left'
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   133
    contextual = False
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   134
    title = None
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   135
    # XXX support kwargs for compat with old boxes which gets the view as
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   136
    # argument
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   137
    def render(self, w, **kwargs):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   138
        getlayout = self._cw.vreg['components'].select
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   139
        try:
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   140
            # XXX ensure context is given when the component is reloaded through
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   141
            # ajax
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   142
            context = self.cw_extra_kwargs['context']
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   143
        except KeyError:
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   144
            context = self.cw_propval('context')
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   145
        layout = getlayout('layout', self._cw, rset=self.cw_rset,
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   146
                           row=self.cw_row, col=self.cw_col,
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   147
                           view=self, context=context)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   148
        layout.render(w)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   149
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   150
    def init_rendering(self):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   151
        """init rendering callback: that's the good time to check your component
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   152
        has some content to display. If not, you can still raise
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   153
        :exc:`EmptyComponent` to inform it should be skipped.
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   154
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   155
        Also, :exc:`Unauthorized` will be catched, logged, then the component
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   156
        will be skipped.
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   157
        """
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   158
        self.items = []
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   159
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   160
    @property
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   161
    def domid(self):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   162
        """return the HTML DOM identifier for this component"""
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   163
        return domid(self.__regid__)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   164
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   165
    @property
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   166
    def cssclass(self):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   167
        """return the CSS class name for this component"""
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   168
        return domid(self.__regid__)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   169
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   170
    def render_title(self, w):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   171
        """return the title for this component"""
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   172
        if self.title is None:
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   173
            raise NotImplementedError()
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   174
        w(self._cw._(self.title))
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   175
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   176
    def render_body(self, w):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   177
        """return the body (content) for this component"""
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   178
        raise NotImplementedError()
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   179
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   180
    def render_items(self, w, items=None, klass=u'boxListing'):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   181
        if items is None:
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   182
            items = self.items
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   183
        assert items
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   184
        w(u'<ul class="%s">' % klass)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   185
        for item in items:
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   186
            if hasattr(item, 'render'):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   187
                item.render(w) # XXX display <li> by itself
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   188
            else:
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   189
                w(u'<li>')
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   190
                w(item)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   191
                w(u'</li>')
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   192
        w(u'</ul>')
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   193
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   194
    def append(self, item):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   195
        self.items.append(item)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   196
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   197
    def box_action(self, action): # XXX action_link
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   198
        return self.build_link(self._cw._(action.title), action.url())
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   199
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   200
    def build_link(self, title, url, **kwargs):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   201
        if self._cw.selected(url):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   202
            try:
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   203
                kwargs['klass'] += ' selected'
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   204
            except KeyError:
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   205
                kwargs['klass'] = 'selected'
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   206
        return tags.a(title, href=url, **kwargs)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   207
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   208
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   209
class EntityBox(Box): # XXX ContextEntityComponent
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   210
    """base class for boxes related to a single entity"""
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   211
    __select__ = Box.__select__ & one_line_rset()
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   212
    context = 'incontext'
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   213
    contextual = True
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   214
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   215
    def __init__(self, *args, **kwargs):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   216
        super(EntityBox, self).__init__(*args, **kwargs)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   217
        try:
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   218
            entity = kwargs['entity']
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   219
        except KeyError:
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   220
            entity = self.cw_rset.get_entity(self.cw_row or 0, self.cw_col or 0)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   221
        self.entity = entity
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   222
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   223
    @property
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   224
    def domid(self):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   225
        return domid(self.__regid__) + unicode(self.entity.eid)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   226
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   227
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   228
# high level abstract box classes ##############################################
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   229
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   230
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   231
class RQLBox(Box):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   232
    """abstract box for boxes displaying the content of a rql query not
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   233
    related to the current result set.
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   234
    """
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   235
    rql  = None
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   236
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   237
    def to_display_rql(self):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   238
        assert self.rql is not None, self.__regid__
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   239
        return (self.rql,)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   240
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   241
    def init_rendering(self):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   242
        rset = self._cw.execute(*self.to_display_rql())
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   243
        if not rset:
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   244
            raise EmptyComponent()
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   245
        if len(rset[0]) == 2:
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   246
            self.items = []
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   247
            for i, (eid, label) in enumerate(rset):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   248
                entity = rset.get_entity(i, 0)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   249
                self.items.append(self.build_link(label, entity.absolute_url()))
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   250
        else:
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   251
            self.items = [self.build_link(e.dc_title(), e.absolute_url())
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   252
                          for e in rset.entities()]
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   253
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   254
    def render_body(self, w):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   255
        self.render_items(w)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   256
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   257
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   258
class EditRelationBox(EditRelationMixIn, EntityBox):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   259
    """base class for boxes which let add or remove entities linked by a given
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   260
    relation
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   261
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   262
    subclasses should define at least id, rtype and target class attributes.
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   263
    """
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   264
    def render_title(self, w):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   265
        return display_name(self._cw, self.rtype, get_role(self),
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   266
                            context=self.entity.__regid__)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   267
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   268
    def render_body(self, w):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   269
        self._cw.add_js('cubicweb.ajax.js')
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   270
        related = self.related_boxitems(self.entity)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   271
        unrelated = self.unrelated_boxitems(self.entity)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   272
        self.items.extend(related)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   273
        if related and unrelated:
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   274
            self.items.append(BoxSeparator())
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   275
        self.items.extend(unrelated)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   276
        self.render_items(w)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   277
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   278
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   279
class AjaxEditRelationBox(EntityBox):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   280
    __select__ = EntityBox.__select__ & (
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   281
        partial_relation_possible(action='add') | partial_has_related_entities())
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   282
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   283
    # view used to display related entties
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   284
    item_vid = 'incontext'
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   285
    # values separator when multiple values are allowed
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   286
    separator = ','
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   287
    # msgid of the message to display when some new relation has been added/removed
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   288
    added_msg = None
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   289
    removed_msg = None
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   290
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   291
    # class attributes below *must* be set in concret classes (additionaly to
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   292
    # rtype / role [/ target_etype]. They should correspond to js_* methods on
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   293
    # the json controller
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   294
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   295
    # function(eid)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   296
    # -> expected to return a list of values to display as input selector
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   297
    #    vocabulary
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   298
    fname_vocabulary = None
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   299
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   300
    # function(eid, value)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   301
    # -> handle the selector's input (eg create necessary entities and/or
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   302
    # relations). If the relation is multiple, you'll get a list of value, else
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   303
    # a single string value.
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   304
    fname_validate = None
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   305
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   306
    # function(eid, linked entity eid)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   307
    # -> remove the relation
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   308
    fname_remove = None
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   309
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   310
    def __init__(self, *args, **kwargs):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   311
        super(AjaxEditRelationBox, self).__init__(*args, **kwargs)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   312
        self.rdef = self.entity.e_schema.rdef(self.rtype, self.role, self.target_etype)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   313
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   314
    def render_title(self, w):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   315
        w(self.rdef.rtype.display_name(self._cw, self.role,
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   316
                                       context=self.entity.__regid__))
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   317
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   318
    def render_body(self, w):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   319
        req = self._cw
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   320
        entity = self.entity
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   321
        related = entity.related(self.rtype, self.role)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   322
        if self.role == 'subject':
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   323
            mayadd = self.rdef.has_perm(req, 'add', fromeid=entity.eid)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   324
            maydel = self.rdef.has_perm(req, 'delete', fromeid=entity.eid)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   325
        else:
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   326
            mayadd = self.rdef.has_perm(req, 'add', toeid=entity.eid)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   327
            maydel = self.rdef.has_perm(req, 'delete', toeid=entity.eid)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   328
        if mayadd or maydel:
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   329
            req.add_js(('cubicweb.ajax.js', 'cubicweb.ajax.box.js'))
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   330
        _ = req._
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   331
        if related:
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   332
            w(u'<table>')
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   333
            for rentity in related.entities():
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   334
                # for each related entity, provide a link to remove the relation
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   335
                subview = rentity.view(self.item_vid)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   336
                if maydel:
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   337
                    jscall = unicode(js.ajaxBoxRemoveLinkedEntity(
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   338
                        self.__regid__, entity.eid, rentity.eid,
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   339
                        self.fname_remove,
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   340
                        self.removed_msg and _(self.removed_msg)))
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   341
                    w(u'<tr><td>[<a href="javascript: %s">-</a>]</td>'
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   342
                      '<td class="tagged"> %s</td></tr>' % (xml_escape(jscall),
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   343
                                                            subview))
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   344
                else:
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   345
                    w(u'<tr><td class="tagged">%s</td></tr>' % (subview))
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   346
            w(u'</table>')
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   347
        else:
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   348
            w(_('no related entity'))
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   349
        if mayadd:
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   350
            req.add_js('jquery.autocomplete.js')
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   351
            req.add_css('jquery.autocomplete.css')
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   352
            multiple = self.rdef.role_cardinality(self.role) in '*+'
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   353
            w(u'<table><tr><td>')
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   354
            jscall = unicode(js.ajaxBoxShowSelector(
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   355
                self.__regid__, entity.eid, self.fname_vocabulary,
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   356
                self.fname_validate, self.added_msg and _(self.added_msg),
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   357
                _(stdmsgs.BUTTON_OK[0]), _(stdmsgs.BUTTON_CANCEL[0]),
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   358
                multiple and self.separator))
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   359
            w('<a class="button sglink" href="javascript: %s">%s</a>' % (
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   360
                xml_escape(jscall),
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   361
                multiple and _('add_relation') or _('update_relation')))
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   362
            w(u'</td><td>')
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   363
            w(u'<div id="%sHolder"></div>' % self.domid)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   364
            w(u'</td></tr></table>')
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   365
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   366
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   367
# old box system, deprecated ###################################################
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   368
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   369
class BoxTemplate(View):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   370
    """base template for boxes, usually a (contextual) list of possible
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   371
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   372
    actions. Various classes attributes may be used to control the box
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   373
    rendering.
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   374
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   375
    You may override on of the formatting callbacks is this is not necessary
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   376
    for your custom box.
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   377
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   378
    Classes inheriting from this class usually only have to override call
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   379
    to fetch desired actions, and then to do something like  ::
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   380
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   381
        box.render(self.w)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   382
    """
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   383
    __metaclass__ = class_deprecated
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   384
    __deprecation_warning__ = '*BoxTemplate classes are deprecated, use *Box instead'
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   385
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   386
    __registry__ = 'boxes'
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   387
    __select__ = ~no_cnx() & match_context_prop()
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   388
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   389
    categories_in_order = ()
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   390
    cw_property_defs = {
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   391
        _('visible'): dict(type='Boolean', default=True,
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   392
                           help=_('display the box or not')),
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   393
        _('order'):   dict(type='Int', default=99,
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   394
                           help=_('display order of the box')),
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   395
        # XXX 'incontext' boxes are handled by the default primary view
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   396
        _('context'): dict(type='String', default='left',
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   397
                           vocabulary=(_('left'), _('incontext'), _('right')),
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   398
                           help=_('context where this box should be displayed')),
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   399
        }
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   400
    context = 'left'
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   401
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   402
    def sort_actions(self, actions):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   403
        """return a list of (category, actions_sorted_by_title)"""
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   404
        return sort_by_category(actions, self.categories_in_order)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   405
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   406
    def mk_action(self, title, url, escape=True, **kwargs):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   407
        """factory function to create dummy actions compatible with the
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   408
        .format_actions method
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   409
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   410
        if escape:
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2159
diff changeset
   411
            title = xml_escape(title)
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   412
        return self.box_action(self._action(title, url, **kwargs))
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
   413
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   414
    def _action(self, title, url, **kwargs):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   415
        return UnregisteredAction(self._cw, title, url, **kwargs)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   416
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   417
    # formating callbacks
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   418
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   419
    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
   420
        if action.__regid__:
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3230
diff changeset
   421
            return u'keyword: %s' % action.__regid__
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   422
        return u''
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   423
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   424
    def box_action(self, action):
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   425
        klass = getattr(action, 'html_class', lambda: None)()
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3230
diff changeset
   426
        return BoxLink(action.url(), self._cw._(action.title),
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   427
                       klass, self.boxitem_link_tooltip(action))
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
   428
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   429
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   430
class RQLBoxTemplate(BoxTemplate):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   431
    """abstract box for boxes displaying the content of a rql query not
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   432
    related to the current result set.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   433
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   434
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   435
    rql  = None
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
   436
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   437
    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
   438
        assert self.rql is not None, self.__regid__
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   439
        return (self.rql,)
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
   440
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   441
    def call(self, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   442
        try:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3230
diff changeset
   443
            rset = self._cw.execute(*self.to_display_rql())
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   444
        except Unauthorized:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   445
            # can't access to something in the query, forget this box
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   446
            return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   447
        if len(rset) == 0:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   448
            return
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3230
diff changeset
   449
        box = BoxWidget(self._cw._(self.title), self.__regid__)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   450
        for i, (teid, tname) in enumerate(rset):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   451
            entity = rset.get_entity(i, 0)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   452
            box.append(self.mk_action(tname, entity.absolute_url()))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   453
        box.render(w=self.w)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   454
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
   455
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   456
class UserRQLBoxTemplate(RQLBoxTemplate):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   457
    """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
   458
    request's user
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   459
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   460
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   461
    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
   462
        assert self.rql is not None, self.__regid__
5979
561b6c2eb288 [web] eid key is deprecated
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 5952
diff changeset
   463
        return (self.rql, {'x': self._cw.user.eid})
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
   464
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   465
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   466
class EntityBoxTemplate(BoxTemplate):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   467
    """base class for boxes related to a single entity"""
809
31962f99770b fix box selectors
sylvain.thenault@logilab.fr
parents: 782
diff changeset
   468
    __select__ = BoxTemplate.__select__ & one_line_rset() & primary_view()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   469
    context = 'incontext'
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
   470
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   471
    def call(self, row=0, col=0, **kwargs):
526
sylvain.thenault@logilab.fr
parents: 455
diff changeset
   472
        """classes inheriting from EntityBoxTemplate should define cell_call"""
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   473
        self.cell_call(row, col, **kwargs)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   474
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   475
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   476
class EditRelationBoxTemplate(EditRelationMixIn, EntityBoxTemplate):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   477
    """base class for boxes which let add or remove entities linked
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   478
    by a given relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   479
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   480
    subclasses should define at least id, rtype and target
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   481
    class attributes.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   482
    """
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
   483
1624
baf484a182cd should take arbitrary arguments
sylvain.thenault@logilab.fr
parents: 1493
diff changeset
   484
    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
   485
        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
   486
        entity = self.cw_rset.get_entity(row, col)
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   487
        title = display_name(self._cw, self.rtype, get_role(self),
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   488
                             context=entity.__regid__)
6017
5f6a60ea8544 [relations in ui] provide context information when computing label for a relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5979
diff changeset
   489
        box = SideBoxWidget(title, 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
   490
        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
   491
        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
   492
        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
   493
        if related and unrelated:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   494
            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
   495
        box.extend(unrelated)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   496
        box.render(self.w)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   497
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   498
    def box_item(self, entity, etarget, rql, label):
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   499
        label = super(EditRelationBoxTemplate, self).box_item(
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   500
            entity, etarget, rql, label)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   501
        return RawBoxItem(label, liclass=u'invisible')
1493
8270580b65a0 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1422
diff changeset
   502
5949
2a273c896a38 [box] provide a new generic base box class to edit relation to simple entities, backported from the 'tag' cube
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5927
diff changeset
   503
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   504
AjaxEditRelationBoxTemplate = class_renamed(
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   505
    'AjaxEditRelationBoxTemplate', AjaxEditRelationBox,
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   506
    '[3.10] AjaxEditRelationBoxTemplate has been renamed to AjaxEditRelationBox')
5949
2a273c896a38 [box] provide a new generic base box class to edit relation to simple entities, backported from the 'tag' cube
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5927
diff changeset
   507