web/views/pyviews.py
changeset 7992 4ff9f25cb06e
parent 7903 ac658ab4c7b7
child 8190 2a3c1b787688
--- a/web/views/pyviews.py	Fri Oct 21 14:32:37 2011 +0200
+++ b/web/views/pyviews.py	Fri Oct 21 14:32:37 2011 +0200
@@ -21,18 +21,38 @@
 
 from cubicweb.view import View
 from cubicweb.selectors import match_kwargs
+from cubicweb.web.views import tableview
 
 
-class PyValTableView(View):
-    """display a list of list of values into an HTML table.
+class PyValTableColRenderer(tableview.AbstractColumnRenderer):
+    """Default column renderer for :class:`PyValTableView`."""
+    def bind(self, view, colid):
+        super(PyValTableColRenderer, self).bind(view, colid)
+        self.header = view.headers[colid] if view.headers else None
+        self.data = view.pyvalue
+
+    def render_header(self, w):
+        if self.header:
+            w(self._cw._(self.header))
+        else:
+            w(self.empty_cell_content)
 
-    Take care, content is NOT xml-escaped.
+    def render_cell(self, w, rownum):
+        w(unicode(self.data[rownum][self.colid]))
+
 
-    If `headers` is specfied, it is expected to be a list of headers to be
+class PyValTableView(tableview.TableMixIn, View):
+    """This table view is designed to be used a list of list of unicode values
+    given as a mandatory `pyvalue` argument. Take care, content is NOT
+    xml-escaped.
+
+    It's configured through the following selection arguments.
+
+    If `headers` is specified, it is expected to be a list of headers to be
     inserted as first row (in <thead>).
 
-    If `colheaders` is True, the first column will be considered as an headers
-    column an its values will be inserted inside <th> instead of <td>.
+    `header_column_idx` may be used to specify a column index or a set of column
+    indiced where values should be inserted inside <th> tag instead of <td>.
 
     `cssclass` is the CSS class used on the <table> tag, and default to
     'listing' (so that the table will look similar to those generated by the
@@ -40,31 +60,53 @@
     """
     __regid__ = 'pyvaltable'
     __select__ = match_kwargs('pyvalue')
+    default_column_renderer_class = PyValTableColRenderer
+    paginable = False # not supported
+    headers = None
+    cssclass = None
+    domid = None
 
-    def call(self, pyvalue, headers=None, colheaders=False,
-             cssclass='listing'):
-        if headers is None:
-            headers = self._cw.form.get('headers')
-        w = self.w
-        w(u'<table class="%s">\n' % cssclass)
-        if headers:
-            w(u'<thead>')
-            w(u'<tr>')
-            for header in headers:
-                w(u'<th>%s</th>' % header)
-            w(u'</tr>\n')
-            w(u'</thead>')
-        w(u'<tbody>')
-        for row in pyvalue:
-            w(u'<tr>')
-            if colheaders:
-                w(u'<th>%s</th>' % row[0])
-                row = row[1:]
-            for cell in row:
-                w(u'<td>%s</td>' % cell)
-            w(u'</tr>\n')
-        w(u'</tbody>')
-        w(u'</table>\n')
+    def __init__(self, req, pyvalue, headers=None, cssclass=None,
+                 header_column_idx=None, **kwargs):
+        super(PyValTableView, self).__init__(req, **kwargs)
+        self.pyvalue = pyvalue
+        if headers is not None:
+            self.headers = headers
+        elif self.headers: # headers set on a class attribute, translate
+            self.headers = [self._cw._(header) for header in self.headers]
+        if cssclass is not None:
+            self.cssclass = cssclass
+        self.header_column_idx = header_column_idx
+
+    @property
+    def layout_args(self):
+        args = {}
+        if self.cssclass:
+            args['cssclass'] = self.cssclass
+        if self.header_column_idx is not None:
+            args['header_column_idx'] = self.header_column_idx
+        return args
+
+    # layout callbacks #########################################################
+
+    @property
+    def table_size(self):
+        """return the number of rows (header excluded) to be displayed"""
+        return len(self.pyvalue)
+
+    @property
+    def has_headers(self):
+        return self.headers
+
+    def build_column_renderers(self):
+        return [self.column_renderer(colid)
+                for colid in xrange(len(self.pyvalue[0]))]
+
+    def facets_form(self, mainvar=None):
+        return None # not supported
+
+    def table_actions(self):
+        return [] # not supported
 
 
 class PyValListView(View):