view.py
brancholdstable
changeset 8123 a4e667270dd4
parent 8011 23552e79316f
child 8013 7b2b8a7fb96d
equal deleted inserted replaced
7863:d8bb8f631d41 8123:a4e667270dd4
     1 # copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
     1 # copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
     2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
     2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
     3 #
     3 #
     4 # This file is part of CubicWeb.
     4 # This file is part of CubicWeb.
     5 #
     5 #
     6 # CubicWeb is free software: you can redistribute it and/or modify it under the
     6 # CubicWeb is free software: you can redistribute it and/or modify it under the
    21 _ = unicode
    21 _ = unicode
    22 
    22 
    23 import types, new
    23 import types, new
    24 from cStringIO import StringIO
    24 from cStringIO import StringIO
    25 from warnings import warn
    25 from warnings import warn
       
    26 from functools import partial
    26 
    27 
    27 from logilab.common.deprecation import deprecated
    28 from logilab.common.deprecation import deprecated
    28 from logilab.mtconverter import xml_escape
    29 from logilab.mtconverter import xml_escape
    29 
    30 
    30 from rql import nodes
    31 from rql import nodes
   172         else:
   173         else:
   173             view_func = self.call
   174             view_func = self.call
   174         stream = self.set_stream(w)
   175         stream = self.set_stream(w)
   175         try:
   176         try:
   176             view_func(**context)
   177             view_func(**context)
   177         except:
   178         except Exception:
   178             self.debug('view call %s failed (context=%s)', view_func, context)
   179             self.debug('view call %s failed (context=%s)', view_func, context)
   179             raise
   180             raise
   180         # return stream content if we have created it
   181         # return stream content if we have created it
   181         if stream is not None:
   182         if stream is not None:
   182             return self._stream.getvalue()
   183             return self._stream.getvalue()
   373     __select__ = non_final_entity()
   374     __select__ = non_final_entity()
   374     category = _('entityview')
   375     category = _('entityview')
   375 
   376 
   376     def call(self, **kwargs):
   377     def call(self, **kwargs):
   377         if self.cw_rset is None:
   378         if self.cw_rset is None:
   378             self.entity_call(self.cw_extra_kwargs.pop('entity'))
   379             # * cw_extra_kwargs is the place where extra selection arguments are
       
   380             #   stored
       
   381             # * when calling req.view('somevid', entity=entity), 'entity' ends
       
   382             #   up in cw_extra_kwargs and kwargs
       
   383             #
       
   384             # handle that to avoid a TypeError with a sanity check
       
   385             #
       
   386             # Notice that could probably be avoided by handling entity_call in
       
   387             # .render
       
   388             entity = self.cw_extra_kwargs.pop('entity')
       
   389             if 'entity' in kwargs:
       
   390                 assert kwargs.pop('entity') is entity
       
   391             self.entity_call(entity, **kwargs)
   379         else:
   392         else:
   380             super(EntityView, self).call(**kwargs)
   393             super(EntityView, self).call(**kwargs)
   381 
   394 
   382     def cell_call(self, row, col, **kwargs):
   395     def cell_call(self, row, col, **kwargs):
   383         self.entity_call(self.cw_rset.get_entity(row, col), **kwargs)
   396         self.entity_call(self.cw_rset.get_entity(row, col), **kwargs)
   437     __select__ = nonempty_rset()
   450     __select__ = nonempty_rset()
   438 
   451 
   439     category = _('anyrsetview')
   452     category = _('anyrsetview')
   440 
   453 
   441     def columns_labels(self, mainindex=0, tr=True):
   454     def columns_labels(self, mainindex=0, tr=True):
       
   455         """compute the label of the rset colums
       
   456 
       
   457         The logic is based on :meth:`~rql.stmts.Union.get_description`.
       
   458 
       
   459         :param mainindex: The index of the main variable. This is an hint to get
       
   460                           more accurate label for various situation
       
   461         :type mainindex:  int
       
   462 
       
   463         :param tr: Should the label be translated ?
       
   464         :type tr: boolean
       
   465         """
   442         if tr:
   466         if tr:
   443             translate = lambda val, req=self._cw: display_name(req, val)
   467             translate = partial(display_name, self._cw)
   444         else:
   468         else:
   445             translate = lambda val: val
   469             translate = lambda val, *args,**kwargs: val
   446         # XXX [0] because of missing Union support
   470         # XXX [0] because of missing Union support
   447         rqlstdescr = self.cw_rset.syntax_tree().get_description(mainindex,
   471         rql_syntax_tree = self.cw_rset.syntax_tree()
   448                                                                 translate)[0]
   472         rqlstdescr = rql_syntax_tree.get_description(mainindex, translate)[0]
   449         labels = []
   473         labels = []
   450         for colidx, label in enumerate(rqlstdescr):
   474         for colidx, label in enumerate(rqlstdescr):
   451             try:
   475             labels.append(self.column_label(colidx, label, translate))
   452                 label = getattr(self, 'label_column_%s' % colidx)()
       
   453             except AttributeError:
       
   454                 # compute column header
       
   455                 if label == 'Any': # find a better label
       
   456                     label = ','.join(translate(et)
       
   457                                      for et in self.cw_rset.column_types(colidx))
       
   458             labels.append(label)
       
   459         return labels
   476         return labels
       
   477 
       
   478     def column_label(self, colidx, default, translate_func=None):
       
   479         """return the label of a specified columns index
       
   480 
       
   481         Overwrite me if you need to compute specific label.
       
   482 
       
   483         :param colidx: The index of the column the call computes a label for.
       
   484         :type colidx:  int
       
   485 
       
   486         :param default: Default value. If ``"Any"`` the default value will be
       
   487                         recomputed as coma separated list for all possible
       
   488                         etypes name.
       
   489         :type colidx:  string
       
   490 
       
   491         :param translate_func: A function used to translate name.
       
   492         :type colidx:  function
       
   493         """
       
   494         label = default
       
   495         if label == 'Any':
       
   496             etypes = self.cw_rset.column_types(colidx)
       
   497             if translate_func is not None:
       
   498                 etypes = map(translate_func, etypes)
       
   499             label = u','.join(etypes)
       
   500         return label
       
   501 
   460 
   502 
   461 
   503 
   462 # concrete template base classes ##############################################
   504 # concrete template base classes ##############################################
   463 
   505 
   464 class MainTemplate(View):
   506 class MainTemplate(View):