web/facet.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Mon, 04 Jul 2011 16:46:29 +0200
changeset 7615 e5ad51352eb3
parent 7609 fbefd1b9e587
child 7618 5395007c415c
permissions -rw-r--r--
[facet] fix argument inversion in date range facet
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7402
826e5663a686 [facets/table] vertically group facets by two when possible in order to have a more compact horizontal layout in table filter form
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7280
diff changeset
     1
# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5225
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: 5225
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: 5225
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: 5225
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: 5225
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: 5225
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: 5225
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: 5225
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: 5225
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: 5225
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: 5225
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: 5225
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: 5225
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: 5225
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: 5225
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    18
"""
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    19
The :mod:`cubicweb.web.facet` module contains a set of abstract classes to use
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    20
as bases to build your own facets
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    21
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    22
All facet classes inherits from the :class:`AbstractFacet` class, though you'll
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    23
usually find some more handy class that do what you want.
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    24
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    25
Let's see available classes.
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    26
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    27
Classes you'll want to use
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    28
--------------------------
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    29
.. autoclass:: cubicweb.web.facet.RelationFacet
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    30
.. autoclass:: cubicweb.web.facet.RelationAttributeFacet
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    31
.. autoclass:: cubicweb.web.facet.HasRelationFacet
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    32
.. autoclass:: cubicweb.web.facet.AttributeFacet
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    33
.. autoclass:: cubicweb.web.facet.RangeFacet
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    34
.. autoclass:: cubicweb.web.facet.DateRangeFacet
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    35
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    36
Classes for facets implementor
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    37
------------------------------
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    38
Unless you didn't find the class that does the job you want above, you may want
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    39
to skip those classes...
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    40
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    41
.. autoclass:: cubicweb.web.facet.AbstractFacet
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    42
.. autoclass:: cubicweb.web.facet.VocabularyFacet
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    43
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
    44
.. comment: XXX widgets
5768
1e73a466aa69 [fti] support for fti ranking: has_text query results sorted by relevance, and provides a way to control weight per entity / entity's attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5618
diff changeset
    45
"""
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    46
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    47
__docformat__ = "restructuredtext en"
6582
8eb7883b4223 [pylint] fix a bug of pylint detected errors and i18n pb (calling builtins._ instead of req._)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6380
diff changeset
    48
_ = unicode
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    49
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    50
from copy import deepcopy
2152
Florent <florent@secondweb.fr>
parents: 2149
diff changeset
    51
from datetime import date, datetime, timedelta
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    52
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2305
diff changeset
    53
from logilab.mtconverter import xml_escape
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    54
from logilab.common.graph import has_path
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    55
from logilab.common.decorators import cached
7117
44775b275d45 [facets] closes #1569459 (date-range facet with year < 1900)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7070
diff changeset
    56
from logilab.common.date import datetime2ticks, ustrftime, ticks2datetime
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    57
from logilab.common.compat import all
7600
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
    58
from logilab.common.deprecation import deprecated
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    59
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
    60
from rql import parse, nodes, utils
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    61
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    62
from cubicweb import Unauthorized, typed_eid
2305
8f6dbe884700 import display_name
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2152
diff changeset
    63
from cubicweb.schema import display_name
4466
8b0ca7904820 moved generic datetime manipulation function to lgc
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4333
diff changeset
    64
from cubicweb.utils import make_uid
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 782
diff changeset
    65
from cubicweb.selectors import match_context_prop, partial_relation_possible
2656
a93ae0f6c0ad R [base classes] only AppObject remaning, no more AppRsetObject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
    66
from cubicweb.appobject import AppObject
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    67
from cubicweb.web.htmlwidgets import HTMLWidget
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    68
6336
ae80aed607f2 [facet] use contextified label when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6251
diff changeset
    69
ae80aed607f2 [facet] use contextified label when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6251
diff changeset
    70
def rtype_facet_title(facet):
ae80aed607f2 [facet] use contextified label when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6251
diff changeset
    71
    ptypes = facet.cw_rset.column_types(0)
ae80aed607f2 [facet] use contextified label when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6251
diff changeset
    72
    if len(ptypes) == 1:
ae80aed607f2 [facet] use contextified label when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6251
diff changeset
    73
        return display_name(facet._cw, facet.rtype, form=facet.role,
ae80aed607f2 [facet] use contextified label when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6251
diff changeset
    74
                            context=iter(ptypes).next())
ae80aed607f2 [facet] use contextified label when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6251
diff changeset
    75
    return display_name(facet._cw, facet.rtype, form=facet.role)
ae80aed607f2 [facet] use contextified label when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6251
diff changeset
    76
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
    77
def get_facet(req, facetid, select, filtered_variable):
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
    78
    return req.vreg['facets'].object_by_id(facetid, req, select=select,
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
    79
                                           filtered_variable=filtered_variable)
7600
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
    80
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
    81
@deprecated('[3.13] filter_hiddens moved to cubicweb.web.views.facets with '
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
    82
            'slightly modified prototype')
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
    83
def filter_hiddens(w, **kwargs):
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
    84
    from cubicweb.web.views.facets import filter_hiddens
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
    85
    return filter_hiddens(w, wdgs=kwargs.pop('facets'))
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
    86
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
    87
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    88
## rqlst manipulation functions used by facets ################################
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    89
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
    90
def init_facets(rset, select, mainvar=None):
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
    91
    rset.req.vreg.rqlhelper.annotate(select)
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
    92
    filtered_variable = get_filtered_variable(select, mainvar)
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
    93
    baserql = select.as_string(kwargs=rset.args) # before call to prepare_select
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
    94
    prepare_select(select, filtered_variable)
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
    95
    return filtered_variable, baserql
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
    96
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
    97
def get_filtered_variable(select, mainvar=None):
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
    98
    """drop any limit/offset from select (in-place modification) and return the
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
    99
    variable whose name is `mainvar` or the first variable selected in column 0
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   100
    """
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   101
    select.set_limit(None)
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   102
    select.set_offset(None)
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   103
    if mainvar is None:
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   104
        vref = select.selection[0].iget_nodes(nodes.VariableRef).next()
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   105
        return vref.variable
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   106
    return select.defined_vars[mainvar]
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   107
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   108
def prepare_select(select, filtered_variable):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   109
    """prepare a syntax tree to generate facet filters
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   110
7601
9030e8a4481e [facets] should remove groupby from base rqlst. Closes #1796196
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7280
diff changeset
   111
    * remove ORDERBY/GROUPBY clauses
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   112
    * cleanup selection (remove everything)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   113
    * undefine unnecessary variables
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   114
    * set DISTINCT
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   115
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   116
    Notice unset of LIMIT/OFFSET us expected to be done by a previous call to
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   117
    :func:`get_filtered_variable`.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   118
    """
7601
9030e8a4481e [facets] should remove groupby from base rqlst. Closes #1796196
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7280
diff changeset
   119
    # cleanup sort terms / group by
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   120
    select.remove_sort_terms()
7601
9030e8a4481e [facets] should remove groupby from base rqlst. Closes #1796196
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7280
diff changeset
   121
    select.remove_groups()
9030e8a4481e [facets] should remove groupby from base rqlst. Closes #1796196
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7280
diff changeset
   122
    # XXX remove aggregat from having
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   123
    # selection: only vocabulary entity
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   124
    for term in select.selection[:]:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   125
        select.remove_selected(term)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   126
    # remove unbound variables which only have some type restriction
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   127
    for dvar in select.defined_vars.values():
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   128
        if not (dvar is filtered_variable or dvar.stinfo['relations']):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   129
            select.undefine_variable(dvar)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   130
    # global tree config: DISTINCT, LIMIT, OFFSET
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   131
    select.set_distinct(True)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   132
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   133
@deprecated('[3.13] use init_facets instead')
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   134
def prepare_facets_rqlst(rqlst, args=None):
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   135
    assert len(rqlst.children) == 1, 'FIXME: union not yet supported'
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   136
    select = rqlst.children[0]
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   137
    filtered_variable = get_filtered_variable(select)
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   138
    baserql = select.as_string(args)
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   139
    prepare_select(select, filtered_variable)
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   140
    return filtered_variable, baserql
7600
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   141
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   142
def prepare_vocabulary_select(select, filtered_variable, rtype, role,
7600
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   143
                              select_target_entity=True):
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   144
    """prepare a syntax tree to generate a filter vocabulary rql using the given
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   145
    relation:
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   146
    * create a variable to filter on this relation
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   147
    * add the relation
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   148
    * add the new variable to GROUPBY clause if necessary
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   149
    * add the new variable to the selection
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   150
    """
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   151
    newvar = _add_rtype_relation(select, filtered_variable, rtype, role)[0]
7600
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   152
    if select_target_entity:
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   153
        if select.groupby:
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   154
            select.add_group_var(newvar)
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   155
        select.add_selected(newvar)
7600
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   156
    # add is restriction if necessary
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   157
    if filtered_variable.stinfo['typerel'] is None:
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   158
        etypes = frozenset(sol[filtered_variable.name] for sol in select.solutions)
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   159
        select.add_type_restriction(filtered_variable, etypes)
7600
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   160
    return newvar
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
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   163
def insert_attr_select_relation(select, filtered_variable, rtype, role, attrname,
7600
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   164
                                sortfuncname=None, sortasc=True,
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   165
                                select_target_entity=True):
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   166
    """modify a syntax tree to :
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   167
    * link a new variable to `filtered_variable` through `rtype` (where filtered_variable has `role`)
7600
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   168
    * retrieve only the newly inserted variable and its `attrname`
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   169
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   170
    Sorting:
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   171
    * on `attrname` ascendant (`sortasc`=True) or descendant (`sortasc`=False)
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   172
    * on `sortfuncname`(`attrname`) if `sortfuncname` is specified
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   173
    * no sort if `sortasc` is None
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   174
    """
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   175
    cleanup_select(select, filtered_variable)
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   176
    var = prepare_vocabulary_select(select, filtered_variable, rtype, role,
7600
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   177
                                   select_target_entity)
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   178
    attrvar = select.make_variable()
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   179
    select.add_relation(var, attrname, attrvar)
7600
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   180
    # if query is grouped, we have to add the attribute variable
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   181
    #if select.groupby: XXX may not occur anymore
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   182
    #    if not attrvar in select.groupby:
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   183
    #        select.add_group_var(attrvar)
7600
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   184
    if sortasc is not None:
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   185
        _set_orderby(select, attrvar, sortasc, sortfuncname)
