Index: /waeup/branches/ulif-rewrite/src/waeup/widgets/table.py
===================================================================
--- /waeup/branches/ulif-rewrite/src/waeup/widgets/table.py	(revision 4404)
+++ /waeup/branches/ulif-rewrite/src/waeup/widgets/table.py	(revision 4404)
@@ -0,0 +1,151 @@
+"""Table widget.
+"""
+import grok
+from grok.interfaces import IGrokSecurityView
+from hurry import yui
+from zope.interface import Interface
+from waeup.widgets.interfaces import ITableProvider
+
+def varName(string):
+    varname = string.lower()
+    return ''.join([x for x in varname
+                    if x in 'abcdefghijklmnopqrstuvwxyz_0123456789'])
+
+class Col(object):
+    """A column in a table.
+    """
+    header = 'Unnamed'
+    type = None
+    sortable = False
+    width = 100
+
+    def __init__(self, header=u'Unnamed', width=None, sortable=False,
+                 type=None, data=()):
+        self.header = header
+        self.width = width
+        self.sortable = sortable
+        self.type = type
+        self.data = data
+        self.key = varName(header)
+    
+class Table(object):
+    """A table.
+    """
+    def __init__(self, title=u'Unnamed', width=500, height=180, cols=()):
+        self.title = title
+        self.cols = cols
+        self.width = width
+        self.height = height
+        self.internal_title = varName(title)
+
+    def renderHTML(self):
+        result = '<div id="%s-tablecontainer"><table id="%s-table">' % (
+            self.internal_title, self.internal_title)
+        data_rows = self.getRows()
+        result += '<thead><tr>'
+        for col in self.cols:
+            result += '<th>%s</th>' % (col.header,)
+        result += '</tr></thead>\n'
+        result += '<tbody>'
+            
+        for row in data_rows:
+            result += '<tr>\n  '
+            for elem in row:
+                result += '<td>%s</td>' % elem
+            result += '\n</tr>'
+        result += '</tbody></table></div>'
+        return result
+
+    def castValue(self, value, type):
+        return value
+        if type == 'int':
+            return str(value)
+        return "'%s'" % value
+    
+    def castRow(self, row):
+        """Lookup type of each column and cast values to strings usable in JS
+        code.
+        """
+        result = []
+        for num, value in enumerate(row):
+            type = self.cols[num].type
+            result.append(self.castValue(value, type))
+        return result
+
+    def getRows(self):
+        data_cols = (x.data for x in self.cols)
+        # turn rows into cols and vice versa:
+        # ((a, 1, p), (b, 2, q)) --> ((a, b), (1, 2), (p, q))
+        data_rows = tuple(map(lambda *x: (x), *data_cols))
+        return data_rows
+
+
+class YUITable(Table):
+    """A table that can generate JavaScript code for use with YUI.
+    """
+    def need(self):
+        yui.paginator.need()
+        yui.datatable.need()
+        yui.sam.need()
+        yui.fonts.need()
+
+    def getJSTableCode(self, paginator=True):
+        title = self.internal_title
+        fielddefs = ",".join(['{key:"%s"}'%x.key for x in self.cols])
+        coldefs = ",".join([
+                '{key:"%s",label:"%s",sortable:%s}' % (
+                    x.key, x.header, str(x.sortable).lower())
+                for x in self.cols
+                ])
+        result = """
+YAHOO.util.Event.addListener(window, "load", function() {
+  var %sDataSource = new YAHOO.util.DataSource(YAHOO.util.Dom.get("%s-table"));
+  %sDataSource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
+  %sDataSource.responseSchema = {
+    fields: [%s]
+  };
+
+  var %sColDefs = [%s];
+  var %sDataTable = new YAHOO.widget.DataTable("%s-tablecontainer",
+                                               %sColDefs, %sDataSource,
+                                               {
+paginator: new YAHOO.widget.Paginator({ 
+	                rowsPerPage: 15, 
+	                template: YAHOO.widget.Paginator.TEMPLATE_ROWS_PER_PAGE, 
+	                rowsPerPageOptions: [10,15,30,50,100], 
+	                pageLinks: 5 
+	            }), 
+draggableColumns:true });
+});
+""" % (
+            title, title, title, title, fielddefs, title, coldefs,
+            title, title, title, title)
+        return result
+
+
+    
+class YUIStaticTable(grok.View):
+    grok.context(Interface)
+    grok.name('yuistatictables.js')
+    grok.implements(IGrokSecurityView)
+
+    def render(self):
+        try:
+            provider = ITableProvider(self.context)
+        except:
+            # Couldn't find a table provider for the context. Okay, if
+            # the context is a view, we try to lookup the context of
+            # the context...
+            if hasattr(self.context, 'context'):
+                try:
+                    print self.context.context
+                    provider = ITableProvider(self.context.context)
+                except:
+                    return ''
+            else:
+                return ''
+        self.response.setHeader('Content-Type',
+                                'text/javascript; charset=UTF-8')
+        table = provider.getTable()
+        result = table.getJSTableCode()
+        return result