7600
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   186
    # add attribute variable to selection
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   187
    select.add_selected(attrvar)
7600
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   188
    return var
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   189
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   190
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   191
def cleanup_select(select, filtered_variable):
7600
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   192
    """cleanup tree from unnecessary restrictions:
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   193
    * attribute selection
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   194
    * optional relations linked to the main variable
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   195
    * mandatory relations linked to the main variable
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   196
    """
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   197
    if select.where is None:
7600
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   198
        return
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   199
    schema = select.root.schema
7600
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   200
    toremove = set()
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   201
    vargraph = deepcopy(select.vargraph) # graph representing links between variable
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   202
    for rel in select.where.get_nodes(nodes.Relation):
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   203
        ovar = _may_be_removed(rel, schema, filtered_variable)
7600
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   204
        if ovar is not None:
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   205
            toremove.add(ovar)
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   206
    removed = set()
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   207
    while toremove:
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   208
        trvar = toremove.pop()
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   209
        trvarname = trvar.name
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   210
        # remove paths using this variable from the graph
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   211
        linkedvars = vargraph.pop(trvarname)
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   212
        for ovarname in linkedvars:
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   213
            vargraph[ovarname].remove(trvarname)
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   214
        # remove relation using this variable
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   215
        for rel in trvar.stinfo['relations']:
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   216
            if rel in removed:
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   217
                # already removed
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   218
                continue
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   219
            select.remove_node(rel)
7600
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   220
            removed.add(rel)
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   221
        rel = trvar.stinfo['typerel']
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   222
        if rel is not None and not rel in removed:
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   223
            select.remove_node(rel)
7600
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   224
            removed.add(rel)
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   225
        # cleanup groupby clause
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   226
        if select.groupby:
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   227
            for vref in select.groupby[:]:
7600
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   228
                if vref.name == trvarname:
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   229
                    select.remove_group_var(vref)
7600
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   230
        # we can also remove all variables which are linked to this variable
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   231
        # and have no path to the main variable
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   232
        for ovarname in linkedvars:
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   233
            if ovarname == filtered_variable.name:
7600
75d208ab8444 [facets] factorize table filter form / facets box generation, moving out filter form from the table view so it's usable from other views. Closes #1794009
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7414
diff changeset
   234
                continue
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   235
            if not has_path(vargraph, ovarname, filtered_variable.name):
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   236
                toremove.add(select.defined_vars[ovarname])
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   237
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   238
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   239
def _may_be_removed(rel, schema, variable):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   240
    """if the given relation may be removed from the tree, return the variable
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   241
    on the other side of `variable`, else return None
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   242
    Conditions:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   243
    * the relation is an attribute selection of the main variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   244
    * the relation is optional relation linked to the main variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   245
    * the relation is a mandatory relation linked to the main variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   246
      without any restriction on the other variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   247
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   248
    lhs, rhs = rel.get_variable_parts()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   249
    rschema = schema.rschema(rel.r_type)
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   250
    if lhs.variable is variable:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   251
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   252
            ovar = rhs.variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   253
        except AttributeError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   254
            # constant restriction
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   255
            # XXX: X title LOWER(T) if it makes sense?
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   256
            return None
3689
deb13e88e037 follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3333
diff changeset
   257
        if rschema.final:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   258
            if len(ovar.stinfo['relations']) == 1:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   259
                # attribute selection
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   260
                return ovar
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   261
            return None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   262
        opt = 'right'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   263
        cardidx = 0
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   264
    elif getattr(rhs, 'variable', None) is variable:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   265
        ovar = lhs.variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   266
        opt = 'left'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   267
        cardidx = 1
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   268
    else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   269
        # not directly linked to the main variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   270
        return None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   271
    if rel.optional in (opt, 'both'):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   272
        # optional relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   273
        return ovar
4073
03681ba6da0b cw 3.6 api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 3720
diff changeset
   274
    if all(rdef.cardinality[cardidx] in '1+'
03681ba6da0b cw 3.6 api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 3720
diff changeset
   275
           for rdef in rschema.rdefs.values()):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   276
        # mandatory relation without any restriction on the other variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   277
        for orel in ovar.stinfo['relations']:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   278
            if rel is orel:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   279
                continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   280
            if _may_be_removed(orel, schema, ovar) is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   281
                return None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   282
        return ovar
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   283
    return None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   284
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   285
def _make_relation(select, variable, rtype, role):
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   286
    newvar = select.make_variable()
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   287
    if role == 'object':
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   288
        rel = nodes.make_relation(newvar, rtype, (variable,), nodes.VariableRef)
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   289
    else:
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   290
        rel = nodes.make_relation(variable, rtype, (newvar,), nodes.VariableRef)
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   291
    return newvar, rel
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   292
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   293
def _add_rtype_relation(select, variable, rtype, role):
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   294
    """add a relation relying `variable` to entities linked by the `rtype`
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   295
    relation (where `variable` has `role`)
1149
1e19b6ef53a1 pylint cleanup
sylvain.thenault@logilab.fr
parents: 1132
diff changeset
   296
1e19b6ef53a1 pylint cleanup
sylvain.thenault@logilab.fr
parents: 1132
diff changeset
   297
    return the inserted variable for linked entities.
1e19b6ef53a1 pylint cleanup
sylvain.thenault@logilab.fr
parents: 1132
diff changeset
   298
    """
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   299
    newvar, newrel = _make_relation(select, variable, rtype, role)
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   300
    select.add_restriction(newrel)
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   301
    return newvar, newrel
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   302
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   303
def _add_eid_restr(rel, restrvar, value):
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   304
    rrel = nodes.make_constant_restriction(restrvar, 'eid', value, 'Int')
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   305
    rel.parent.replace(rel, nodes.And(rel, rrel))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   306
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   307
def _remove_relation(select, rel, var):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   308
    """remove a constraint relation from the syntax tree"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   309
    # remove the relation
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   310
    select.remove_node(rel)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   311
    # remove relations where the filtered variable appears on the
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   312
    # lhs and rhs is a constant restriction
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   313
    extra = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   314
    for vrel in var.stinfo['relations']:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   315
        if vrel is rel:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   316
            continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   317
        if vrel.children[0].variable is var:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   318
            if not vrel.children[1].get_nodes(nodes.Constant):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   319
                extra.append(vrel)
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   320
            select.remove_node(vrel)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   321
    return extra
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   322
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   323
def _set_orderby(select, newvar, sortasc, sortfuncname):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   324
    if sortfuncname is None:
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   325
        select.add_sort_var(newvar, sortasc)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   326
    else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   327
        vref = nodes.variable_ref(newvar)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   328
        vref.register_reference()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   329
        sortfunc = nodes.Function(sortfuncname)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   330
        sortfunc.append(vref)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   331
        term = nodes.SortTerm(sortfunc, sortasc)
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   332
        select.add_sort_term(term)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   333
3329
8430f6c693a1 cleanup, smarter sort control to avoid it when not necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3328
diff changeset
   334
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   335
_prepare_vocabulary_rqlst = deprecated('[3.13] renamed prepare_vocabulary_select')(
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   336
    prepare_vocabulary_select)
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   337
_cleanup_rqlst = deprecated('[3.13] renamed to cleanup_select')(cleanup_select)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   338
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   339
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   340
## base facet classes ##########################################################
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   341
2656
a93ae0f6c0ad R [base classes] only AppObject remaning, no more AppRsetObject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   342
class AbstractFacet(AppObject):
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   343
    """Abstract base class for all facets. Facets are stored in their own
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   344
    'facets' registry. They are similar to contextual components since the use
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   345
    the following configurable properties:
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   346
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   347
    * `visible`, boolean flag telling if a facet should be displayed or not
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   348
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   349
    * `order`, integer to control facets display order
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   350
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   351
    * `context`, telling if a facet should be displayed in the table form filter
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   352
      (context = 'tablefilter') or in the facet box (context = 'facetbox') or in
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   353
      both (context = '')
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   354
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   355
    The following methods define the facet API:
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   356
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   357
    .. automethod:: cubicweb.web.facet.AbstractFacet.get_widget
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   358
    .. automethod:: cubicweb.web.facet.AbstractFacet.add_rql_restrictions
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   359
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   360
    Facets will have the following attributes set (beside the standard
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   361
    :class:`~cubicweb.appobject.AppObject` ones):
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   362
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   363
    * `select`, the :class:`rql.stmts.Select` node of the rql syntax tree being
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   364
      filtered
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   365
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   366
    * `filtered_variable`, the variable node in this rql syntax tree that we're
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   367
      interested in filtering
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   368
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   369
    Facets implementors may also be interested in the following properties /
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   370
    methods:
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   371
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   372
    .. automethod:: cubicweb.web.facet.AbstractFacet.operator
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   373
    .. automethod:: cubicweb.web.facet.AbstractFacet.rqlexec
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   374
    """
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   375
    __abstract__ = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   376
    __registry__ = 'facets'
2799
b703639614e7 refactor property handling to avoid name conflicts
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2770
diff changeset
   377
    cw_property_defs = {
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   378
        _('visible'): dict(type='Boolean', default=True,
6038
5c5d819e8e93 small cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5774
diff changeset
   379
                           help=_('display the facet or not')),
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   380
        _('order'):   dict(type='Int', default=99,
6038
5c5d819e8e93 small cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5774
diff changeset
   381
                           help=_('display order of the facet')),
496
e25a3c2f5393 set default to empty string, not None
sylvain.thenault@logilab.fr
parents: 467
diff changeset
   382
        _('context'): dict(type='String', default='',
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   383
                           # None <-> both
446
3a3ab6bbccc5 use empty string instead of None as possible context value to avoid getting an <optgroup> tag in associated widget
sylvain.thenault@logilab.fr
parents: 408
diff changeset
   384
                           vocabulary=(_('tablefilter'), _('facetbox'), ''),
6038
5c5d819e8e93 small cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5774
diff changeset
   385
                           help=_('context where this facet should be displayed, '
5c5d819e8e93 small cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5774
diff changeset
   386
                                  'leave empty for both')),
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   387
        }
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   388
    visible = True
446
3a3ab6bbccc5 use empty string instead of None as possible context value to avoid getting an <optgroup> tag in associated widget
sylvain.thenault@logilab.fr
parents: 408
diff changeset
   389
    context = ''
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   390
    needs_update = False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   391
    start_unfolded = True
4701
3acd198a66c9 [facet] before 3.6 we were sure to have a cw_rset attribute. Restore this for facets
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4615
diff changeset
   392
    cw_rset = None # ensure facets have a cw_rset attribute
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   393
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   394
    def __init__(self, req, select=None, filtered_variable=None,
2658
5535857eeaa5 [appobject selection process] drop the need for the .selected method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2656
diff changeset
   395
                 **kwargs):
4614
95ccd84c892b fix the bad rqlst syntax tree usage during facets initialization by copying it
Charles Hébert <charles.hebert@logilab.fr>
parents: 4546
diff changeset
   396
        super(AbstractFacet, self).__init__(req, **kwargs)
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   397
        assert select is not None
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   398
        assert filtered_variable
4614
95ccd84c892b fix the bad rqlst syntax tree usage during facets initialization by copying it
Charles Hébert <charles.hebert@logilab.fr>
parents: 4546
diff changeset
   399
        # take care: facet may be retreived using `object_by_id` from an ajax call
95ccd84c892b fix the bad rqlst syntax tree usage during facets initialization by copying it
Charles Hébert <charles.hebert@logilab.fr>
parents: 4546
diff changeset
   400
        # or from `select` using the result set to filter
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   401
        self.select = select
2658
5535857eeaa5 [appobject selection process] drop the need for the .selected method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2656
diff changeset
   402
        self.filtered_variable = filtered_variable
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   403
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   404
    def __repr__(self):
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   405
        return '<%s>' % self.__class__.__name__
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   406
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   407
    @property
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   408
    def operator(self):
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   409
        """Return the operator (AND or OR) to use for this facet when multiple
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   410
        values are selected.
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   411
        """
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   412
        # OR between selected values by default
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   413
        return self._cw.form.get(self.__regid__ + '_andor', 'OR')
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   414
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   415
    def rqlexec(self, rql, args=None):
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   416
        """Utility method to execute some rql queries, and simply returning an
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   417
        empty list if :exc:`Unauthorized` is raised.
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   418
        """
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   419
        try:
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   420
            return self._cw.execute(rql, args)
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   421
        except Unauthorized:
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   422
            return []
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   423
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   424
    def get_widget(self):
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   425
        """Return the widget instance to use to display this facet, or None if
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   426
        the facet can't do anything valuable (only one value in the vocabulary
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   427
        for instance).
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   428
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   429
        raise NotImplementedError
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   430
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   431
    def add_rql_restrictions(self):
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   432
        """When some facet criteria has been updated, this method is called to
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   433
        add restriction for this facet into the rql syntax tree. It should get
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   434
        back its value in form parameters, and modify the syntax tree
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   435
        (`self.select`) accordingly.
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   436
        """
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   437
        raise NotImplementedError
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   438
7402
826e5663a686 [facets/table] vertically group facets by two when possible in order to have a more compact horizontal layout in table filter form
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7280
diff changeset
   439
    @property
826e5663a686 [facets/table] vertically group facets by two when possible in order to have a more compact horizontal layout in table filter form
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7280
diff changeset
   440
    def wdgclass(self):
826e5663a686 [facets/table] vertically group facets by two when possible in order to have a more compact horizontal layout in table filter form
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7280
diff changeset
   441
        raise NotImplementedError
826e5663a686 [facets/table] vertically group facets by two when possible in order to have a more compact horizontal layout in table filter form
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7280
diff changeset
   442
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   443
    @property
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   444
    @deprecated('[3.13] renamed .select')
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   445
    def rqlst(self):
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   446
        return self.select
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   447
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   448
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   449
class VocabularyFacet(AbstractFacet):
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   450
    """This abstract class extend :class:`AbstractFacet` to use the
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   451
    :class:`FacetVocabularyWidget` as widget, suitable for facets that may
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   452
    restrict values according to a (usually computed) vocabulary.
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   453
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   454
    A class which inherits from VocabularyFacet must define at least these methods:
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   455
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   456
    .. automethod:: cubicweb.web.facet.VocabularyFacet.vocabulary
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   457
    .. automethod:: cubicweb.web.facet.VocabularyFacet.possible_values
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   458
    """
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   459
    needs_update = True
7608
47311917a548 [facet] more api cleanup: support_and should be a property, so it's easier to deactivate.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7607
diff changeset
   460
    support_and = False
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   461
7402
826e5663a686 [facets/table] vertically group facets by two when possible in order to have a more compact horizontal layout in table filter form
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7280
diff changeset
   462
    @property
826e5663a686 [facets/table] vertically group facets by two when possible in order to have a more compact horizontal layout in table filter form
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7280
diff changeset
   463
    def wdgclass(self):
826e5663a686 [facets/table] vertically group facets by two when possible in order to have a more compact horizontal layout in table filter form
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7280
diff changeset
   464
        return FacetVocabularyWidget
826e5663a686 [facets/table] vertically group facets by two when possible in order to have a more compact horizontal layout in table filter form
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7280
diff changeset
   465
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   466
    def get_widget(self):
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   467
        """Return the widget instance to use to display this facet.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   468
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   469
        This implementation expects a .vocabulary method on the facet and
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   470
        return a combobox displaying this vocabulary.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   471
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   472
        vocab = self.vocabulary()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   473
        if len(vocab) <= 1:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   474
            return None
7402
826e5663a686 [facets/table] vertically group facets by two when possible in order to have a more compact horizontal layout in table filter form
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7280
diff changeset
   475
        wdg = self.wdgclass(self)
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   476
        selected = frozenset(typed_eid(eid) for eid in self._cw.list_form_param(self.__regid__))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   477
        for label, value in vocab:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   478
            if value is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   479
                wdg.append(FacetSeparator(label))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   480
            else:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   481
                wdg.append(FacetItem(self._cw, label, value, value in selected))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   482
        return wdg
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   483
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   484
    def vocabulary(self):
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   485
        """Return vocabulary for this facet, eg a list of 2-uple (label, value).
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   486
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   487
        raise NotImplementedError
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   488
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   489
    def possible_values(self):
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   490
        """Return a list of possible values (as string since it's used to
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   491
        compare to a form value in javascript) for this facet.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   492
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   493
        raise NotImplementedError
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   494
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   495
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   496
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   497
class RelationFacet(VocabularyFacet):
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   498
    """Base facet to filter some entities according to other entities to which
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   499
    they are related. Create concret facet by inheriting from this class an then
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   500
    configuring it by setting class attribute described below.
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   501
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   502
    The relation is defined by the `rtype` and `role` attributes.
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   503
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   504
    The `no_relation` boolean flag tells if a special 'no relation' value should be
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   505
    added (allowing to filter on entities which *do not* have the relation set).
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   506
    Default is computed according the relation's cardinality.
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   507
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   508
    The values displayed for related entities will be:
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   509
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   510
    * result of calling their `label_vid` view if specified
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   511
    * else their `target_attr` attribute value if specified
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   512
    * else their eid (you usually want something nicer...)
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   513
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   514
    When no `label_vid` is set, you will get translated value if `i18nable` is
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   515
    set. By default, `i18nable` will be set according to the schema, but you can
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   516
    force its value by setting it has a class attribute.
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   517
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   518
    You can filter out target entity types by specifying `target_type`
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   519
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   520
    By default, vocabulary will be displayed sorted on `target_attr` value in an
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   521
    ascending way. You can control sorting with:
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   522
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   523
    * `sortfunc`: set this to a stored procedure name if you want to sort on the
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   524
      result of this function's result instead of direct value
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   525
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   526
    * `sortasc`: boolean flag to control ascendant/descendant sorting
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   527
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   528
    To illustrate this facet, let's take for example an *excerpt* of the schema
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   529
    of an office location search application:
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   530
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   531
    .. sourcecode:: python
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   532
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   533
      class Office(WorkflowableEntityType):
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   534
          price = Int(description='euros / m2 / HC / HT')
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   535
          surface = Int(description='m2')
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   536
          has_address = SubjectRelation('PostalAddress',
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   537
                                        cardinality='1?',
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   538
                                        composite='subject')
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   539
          proposed_by = SubjectRelation('Agency')
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   540
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   541
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   542
    We can simply define a facet to filter offices according to the agency
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   543
    proposing it:
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   544
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   545
    .. sourcecode:: python
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   546
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   547
      class AgencyFacet(RelationFacet):
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   548
          __regid__ = 'agency'
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   549
          # this facet should only be selected when visualizing offices
6152
6824f8b61098 use is_instance in a number of places (esp. documentation) rather than the deprecated implements
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6120
diff changeset
   550
          __select__ = RelationFacet.__select__ & is_instance('Office')
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   551
          # this facet is a filter on the 'Agency' entities linked to the office
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   552
          # through the 'proposed_by' relation, where the office is the subject
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   553
          # of the relation
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   554
          rtype = 'has_address'
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   555
          # 'subject' is the default but setting it explicitly doesn't hurt...
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   556
          role = 'subject'
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   557
          # we want to display the agency's name
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   558
          target_attr = 'name'
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   559
    """
838
f2c56312b03a rename abstract_* selectors into partial_* + add docstrings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 782
diff changeset
   560
    __select__ = partial_relation_possible() & match_context_prop()
5006
871269e5e020 [facet] allow to specify a target type on relation facets for case such as Keyword/CodeKeyword where we only targets Keyword
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4719
diff changeset
   561
    # class attributes to configure the relation facet
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   562
    rtype = None
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   563
    role = 'subject'
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   564
    target_attr = 'eid'
5006
871269e5e020 [facet] allow to specify a target type on relation facets for case such as Keyword/CodeKeyword where we only targets Keyword
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4719
diff changeset
   565
    target_type = None
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   566
    # set this to a stored procedure name if you want to sort on the result of
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   567
    # this function's result instead of direct value
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   568
    sortfunc = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   569
    # ascendant/descendant sorting
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   570
    sortasc = True
3328
76888cd23d83 facets enhancement: can now set label_vid to use a view instead of a simple attribute as label
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   571
    # if you want to call a view on the entity instead of using `target_attr`
76888cd23d83 facets enhancement: can now set label_vid to use a view instead of a simple attribute as label
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   572
    label_vid = None
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   573
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   574
    # internal purpose
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   575
    _select_target_entity = True
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   576
6336
ae80aed607f2 [facet] use contextified label when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6251
diff changeset
   577
    title = property(rtype_facet_title)
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   578
    no_relation_label = '<no relation>'
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   579
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   580
    def __repr__(self):
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   581
        return '<%s on (%s-%s)>' % (self.__class__.__name__, self.rtype, self.role)
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   582
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   583
    # facet public API #########################################################
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   584
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   585
    def vocabulary(self):
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   586
        """return vocabulary for this facet, eg a list of 2-uple (label, value)
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   587
        """
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   588
        select = self.select
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   589
        select.save_state()
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   590
        if self.rql_sort:
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   591
            sort = self.sortasc
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   592
        else:
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   593
            sort = None # will be sorted on label
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   594
        try:
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   595
            var = insert_attr_select_relation(
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   596
                select, self.filtered_variable, self.rtype, self.role,
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   597
                self.target_attr, self.sortfunc, sort,
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   598
                self._select_target_entity)
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   599
            if self.target_type is not None:
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   600
                select.add_type_restriction(var, self.target_type)
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   601
            try:
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   602
                rset = self.rqlexec(select.as_string(), self.cw_rset.args)
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   603
            except:
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   604
                self.exception('error while getting vocabulary for %s, rql: %s',
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   605
                               self, select.as_string())
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   606
                return ()
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   607
        finally:
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   608
            select.recover()
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   609
        # don't call rset_vocabulary on empty result set, it may be an empty
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   610
        # *list* (see rqlexec implementation)
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   611
        values = rset and self.rset_vocabulary(rset) or []
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   612
        if self._include_no_relation():
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   613
            values.insert(0, (self._cw._(self.no_relation_label), ''))
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   614
        return values
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   615
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   616
    def possible_values(self):
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   617
        """return a list of possible values (as string since it's used to
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   618
        compare to a form value in javascript) for this facet
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   619
        """
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   620
        select = self.select
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   621
        select.save_state()
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   622
        try:
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   623
            cleanup_select(select, self.filtered_variable)
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   624
            if self._select_target_entity:
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   625
                prepare_vocabulary_select(select, self.filtered_variable, self.rtype,
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   626
                                         self.role, select_target_entity=True)
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   627
            else:
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   628
                insert_attr_select_relation(
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   629
                    select, self.filtered_variable, self.rtype, self.role, self.target_attr,
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   630
                    select_target_entity=False)
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   631
            values = [unicode(x) for x, in self.rqlexec(select.as_string())]
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   632
        except:
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   633
            self.exception('while computing values for %s', self)
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   634
            return []
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   635
        finally:
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   636
            select.recover()
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   637
        if self._include_no_relation():
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   638
            values.append('')
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   639
        return values
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   640
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   641
    def add_rql_restrictions(self):
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   642
        """add restriction for this facet into the rql syntax tree"""
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   643
        value = self._cw.form.get(self.__regid__)
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   644
        if value is None:
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   645
            return
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   646
        filtered_variable = self.filtered_variable
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   647
        restrvar, rel = _add_rtype_relation(self.select, filtered_variable,
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   648
                                            self.rtype, self.role)
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   649
        self.value_restriction(restrvar, rel, value)
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   650
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   651
    # internal control API #####################################################
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   652
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   653
    @property
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   654
    def i18nable(self):
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   655
        """should label be internationalized"""
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   656
        if self.target_type:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   657
            eschema = self._cw.vreg.schema.eschema(self.target_type)
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   658
        elif self.role == 'subject':
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   659
            eschema = self._cw.vreg.schema.rschema(self.rtype).objects()[0]
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   660
        else:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   661
            eschema = self._cw.vreg.schema.rschema(self.rtype).subjects()[0]
6662
8862bf4a6dd4 [facet] only String attributes have internationalizable property
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6623
diff changeset
   662
        return getattr(eschema.rdef(self.target_attr), 'internationalizable', False)
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   663
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   664
    @property
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   665
    def no_relation(self):
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   666
        return (not self._cw.vreg.schema.rschema(self.rtype).final
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   667
                and self._search_card('?*'))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   668
6251
afc757568492 [facet] add missing @property making subsequent access always true
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6152
diff changeset
   669
    @property
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   670
    def rql_sort(self):
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   671
        """return true if we can handle sorting in the rql query. E.g.  if
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   672
        sortfunc is set or if we have not to transform the returned value (eg no
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   673
        label_vid and not i18nable)
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   674
        """
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   675
        return self.sortfunc is not None or (self.label_vid is None
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   676
                                             and not self.i18nable)
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   677
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   678
    def rset_vocabulary(self, rset):
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   679
        if self.i18nable:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   680
            _ = self._cw._
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   681
        else:
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   682
            _ = unicode
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   683
        if self.rql_sort:
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   684
            values = [(_(label), eid) for eid, label in rset]
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   685
        else:
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   686
            if self.label_vid is None:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   687
                values = [(_(label), eid) for eid, label in rset]
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   688
            else:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   689
                values = [(entity.view(self.label_vid), entity.eid)
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   690
                          for entity in rset.entities()]
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   691
            values = sorted(values)
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   692
            if not self.sortasc:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   693
                values = list(reversed(values))
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   694
        return values
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   695
7608
47311917a548 [facet] more api cleanup: support_and should be a property, so it's easier to deactivate.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7607
diff changeset
   696
    @property
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   697
    def support_and(self):
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   698
        return self._search_card('+*')
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   699
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   700
    # internal utilities #######################################################
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   701
7608
47311917a548 [facet] more api cleanup: support_and should be a property, so it's easier to deactivate.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7607
diff changeset
   702
    def _support_and_compat(self):
47311917a548 [facet] more api cleanup: support_and should be a property, so it's easier to deactivate.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7607
diff changeset
   703
        support = self.support_and
47311917a548 [facet] more api cleanup: support_and should be a property, so it's easier to deactivate.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7607
diff changeset
   704
        if callable(support):
47311917a548 [facet] more api cleanup: support_and should be a property, so it's easier to deactivate.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7607
diff changeset
   705
            warn('[3.13] %s.support_and is now a property' % self.__class__,
47311917a548 [facet] more api cleanup: support_and should be a property, so it's easier to deactivate.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7607
diff changeset
   706
                 DeprecationWarning)
47311917a548 [facet] more api cleanup: support_and should be a property, so it's easier to deactivate.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7607
diff changeset
   707
            support = support()
47311917a548 [facet] more api cleanup: support_and should be a property, so it's easier to deactivate.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7607
diff changeset
   708
        return support
47311917a548 [facet] more api cleanup: support_and should be a property, so it's easier to deactivate.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7607
diff changeset
   709
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   710
    def value_restriction(self, restrvar, rel, value):
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   711
        if isinstance(value, basestring):
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   712
            # only one value selected
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   713
            if value:
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   714
                self.select.add_eid_restriction(restrvar, value)
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   715
            else:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   716
                rel.parent.replace(rel, nodes.Not(rel))
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   717
        elif self.operator == 'OR':
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   718
            # set_distinct only if rtype cardinality is > 1
7608
47311917a548 [facet] more api cleanup: support_and should be a property, so it's easier to deactivate.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7607
diff changeset
   719
            if self._support_and_compat():
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   720
                self.select.set_distinct(True)
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   721
            # multiple ORed values: using IN is fine
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   722
            if '' in value:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   723
                value.remove('')
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   724
                self._add_not_rel_restr(rel)
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   725
            _add_eid_restr(rel, restrvar, value)
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   726
        else:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   727
            # multiple values with AND operator
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   728
            if '' in value:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   729
                value.remove('')
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   730
                self._add_not_rel_restr(rel)
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   731
            _add_eid_restr(rel, restrvar, value.pop())
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   732
            while value:
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   733
                restrvar, rtrel = _make_relation(self.select, filtered_variable,
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   734
                                                 self.rtype, self.role)
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   735
                _add_eid_restr(rel, restrvar, value.pop())
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   736
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   737
    @cached
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   738
    def _search_card(self, cards):
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   739
        for rdef in self._iter_rdefs():
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   740
            if rdef.role_cardinality(self.role) in cards:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   741
                return True
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   742
        return False
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   743
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   744
    def _iter_rdefs(self):
3456
1a63a252601f [facets] typo fix
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3451
diff changeset
   745
        rschema = self._cw.vreg.schema.rschema(self.rtype)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   746
        # XXX when called via ajax, no rset to compute possible types
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   747
        possibletypes = self.cw_rset and self.cw_rset.column_types(0)
4087
2b8bc4cfd6ee api update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4074
diff changeset
   748
        for rdef in rschema.rdefs.itervalues():
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   749
            if possibletypes is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   750
                if self.role == 'subject':
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   751
                    if rdef.subject not in possibletypes:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   752
                        continue
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   753
                elif rdef.object not in possibletypes:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   754
                    continue
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   755
            if self.target_type is not None:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   756
                if self.role == 'subject':
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   757
                    if rdef.object != self.target_type:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   758
                        continue
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   759
                elif rdef.subject != self.target_type:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   760
                    continue
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   761
            yield rdef
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   762
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   763
    def _include_no_relation(self):
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   764
        if not self.no_relation:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   765
            return False
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   766
        if self._cw.vreg.schema.rschema(self.rtype).final:
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   767
            return False
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   768
        if self.role == 'object':
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   769
            subj = utils.rqlvar_maker(defined=self.select.defined_vars,
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   770
                                      aliases=self.select.aliases).next()
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   771
            obj = self.filtered_variable.name
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   772
        else:
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   773
            subj = self.filtered_variable.name
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   774
            obj = utils.rqlvar_maker(defined=self.select.defined_vars,
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   775
                                     aliases=self.select.aliases).next()
6681
674461009c7c fix #1376317: facet: no_relation feature crash when rql has no restriction
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6662
diff changeset
   776
        restrictions = []
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   777
        if self.select.where:
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   778
            restrictions.append(self.select.where.as_string())
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   779
        if self.select.with_:
6681
674461009c7c fix #1376317: facet: no_relation feature crash when rql has no restriction
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6662
diff changeset
   780
            restrictions.append('WITH ' + ','.join(
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   781
                term.as_string() for term in self.select.with_))
6681
674461009c7c fix #1376317: facet: no_relation feature crash when rql has no restriction
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6662
diff changeset
   782
        if restrictions:
674461009c7c fix #1376317: facet: no_relation feature crash when rql has no restriction
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6662
diff changeset
   783
            restrictions = ',' + ','.join(restrictions)
674461009c7c fix #1376317: facet: no_relation feature crash when rql has no restriction
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6662
diff changeset
   784
        else:
674461009c7c fix #1376317: facet: no_relation feature crash when rql has no restriction
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6662
diff changeset
   785
            restrictions = ''
674461009c7c fix #1376317: facet: no_relation feature crash when rql has no restriction
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6662
diff changeset
   786
        rql = 'Any %s LIMIT 1 WHERE NOT %s %s %s%s' % (
674461009c7c fix #1376317: facet: no_relation feature crash when rql has no restriction
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6662
diff changeset
   787
            self.filtered_variable.name, subj, self.rtype, obj, restrictions)
6599
d3008cb6d1c3 [ms] catch exception on executing rql, work-around #1356884 until a proper fix
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6582
diff changeset
   788
        try:
d3008cb6d1c3 [ms] catch exception on executing rql, work-around #1356884 until a proper fix
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6582
diff changeset
   789
            return bool(self.rqlexec(rql, self.cw_rset and self.cw_rset.args))
d3008cb6d1c3 [ms] catch exception on executing rql, work-around #1356884 until a proper fix
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6582
diff changeset
   790
        except:
d3008cb6d1c3 [ms] catch exception on executing rql, work-around #1356884 until a proper fix
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6582
diff changeset
   791
            # catch exception on executing rql, work-around #1356884 until a
d3008cb6d1c3 [ms] catch exception on executing rql, work-around #1356884 until a proper fix
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6582
diff changeset
   792
            # proper fix
d3008cb6d1c3 [ms] catch exception on executing rql, work-around #1356884 until a proper fix
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6582
diff changeset
   793
            self.exception('cant handle rql generated by %s', self)
d3008cb6d1c3 [ms] catch exception on executing rql, work-around #1356884 until a proper fix
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6582
diff changeset
   794
            return False
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   795
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   796
    def _add_not_rel_restr(self, rel):
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   797
        nrrel = nodes.Not(_make_relation(self.select, self.filtered_variable,
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   798
                                         self.rtype, self.role)[1])
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   799
        rel.parent.replace(rel, nodes.Or(nrrel, rel))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   800
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   801
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   802
class RelationAttributeFacet(RelationFacet):
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   803
    """Base facet to filter some entities according to an attribute of other
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   804
    entities to which they are related. Most things work similarly as
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   805
    :class:`RelationFacet`, except that:
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   806
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   807
    * `label_vid` doesn't make sense here
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   808
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   809
    * you should specify the attribute type using `attrtype` if it's not a
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   810
      String
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   811
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   812
    * you can specify a comparison operator using `comparator`
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   813
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   814
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   815
    Back to our example... if you want to search office by postal code and that
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   816
    you use a :class:`RelationFacet` for that, you won't get the expected
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   817
    behaviour: if two offices have the same postal code, they've however two
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   818
    different addresses.  So you'll see in the facet the same postal code twice,
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   819
    though linked to a different address entity. There is a great chance your
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   820
    users won't understand that...
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   821
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   822
    That's where this class come in ! It's used to said that you want to filter
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   823
    according to the *attribute value* of a relatied entity, not to the entity
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   824
    itself. Now here is the source code for the facet:
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   825
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   826
    .. sourcecode:: python
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   827
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   828
      class PostalCodeFacet(RelationAttributeFacet):
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   829
          __regid__ = 'postalcode'
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   830
          # this facet should only be selected when visualizing offices
6152
6824f8b61098 use is_instance in a number of places (esp. documentation) rather than the deprecated implements
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6120
diff changeset
   831
          __select__ = RelationAttributeFacet.__select__ & is_instance('Office')
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   832
          # this facet is a filter on the PostalAddress entities linked to the
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   833
          # office through the 'has_address' relation, where the office is the
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   834
          # subject of the relation
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   835
          rtype = 'has_address'
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   836
          role = 'subject'
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   837
          # we want to search according to address 'postal_code' attribute
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   838
          target_attr = 'postalcode'
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   839
    """
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   840
    _select_target_entity = False
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   841
    # attribute type
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   842
    attrtype = 'String'
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   843
    # type of comparison: default is an exact match on the attribute value
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   844
    comparator = '=' # could be '<', '<=', '>', '>='
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   845
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   846
    def rset_vocabulary(self, rset):
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   847
        if self.i18nable:
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   848
            _ = self._cw._
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   849
        else:
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   850
            _ = unicode
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   851
        if self.rql_sort:
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   852
            return [(_(value), value) for value, in rset]
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   853
        values = [(_(value), value) for value, in rset]
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   854
        if self.sortasc:
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   855
            return sorted(values)
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   856
        return reversed(sorted(values))
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   857
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   858
    def add_rql_restrictions(self):
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   859
        """add restriction for this facet into the rql syntax tree"""
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   860
        value = self._cw.form.get(self.__regid__)
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   861
        if not value:
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   862
            return
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   863
        filtered_variable = self.filtered_variable
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   864
        restrvar = _add_rtype_relation(self.select, filtered_variable, self.rtype,
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   865
                                       self.role)[0]
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   866
        self.select.set_distinct(True)
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   867
        if isinstance(value, basestring) or self.operator == 'OR':
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   868
            # only one value selected or multiple ORed values: using IN is fine
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   869
            self.select.add_constant_restriction(
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   870
                restrvar, self.target_attr, value,
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   871
                self.attrtype, self.comparator)
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   872
        else:
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   873
            # multiple values with AND operator
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   874
            self.select.add_constant_restriction(
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   875
                restrvar, self.target_attr, value.pop(),
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   876
                self.attrtype, self.comparator)
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   877
            while value:
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   878
                restrvar = _add_rtype_relation(self.select, filtered_variable, self.rtype,
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   879
                                               self.role)[0]
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   880
                self.select.add_constant_restriction(
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   881
                    restrvar, self.target_attr, value.pop(),
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   882
                    self.attrtype, self.comparator)
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   883
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   884
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   885
class AttributeFacet(RelationAttributeFacet):
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   886
    """Base facet to filter some entities according one of their attribute.
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   887
    Configuration is mostly similarly as :class:`RelationAttributeFacet`, except that:
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   888
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   889
    * `target_attr` doesn't make sense here (you specify the attribute using `rtype`
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   890
    * `role` neither, it's systematically 'subject'
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   891
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   892
    So, suppose that in our office search example you want to refine search according
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   893
    to the office's surface. Here is a code snippet achieving this:
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   894
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   895
    .. sourcecode:: python
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   896
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   897
      class SurfaceFacet(AttributeFacet):
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   898
          __regid__ = 'surface'
6152
6824f8b61098 use is_instance in a number of places (esp. documentation) rather than the deprecated implements
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6120
diff changeset
   899
          __select__ = AttributeFacet.__select__ & is_instance('Office')
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   900
          # this facet is a filter on the office'surface
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   901
          rtype = 'surface'
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   902
          # override the default value of operator since we want to filter
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   903
          # according to a minimal value, not an exact one
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   904
          comparator = '>='
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   905
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   906
          def vocabulary(self):
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   907
              '''override the default vocabulary method since we want to
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   908
              hard-code our threshold values.
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   909
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   910
              Not overriding would generate a filter containing all existing
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   911
              surfaces defined in the database.
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   912
              '''
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   913
              return [('> 200', '200'), ('> 250', '250'),
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   914
                      ('> 275', '275'), ('> 300', '300')]
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   915
    """
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   916
7608
47311917a548 [facet] more api cleanup: support_and should be a property, so it's easier to deactivate.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7607
diff changeset
   917
    support_and = False
6119
b217635d3b28 new RelationAttributeFacet + other fixes and cleanup + facets test
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   918
    _select_target_entity = True
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   919
6380
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   920
    @property
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   921
    def i18nable(self):
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   922
        """should label be internationalized"""
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   923
        for rdef in self._iter_rdefs():
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   924
            # no 'internationalizable' property for rdef whose object is not a
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   925
            # String
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   926
            if not getattr(rdef, 'internationalizable', False):
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   927
                return False
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   928
        return True
63d5dbaef999 [facets] support for `no_relation` on RelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6336
diff changeset
   929
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   930
    def vocabulary(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   931
        """return vocabulary for this facet, eg a list of 2-uple (label, value)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   932
        """
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   933
        select = self.select
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   934
        select.save_state()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   935
        try:
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   936
            filtered_variable = self.filtered_variable
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   937
            cleanup_select(select, filtered_variable)
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   938
            newvar = prepare_vocabulary_select(select, filtered_variable, self.rtype, self.role)
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   939
            _set_orderby(select, newvar, self.sortasc, self.sortfunc)
346
5bbb01a133ae add try except to avoid error w/ unsupported stuff, log it and return incomplete filter form
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 203
diff changeset
   940
            try:
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   941
                rset = self.rqlexec(select.as_string(), self.cw_rset.args)
346
5bbb01a133ae add try except to avoid error w/ unsupported stuff, log it and return incomplete filter form
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 203
diff changeset
   942
            except:
5bbb01a133ae add try except to avoid error w/ unsupported stuff, log it and return incomplete filter form
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 203
diff changeset
   943
                self.exception('error while getting vocabulary for %s, rql: %s',
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   944
                               self, select.as_string())
346
5bbb01a133ae add try except to avoid error w/ unsupported stuff, log it and return incomplete filter form
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 203
diff changeset
   945
                return ()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   946
        finally:
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   947
            select.recover()
5225
9ff0dee81eb2 [facet] don't crash in rset_vocabulary if an unauthorized error was raised in rqlexec
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5006
diff changeset
   948
        # don't call rset_vocabulary on empty result set, it may be an empty
9ff0dee81eb2 [facet] don't crash in rset_vocabulary if an unauthorized error was raised in rqlexec
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5006
diff changeset
   949
        # *list* (see rqlexec implementation)
9ff0dee81eb2 [facet] don't crash in rset_vocabulary if an unauthorized error was raised in rqlexec
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5006
diff changeset
   950
        return rset and self.rset_vocabulary(rset)
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   951
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   952
    def add_rql_restrictions(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   953
        """add restriction for this facet into the rql syntax tree"""
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   954
        value = self._cw.form.get(self.__regid__)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   955
        if not value:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   956
            return
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   957
        filtered_variable = self.filtered_variable
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
   958
        self.select.add_constant_restriction(filtered_variable, self.rtype, value,
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   959
                                            self.attrtype, self.comparator)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   960
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   961
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   962
class RangeFacet(AttributeFacet):
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   963
    """This class allows to filter entities according to an attribute of
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   964
    numerical type.
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   965
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   966
    It displays a slider using `jquery`_ to choose a lower bound and an upper
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   967
    bound.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   968
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   969
    The example below provides an alternative to the surface facet seen earlier,
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   970
    in a more powerful way since
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   971
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   972
    * lower/upper boundaries are computed according to entities to filter
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   973
    * user can specify lower/upper boundaries, not only the lower one
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   974
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   975
    .. sourcecode:: python
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   976
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   977
      class SurfaceFacet(RangeFacet):
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   978
          __regid__ = 'surface'
6152
6824f8b61098 use is_instance in a number of places (esp. documentation) rather than the deprecated implements
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6120
diff changeset
   979
          __select__ = RangeFacet.__select__ & is_instance('Office')
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   980
          # this facet is a filter on the office'surface
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   981
          rtype = 'surface'
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   982
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   983
    All this with even less code!
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
   984
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   985
    The image below display the rendering of the slider:
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   986
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   987
    .. image:: ../images/facet_range.png
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   988
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   989
    .. _jquery: http://www.jqueryui.com/
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
   990
    """
2010
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   991
    attrtype = 'Float' # only numerical types are supported
7609
fbefd1b9e587 [facets] DontUpdateConstraint mecanism introduced a few commit ago isn't needed: we already have the 'needs_update' property controlling this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7608
diff changeset
   992
    needs_update = False # not supported actually
2010
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   993
7204
2b6d3c9455a7 Backed out changeset e0e802afa8e1, widgets are actually defined below
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7203
diff changeset
   994
    @property
2b6d3c9455a7 Backed out changeset e0e802afa8e1, widgets are actually defined below
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7203
diff changeset
   995
    def wdgclass(self):
2b6d3c9455a7 Backed out changeset e0e802afa8e1, widgets are actually defined below
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7203
diff changeset
   996
        return FacetRangeWidget
2010
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   997
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
   998
    def get_widget(self):
4546
f8ac61376b2b provides a fallback_on_none_attribute field attribute, allowing to specify default value for attributes of *existing* entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4466
diff changeset
   999
        """return the widget instance to use to display this facet"""
2010
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
  1000
        values = set(value for _, value in self.vocabulary() if value is not None)
4615
d69d7ccbe046 Fix: RangeFacet is selected (valid rset) but without any values
Charles Hébert <charles.hebert@logilab.fr>
parents: 4614
diff changeset
  1001
        # Rset with entities (the facet is selected) but without values
7248
f20fc41e3f7d [facets] fix RangeFacet get_widget: do no return a widget unless there are at least 2 values; closes #1625203
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7235
diff changeset
  1002
        if len(values) < 2:
4615
d69d7ccbe046 Fix: RangeFacet is selected (valid rset) but without any values
Charles Hébert <charles.hebert@logilab.fr>
parents: 4614
diff changeset
  1003
            return None
2010
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
  1004
        return self.wdgclass(self, min(values), max(values))
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
  1005
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
  1006
    def formatvalue(self, value):
2020
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1007
        """format `value` before in order to insert it in the RQL query"""
2010
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
  1008
        return unicode(value)
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
  1009
7205
9220ae2cacf1 [facet] ignore range extremas to avoid filtering out rows where value is NULL (closes #1251192)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7204
diff changeset
  1010
    def infvalue(self, min=False):
9220ae2cacf1 [facet] ignore range extremas to avoid filtering out rows where value is NULL (closes #1251192)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7204
diff changeset
  1011
        if min:
9220ae2cacf1 [facet] ignore range extremas to avoid filtering out rows where value is NULL (closes #1251192)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7204
diff changeset
  1012
            return self._cw.form.get('min_%s_inf' % self.__regid__)
9220ae2cacf1 [facet] ignore range extremas to avoid filtering out rows where value is NULL (closes #1251192)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7204
diff changeset
  1013
        return self._cw.form.get('%s_inf' % self.__regid__)
9220ae2cacf1 [facet] ignore range extremas to avoid filtering out rows where value is NULL (closes #1251192)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7204
diff changeset
  1014
9220ae2cacf1 [facet] ignore range extremas to avoid filtering out rows where value is NULL (closes #1251192)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7204
diff changeset
  1015
    def supvalue(self, max=False):
9220ae2cacf1 [facet] ignore range extremas to avoid filtering out rows where value is NULL (closes #1251192)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7204
diff changeset
  1016
        if max:
9220ae2cacf1 [facet] ignore range extremas to avoid filtering out rows where value is NULL (closes #1251192)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7204
diff changeset
  1017
            return self._cw.form.get('max_%s_sup' % self.__regid__)
9220ae2cacf1 [facet] ignore range extremas to avoid filtering out rows where value is NULL (closes #1251192)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7204
diff changeset
  1018
        return self._cw.form.get('%s_sup' % self.__regid__)
9220ae2cacf1 [facet] ignore range extremas to avoid filtering out rows where value is NULL (closes #1251192)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7204
diff changeset
  1019
2010
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
  1020
    def add_rql_restrictions(self):
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
  1021
        infvalue = self.infvalue()
7205
9220ae2cacf1 [facet] ignore range extremas to avoid filtering out rows where value is NULL (closes #1251192)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7204
diff changeset
  1022
        supvalue = self.supvalue()
9220ae2cacf1 [facet] ignore range extremas to avoid filtering out rows where value is NULL (closes #1251192)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7204
diff changeset
  1023
        if infvalue is None or supvalue is None: # nothing sent
2010
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
  1024
            return
7205
9220ae2cacf1 [facet] ignore range extremas to avoid filtering out rows where value is NULL (closes #1251192)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7204
diff changeset
  1025
        # when a value is equal to one of the limit, don't add the restriction,
9220ae2cacf1 [facet] ignore range extremas to avoid filtering out rows where value is NULL (closes #1251192)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7204
diff changeset
  1026
        # else we filter out NULL values implicitly
9220ae2cacf1 [facet] ignore range extremas to avoid filtering out rows where value is NULL (closes #1251192)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7204
diff changeset
  1027
        if infvalue != self.infvalue(min=True):
7607
d332ecfc224a [range facet] refactor to ease overriding, possible_values raise DontUpdateFacet (not handled by js actually)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7605
diff changeset
  1028
            self._add_restriction(infvalue, '>=')
7205
9220ae2cacf1 [facet] ignore range extremas to avoid filtering out rows where value is NULL (closes #1251192)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7204
diff changeset
  1029
        if supvalue != self.supvalue(max=True):
7607
d332ecfc224a [range facet] refactor to ease overriding, possible_values raise DontUpdateFacet (not handled by js actually)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7605
diff changeset
  1030
            self._add_restriction(supvalue, '<=')
d332ecfc224a [range facet] refactor to ease overriding, possible_values raise DontUpdateFacet (not handled by js actually)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7605
diff changeset
  1031
7615
e5ad51352eb3 [facet] fix argument inversion in date range facet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7609
diff changeset
  1032
    def _add_restriction(self, value, operator):
7607
d332ecfc224a [range facet] refactor to ease overriding, possible_values raise DontUpdateFacet (not handled by js actually)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7605
diff changeset
  1033
        self.select.add_constant_restriction(self.filtered_variable,
d332ecfc224a [range facet] refactor to ease overriding, possible_values raise DontUpdateFacet (not handled by js actually)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7605
diff changeset
  1034
                                             self.rtype,
d332ecfc224a [range facet] refactor to ease overriding, possible_values raise DontUpdateFacet (not handled by js actually)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7605
diff changeset
  1035
                                             self.formatvalue(value),
d332ecfc224a [range facet] refactor to ease overriding, possible_values raise DontUpdateFacet (not handled by js actually)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7605
diff changeset
  1036
                                             self.attrtype, operator)
d332ecfc224a [range facet] refactor to ease overriding, possible_values raise DontUpdateFacet (not handled by js actually)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7605
diff changeset
  1037
2010
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
  1038
3329
8430f6c693a1 cleanup, smarter sort control to avoid it when not necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3328
diff changeset
  1039
2010
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
  1040
class DateRangeFacet(RangeFacet):
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1041
    """This class works similarly as the :class:`RangeFacet` but for attribute
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1042
    of date type.
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1043
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1044
    The image below display the rendering of the slider for a date range:
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1045
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1046
    .. image:: ../images/facet_date_range.png
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1047
    """
2010
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
  1048
    attrtype = 'Date' # only date types are supported
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
  1049
7204
2b6d3c9455a7 Backed out changeset e0e802afa8e1, widgets are actually defined below
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7203
diff changeset
  1050
    @property
2b6d3c9455a7 Backed out changeset e0e802afa8e1, widgets are actually defined below
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7203
diff changeset
  1051
    def wdgclass(self):
2b6d3c9455a7 Backed out changeset e0e802afa8e1, widgets are actually defined below
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7203
diff changeset
  1052
        return DateFacetRangeWidget
2010
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
  1053
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
  1054
    def formatvalue(self, value):
2020
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1055
        """format `value` before in order to insert it in the RQL query"""
7117
44775b275d45 [facets] closes #1569459 (date-range facet with year < 1900)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7070
diff changeset
  1056
        try:
44775b275d45 [facets] closes #1569459 (date-range facet with year < 1900)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7070
diff changeset
  1057
            date_value = ticks2datetime(float(value))
44775b275d45 [facets] closes #1569459 (date-range facet with year < 1900)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7070
diff changeset
  1058
        except (ValueError, OverflowError):
44775b275d45 [facets] closes #1569459 (date-range facet with year < 1900)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7070
diff changeset
  1059
            return u'"date out-of-range"'
44775b275d45 [facets] closes #1569459 (date-range facet with year < 1900)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7070
diff changeset
  1060
        return '"%s"' % ustrftime(date_value, '%Y/%m/%d')
2010
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
  1061
2020
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1062
2014
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1063
class HasRelationFacet(AbstractFacet):
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1064
    """This class simply filter according to the presence of a relation
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1065
    (whatever the entity at the other end). It display a simple checkbox that
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1066
    lets you refine your selection in order to get only entities that actually
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1067
    have this relation. You simply have to define which relation using the
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1068
    `rtype` and `role` attributes.
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1069
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1070
    Here is an example of the rendering of thos facet to filter book with image
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1071
    and the corresponding code:
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1072
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1073
    .. image:: ../images/facet_has_image.png
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1074
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1075
    .. sourcecode:: python
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1076
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1077
      class HasImageFacet(HasRelationFacet):
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1078
          __regid__ = 'hasimage'
6152
6824f8b61098 use is_instance in a number of places (esp. documentation) rather than the deprecated implements
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6120
diff changeset
  1079
          __select__ = HasRelationFacet.__select__ & is_instance('Book')
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1080
          rtype = 'has_image'
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1081
          role = 'subject'
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1082
    """
7280
571b29842ef1 [facet] add missing selector to HasRelationFacet
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7279
diff changeset
  1083
    __select__ = partial_relation_possible() & match_context_prop()
2014
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1084
    rtype = None # override me in subclass
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1085
    role = 'subject' # role of filtered entity in the relation
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1086
6336
ae80aed607f2 [facet] use contextified label when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6251
diff changeset
  1087
    title = property(rtype_facet_title)
7609
fbefd1b9e587 [facets] DontUpdateConstraint mecanism introduced a few commit ago isn't needed: we already have the 'needs_update' property controlling this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7608
diff changeset
  1088
    needs_update = False # not supported actually
7608
47311917a548 [facet] more api cleanup: support_and should be a property, so it's easier to deactivate.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7607
diff changeset
  1089
    support_and = False
2014
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1090
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1091
    def get_widget(self):
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1092
        return CheckBoxFacetWidget(self._cw, self,
2014
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1093
                                   '%s:%s' % (self.rtype, self),
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1094
                                   self._cw.form.get(self.__regid__))
2014
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1095
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1096
    def add_rql_restrictions(self):
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1097
        """add restriction for this facet into the rql syntax tree"""
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
  1098
        self.select.set_distinct(True) # XXX
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1099
        value = self._cw.form.get(self.__regid__)
2014
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1100
        if not value: # no value sent for this facet
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1101
            return
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
  1102
        var = self.select.make_variable()
2014
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1103
        if self.role == 'subject':
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
  1104
            self.select.add_relation(self.filtered_variable, self.rtype, var)
2014
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1105
        else:
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
  1106
            self.select.add_relation(var, self.rtype, self.filtered_variable)
2014
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1107
3329
8430f6c693a1 cleanup, smarter sort control to avoid it when not necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3328
diff changeset
  1108
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1109
## html widets ################################################################
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1110
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1111
class FacetVocabularyWidget(HTMLWidget):
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
  1112
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1113
    def __init__(self, facet):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1114
        self.facet = facet
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1115
        self.items = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1116
7402
826e5663a686 [facets/table] vertically group facets by two when possible in order to have a more compact horizontal layout in table filter form
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7280
diff changeset
  1117
    def height(self):
826e5663a686 [facets/table] vertically group facets by two when possible in order to have a more compact horizontal layout in table filter form
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7280
diff changeset
  1118
        return len(self.items) + 1
826e5663a686 [facets/table] vertically group facets by two when possible in order to have a more compact horizontal layout in table filter form
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7280
diff changeset
  1119
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1120
    def append(self, item):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1121
        self.items.append(item)
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
  1122
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1123
    def _render(self):
7414
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1124
        w = self.w
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2305
diff changeset
  1125
        title = xml_escape(self.facet.title)
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1126
        facetid = xml_escape(self.facet.__regid__)
7414
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1127
        w(u'<div id="%s" class="facet">\n' % facetid)
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1128
        w(u'<div class="facetTitle" cubicweb:facetName="%s">%s</div>\n' %
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1129
          (xml_escape(facetid), title))
7608
47311917a548 [facet] more api cleanup: support_and should be a property, so it's easier to deactivate.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7607
diff changeset
  1130
        if self.facet._support_and_compat():
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1131
            _ = self.facet._cw._
7414
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1132
            w(u'''<select name="%s" class="radio facetOperator" title="%s">
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1133
  <option value="OR">%s</option>
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1134
  <option value="AND">%s</option>
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1135
</select>''' % (facetid + '_andor', _('and/or between different values'),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1136
                _('OR'), _('AND')))
7225
a4a115aab086 [facets] make rangefacet comply with start_unfolded (closes #1615869)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7205
diff changeset
  1137
        cssclass = 'facetBody'
368
84a5106840fa facet widgets css cleanup
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 346
diff changeset
  1138
        if not self.facet.start_unfolded:
84a5106840fa facet widgets css cleanup
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 346
diff changeset
  1139
            cssclass += ' hidden'
949
1fba39d6ee70 fix in facets (avoid to have an horizontal space between facets when facets are unfold)
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 536
diff changeset
  1140
        if len(self.items) > 6:
1132
96752791c2b6 pylint cleanup
sylvain.thenault@logilab.fr
parents: 985
diff changeset
  1141
            cssclass += ' overflowed'
7414
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1142
        w(u'<div class="%s">\n' % cssclass)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1143
        for item in self.items:
7414
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1144
            item.render(w=w)
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1145
        w(u'</div>\n')
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1146
        w(u'</div>\n')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1147
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
  1148
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1149
class FacetStringWidget(HTMLWidget):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1150
    def __init__(self, facet):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1151
        self.facet = facet
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1152
        self.value = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1153
7402
826e5663a686 [facets/table] vertically group facets by two when possible in order to have a more compact horizontal layout in table filter form
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7280
diff changeset
  1154
    def height(self):
7413
94ad9523abb7 [web/facet|views/table] bump a bit some heights, split table view methods for easier subclassing
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7402
diff changeset
  1155
        return 3
7402
826e5663a686 [facets/table] vertically group facets by two when possible in order to have a more compact horizontal layout in table filter form
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7280
diff changeset
  1156
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1157
    def _render(self):
7414
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1158
        w = self.w
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2305
diff changeset
  1159
        title = xml_escape(self.facet.title)
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1160
        facetid = xml_escape(self.facet.__regid__)
7414
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1161
        w(u'<div id="%s" class="facet">\n' % facetid)
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1162
        w(u'<div class="facetTitle" cubicweb:facetName="%s">%s</div>\n' %
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1163
               (facetid, title))
7414
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1164
        w(u'<input name="%s" type="text" value="%s" />\n' % (facetid, self.value or u''))
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1165
        w(u'</div>\n')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1166
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1167
1896
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1168
class FacetRangeWidget(HTMLWidget):
2020
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1169
    formatter = 'function (value) {return value;}'
1896
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1170
    onload = u'''
2020
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1171
    var _formatter = %(formatter)s;
1896
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1172
    jQuery("#%(sliderid)s").slider({
2020
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1173
        range: true,
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1174
        min: %(minvalue)s,
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1175
        max: %(maxvalue)s,
1896
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1176
        values: [%(minvalue)s, %(maxvalue)s],
1933
f40ee76ecdf1 [facet][RangeFacet] submit facet form when the user stops sliding
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1896
diff changeset
  1177
        stop: function(event, ui) { // submit when the user stops sliding
f40ee76ecdf1 [facet][RangeFacet] submit facet form when the user stops sliding
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1896
diff changeset
  1178
           var form = $('#%(sliderid)s').closest('form');
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
  1179
           buildRQL.apply(null, cw.evalJSON(form.attr('cubicweb:facetargs')));
1933
f40ee76ecdf1 [facet][RangeFacet] submit facet form when the user stops sliding
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1896
diff changeset
  1180
        },
2020
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1181
        slide: function(event, ui) {
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1182
            jQuery('#%(sliderid)s_inf').html(_formatter(ui.values[0]));
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1183
            jQuery('#%(sliderid)s_sup').html(_formatter(ui.values[1]));
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1184
            jQuery('input[name=%(facetid)s_inf]').val(ui.values[0]);
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1185
            jQuery('input[name=%(facetid)s_sup]').val(ui.values[1]);
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1186
        }
1896
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1187
   });
2020
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1188
   // use JS formatter to format value on page load
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1189
   jQuery('#%(sliderid)s_inf').html(_formatter(jQuery('input[name=%(facetid)s_inf]').val()));
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1190
   jQuery('#%(sliderid)s_sup').html(_formatter(jQuery('input[name=%(facetid)s_sup]').val()));
1896
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1191
'''
2020
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1192
    #'# make emacs happier
1896
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1193
    def __init__(self, facet, minvalue, maxvalue):
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1194
        self.facet = facet
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1195
        self.minvalue = minvalue
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1196
        self.maxvalue = maxvalue
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1197
7402
826e5663a686 [facets/table] vertically group facets by two when possible in order to have a more compact horizontal layout in table filter form
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7280
diff changeset
  1198
    def height(self):
826e5663a686 [facets/table] vertically group facets by two when possible in order to have a more compact horizontal layout in table filter form
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7280
diff changeset
  1199
        return 3
826e5663a686 [facets/table] vertically group facets by two when possible in order to have a more compact horizontal layout in table filter form
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7280
diff changeset
  1200
1896
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1201
    def _render(self):
7414
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1202
        w = self.w
1896
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1203
        facet = self.facet
7233
614f23606091 [js/css] remove old versions of ui.tabs/slider etc.; closes #1625085
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7205
diff changeset
  1204
        facet._cw.add_js('jquery.ui.js')
614f23606091 [js/css] remove old versions of ui.tabs/slider etc.; closes #1625085
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7205
diff changeset
  1205
        facet._cw.add_css('jquery.ui.css')
3333
c61a526b530e [widgets] change make_uid() seed to make slider ids xhtml-valid
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3329
diff changeset
  1206
        sliderid = make_uid('theslider')
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1207
        facetid = xml_escape(self.facet.__regid__)
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1208
        facet._cw.html_headers.add_onload(self.onload % {
2020
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1209
            'sliderid': sliderid,
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1210
            'facetid': facetid,
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1211
            'minvalue': self.minvalue,
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1212
            'maxvalue': self.maxvalue,
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1213
            'formatter': self.formatter,
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1214
            })
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2305
diff changeset
  1215
        title = xml_escape(self.facet.title)
7414
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1216
        w(u'<div id="%s" class="facet">\n' % facetid)
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1217
        w(u'<div class="facetTitle" cubicweb:facetName="%s">%s</div>\n' %
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1218
          (facetid, title))
7225
a4a115aab086 [facets] make rangefacet comply with start_unfolded (closes #1615869)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7205
diff changeset
  1219
        cssclass = 'facetBody'
a4a115aab086 [facets] make rangefacet comply with start_unfolded (closes #1615869)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7205
diff changeset
  1220
        if not self.facet.start_unfolded:
a4a115aab086 [facets] make rangefacet comply with start_unfolded (closes #1615869)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7205
diff changeset
  1221
            cssclass += ' hidden'
7414
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1222
        w(u'<div class="%s">\n' % cssclass)
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1223
        w(u'<span id="%s_inf"></span> - <span id="%s_sup"></span>'
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1224
          % (sliderid, sliderid))
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1225
        w(u'<input type="hidden" name="%s_inf" value="%s" />'
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1226
          % (facetid, self.minvalue))
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1227
        w(u'<input type="hidden" name="%s_sup" value="%s" />'
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1228
          % (facetid, self.maxvalue))
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1229
        w(u'<input type="hidden" name="min_%s_inf" value="%s" />'
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1230
          % (facetid, self.minvalue))
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1231
        w(u'<input type="hidden" name="max_%s_sup" value="%s" />'
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1232
          % (facetid, self.maxvalue))
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1233
        w(u'<div id="%s"></div>' % sliderid)
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1234
        w(u'</div>\n')
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1235
        w(u'</div>\n')
1896
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1236
8182746170c6 work in progress: new 'range facet' usable for numerical values, still lacks the form.submit on mouseUp
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1433
diff changeset
  1237
2010
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
  1238
class DateFacetRangeWidget(FacetRangeWidget):
2149
6a631ec5cc71 fix date rounding issue in DateFacetRangeWidget
Florent <florent@secondweb.fr>
parents: 2130
diff changeset
  1239
2020
fe437afc8fb7 [facet] refactor values formatting in RangeFacets
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2016
diff changeset
  1240
    formatter = 'function (value) {return (new Date(parseFloat(value))).strftime(DATE_FMT);}'
2149
6a631ec5cc71 fix date rounding issue in DateFacetRangeWidget
Florent <florent@secondweb.fr>
parents: 2130
diff changeset
  1241
6a631ec5cc71 fix date rounding issue in DateFacetRangeWidget
Florent <florent@secondweb.fr>
parents: 2130
diff changeset
  1242
    def round_max_value(self, d):
6a631ec5cc71 fix date rounding issue in DateFacetRangeWidget
Florent <florent@secondweb.fr>
parents: 2130
diff changeset
  1243
        'round to upper value to avoid filtering out the max value'
2152
Florent <florent@secondweb.fr>
parents: 2149
diff changeset
  1244
        return datetime(d.year, d.month, d.day) + timedelta(days=1)
2149
6a631ec5cc71 fix date rounding issue in DateFacetRangeWidget
Florent <florent@secondweb.fr>
parents: 2130
diff changeset
  1245
2010
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
  1246
    def __init__(self, facet, minvalue, maxvalue):
2149
6a631ec5cc71 fix date rounding issue in DateFacetRangeWidget
Florent <florent@secondweb.fr>
parents: 2130
diff changeset
  1247
        maxvalue = self.round_max_value(maxvalue)
2010
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
  1248
        super(DateFacetRangeWidget, self).__init__(facet,
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
  1249
                                                   datetime2ticks(minvalue),
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
  1250
                                                   datetime2ticks(maxvalue))
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1251
        fmt = facet._cw.property_value('ui.date-format')
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1252
        facet._cw.html_headers.define_var('DATE_FMT', fmt)
2010
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
  1253
c594323929cb [facet] provide a DateRangeFacet (still need to refactor, maybe create a CWWidget)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1977
diff changeset
  1254
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1255
class FacetItem(HTMLWidget):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1256
203
60cd67acf7fd FacetItem now takes req as first parameter of __init__, THIS IS BACKWARD INCOMPATIBLE
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 0
diff changeset
  1257
    selected_img = "black-check.png"
60cd67acf7fd FacetItem now takes req as first parameter of __init__, THIS IS BACKWARD INCOMPATIBLE
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 0
diff changeset
  1258
    unselected_img = "no-check-no-border.png"
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1259
203
60cd67acf7fd FacetItem now takes req as first parameter of __init__, THIS IS BACKWARD INCOMPATIBLE
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 0
diff changeset
  1260
    def __init__(self, req, label, value, selected=False):
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1261
        self._cw = req
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1262
        self.label = label
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1263
        self.value = value
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1264
        self.selected = selected
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1265
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1266
    def _render(self):
7414
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1267
        w = self.w
7225
a4a115aab086 [facets] make rangefacet comply with start_unfolded (closes #1615869)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7205
diff changeset
  1268
        cssclass = 'facetValue facetCheckBox'
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1269
        if self.selected:
7225
a4a115aab086 [facets] make rangefacet comply with start_unfolded (closes #1615869)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7205
diff changeset
  1270
            cssclass += ' facetValueSelected'
7070
5f8e52d722c5 [web] provide a data_url() method on req and get_rid of explicit datadir_url usage (#1438736)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6681
diff changeset
  1271
            imgsrc = self._cw.data_url(self.selected_img)
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1272
            imgalt = self._cw._('selected')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1273
        else:
7070
5f8e52d722c5 [web] provide a data_url() method on req and get_rid of explicit datadir_url usage (#1438736)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6681
diff changeset
  1274
            imgsrc = self._cw.data_url(self.unselected_img)
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1275
            imgalt = self._cw._('not selected')
7414
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1276
        w(u'<div class="%s" cubicweb:value="%s">\n'
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1277
          % (cssclass, xml_escape(unicode(self.value))))
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1278
        w(u'<img src="%s" alt="%s"/>&#160;' % (imgsrc, imgalt))
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1279
        w(u'<a href="javascript: {}">%s</a>' % xml_escape(self.label))
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1280
        w(u'</div>')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1281
3329
8430f6c693a1 cleanup, smarter sort control to avoid it when not necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3328
diff changeset
  1282
2014
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1283
class CheckBoxFacetWidget(HTMLWidget):
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1284
    selected_img = "black-check.png"
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1285
    unselected_img = "black-uncheck.png"
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1286
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1287
    def __init__(self, req, facet, value, selected):
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1288
        self._cw = req
2014
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1289
        self.facet = facet
2016
a6638de6d4da [views] reindent web/facet.py
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2014
diff changeset
  1290
        self.value = value
a6638de6d4da [views] reindent web/facet.py
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2014
diff changeset
  1291
        self.selected = selected
2014
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1292
7402
826e5663a686 [facets/table] vertically group facets by two when possible in order to have a more compact horizontal layout in table filter form
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7280
diff changeset
  1293
    def height(self):
7413
94ad9523abb7 [web/facet|views/table] bump a bit some heights, split table view methods for easier subclassing
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7402
diff changeset
  1294
        return 2
7402
826e5663a686 [facets/table] vertically group facets by two when possible in order to have a more compact horizontal layout in table filter form
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7280
diff changeset
  1295
2014
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1296
    def _render(self):
7414
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1297
        w = self.w
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2305
diff changeset
  1298
        title = xml_escape(self.facet.title)
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1299
        facetid = xml_escape(self.facet.__regid__)
7414
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1300
        w(u'<div id="%s" class="facet">\n' % facetid)
7225
a4a115aab086 [facets] make rangefacet comply with start_unfolded (closes #1615869)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7205
diff changeset
  1301
        cssclass = 'facetValue facetCheckBox'
2016
a6638de6d4da [views] reindent web/facet.py
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2014
diff changeset
  1302
        if self.selected:
7225
a4a115aab086 [facets] make rangefacet comply with start_unfolded (closes #1615869)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7205
diff changeset
  1303
            cssclass += ' facetValueSelected'
7070
5f8e52d722c5 [web] provide a data_url() method on req and get_rid of explicit datadir_url usage (#1438736)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6681
diff changeset
  1304
            imgsrc = self._cw.data_url(self.selected_img)
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1305
            imgalt = self._cw._('selected')
2014
71a9ab77d9f8 [facet] provide hasRelationFacet (backport from CMHN)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2010
diff changeset
  1306
        else:
7070
5f8e52d722c5 [web] provide a data_url() method on req and get_rid of explicit datadir_url usage (#1438736)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6681
diff changeset
  1307
            imgsrc = self._cw.data_url(self.unselected_img)
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
  1308
            imgalt = self._cw._('not selected')
7414
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1309
        w(u'<div class="%s" cubicweb:value="%s">\n'
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1310
          % (cssclass, xml_escape(unicode(self.value))))
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1311
        w(u'<div class="facetCheckBoxWidget">')
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1312
        w(u'<img src="%s" alt="%s" cubicweb:unselimg="true" />&#160;' % (imgsrc, imgalt))
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1313
        w(u'<label class="facetTitle" cubicweb:facetName="%s"><a href="javascript: {}">%s</a></label>' % (facetid, title))
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1314
        w(u'</div>\n')
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1315
        w(u'</div>\n')
de802bcb6348 [web.facet] self.w -> w
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7413
diff changeset
  1316
        w(u'</div>\n')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1317
3329
8430f6c693a1 cleanup, smarter sort control to avoid it when not necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3328
diff changeset
  1318
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1319
class FacetSeparator(HTMLWidget):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1320
    def __init__(self, label=None):
2996
866a2c135c33 B #345282 xhtml requires to use &#160; instead of &nbsp;
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2658
diff changeset
  1321
        self.label = label or u'&#160;'
467
a6f056bc7d1d [facets] AttributeFacet can now declare which kind of comparator they want to use, default is '=' (+ tidy trailing white spaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 446
diff changeset
  1322
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1323
    def _render(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1324
        pass
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1325
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1326
# other classes ################################################################
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1327
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1328
class FilterRQLBuilder(object):
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1329
    """called by javascript to get a rql string from filter form"""
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1330
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1331
    def __init__(self, req):
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1332
        self._cw = req
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1333
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
  1334
    def build_rql(self):
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1335
        form = self._cw.form
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1336
        facetids = form['facets'].split(',')
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1337
        # XXX Union unsupported yet
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1338
        select = self._cw.vreg.parse(self._cw, form['baserql']).children[0]
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
  1339
        filtered_variable = get_filtered_variable(select, form.get('mainvar'))
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1340
        toupdate = []
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1341
        for facetid in facetids:
7605
48abeac162fd [facets] refactor / cleanup facet api: more consistent variable naming and easier to reuse function. Closes #1796804
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7604
diff changeset
  1342
            facet = get_facet(self._cw, facetid, select, filtered_variable)
6120
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1343
            facet.add_rql_restrictions()
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1344
            if facet.needs_update:
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1345
                toupdate.append(facetid)
c000e41316ec [book] some more documentation and cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6119
diff changeset
  1346
        return select.as_string(), toupdate