Author: justi9
Date: 2008-10-08 11:46:34 -0400 (Wed, 08 Oct 2008)
New Revision: 2606
Added:
mgmt/trunk/cumin/python/cumin/modelwidgets.py
mgmt/trunk/cumin/python/cumin/modelwidgets.strings
Modified:
mgmt/trunk/cumin/python/cumin/brokergroup.py
mgmt/trunk/cumin/python/cumin/brokergroup.strings
mgmt/trunk/cumin/python/cumin/model.py
mgmt/trunk/cumin/python/cumin/page.py
mgmt/trunk/cumin/python/cumin/parameters.py
mgmt/trunk/cumin/python/cumin/widgets.py
mgmt/trunk/cumin/python/cumin/widgets.strings
mgmt/trunk/cumin/python/wooly/__init__.py
mgmt/trunk/cumin/python/wooly/forms.py
mgmt/trunk/cumin/python/wooly/forms.strings
mgmt/trunk/cumin/python/wooly/tables.py
mgmt/trunk/cumin/python/wooly/widgets.py
mgmt/trunk/cumin/python/wooly/widgets.strings
Log:
First step toward model driven table views, to avoid the present
duplication of table view code, and to achieve more uniform
presentation.
* Introduces modelwidgets.py to cumin, a set of standard model-driven
widgets.
* Add a CuminSetAction to cumin model, for describing actions on sets
of objects
* Switch BrokerGroupSet over to the new model widget for tables
* Add group set remove functionality
Other:
* Add a CuminTableWithControls, which renders a CuminTable with
filters and switches included
* Remove field set in favor of putting that functionality directly in
field form
* Adds a SqlTableFilter class to wooly tables.py
* Added an html_class attr to Widget, to set the value returned by
render_class
* Added a WidgetSet widget, which by default produces an unordered
list of its children
Modified: mgmt/trunk/cumin/python/cumin/brokergroup.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/brokergroup.py 2008-10-08 13:28:37 UTC (rev 2605)
+++ mgmt/trunk/cumin/python/cumin/brokergroup.py 2008-10-08 15:46:34 UTC (rev 2606)
@@ -4,42 +4,24 @@
from wooly.forms import *
from broker import BrokerSet
+from model import *
from widgets import *
+from modelwidgets import *
from parameters import *
from formats import *
from util import *
strings = StringCatalog(__file__)
-class BrokerGroupSet(CuminTable):
+class BrokerGroupSet(CuminClassTable):
def __init__(self, app, name):
- super(BrokerGroupSet, self).__init__(app, name)
+ cls = app.model.broker_group
- col = self.NameColumn(app, "name")
+ super(BrokerGroupSet, self).__init__(app, name, cls)
+
+ col = CuminClassNameColumn(app, "name", cls)
self.add_column(col)
- #col = self.StatusColumn(app, "status")
- #self.add_column(col)
-
- def render_title(self, session):
- return "Broker Groups %s" % fmt_count(BrokerGroup.select().count())
-
- def render_group_add_href(self, session):
- branch = session.branch()
- self.frame.show_broker_group(branch, None).show_add(branch)
- return branch.marshal()
-
- class NameColumn(SqlTableColumn):
- def render_title(self, session, data):
- return "Name"
-
- def render_content(self, session, data):
- group = Identifiable(data["id"])
- branch = session.branch()
- frame = self.app.model.broker_group.show_object(branch, group)
- frame = frame.show_view(branch)
- return fmt_olink(branch, group, name=data["name"])
-
class BrokerGroupInputSet(CheckboxInputSet):
def __init__(self, app, name):
super(BrokerGroupInputSet, self).__init__(app, name, None)
Modified: mgmt/trunk/cumin/python/cumin/brokergroup.strings
===================================================================
--- mgmt/trunk/cumin/python/cumin/brokergroup.strings 2008-10-08 13:28:37 UTC (rev 2605)
+++ mgmt/trunk/cumin/python/cumin/brokergroup.strings 2008-10-08 15:46:34 UTC (rev 2606)
@@ -6,21 +6,3 @@
[BrokerGroupSet.count_sql]
select count(*) from broker_group
-
-[BrokerGroupSet.html]
-<ul class="actions">
- <li><a class="nav" href="{group_add_href}">Add Broker
Group</a></li>
-</ul>
-
-<table class="mobjects">
- <thead>
- <tr>
- <th class="setnav" colspan="0">
- <div class="rfloat">{page}</div>
- {count}
- </th>
- </tr>
- <tr>{headers}</tr>
- </thead>
- <tbody>{items}</tbody>
-</table>
Modified: mgmt/trunk/cumin/python/cumin/model.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/model.py 2008-10-08 13:28:37 UTC (rev 2605)
+++ mgmt/trunk/cumin/python/cumin/model.py 2008-10-08 15:46:34 UTC (rev 2606)
@@ -1,3 +1,4 @@
+import logging
from mint.schema import *
from wooly import *
from wooly.parameters import *
@@ -5,7 +6,6 @@
from time import *
from datetime import datetime, timedelta
from types import *
-from logging import getLogger
from struct import unpack
from util import *
@@ -13,7 +13,7 @@
from parameters import *
from job import *
-log = getLogger("cumin.model")
+log = logging.getLogger("cumin.model")
class CuminModel(object):
def __init__(self, app, data_uri, spec_path):
@@ -24,7 +24,7 @@
self.invocations = set()
# Messaging
-
+
CuminBroker(self)
CuminQueue(self)
CuminExchange(self)
@@ -173,6 +173,7 @@
self.title = None
self.summary = False
self.navigable = True
+ self.aggregate = False
self.cumin_class.add_action(self)
@@ -190,7 +191,13 @@
return self.title
else:
return self.name
-
+
+ def get_summary(self, session, object):
+ pred0 = self.get_title(session)
+ pred1 = self.cumin_class.get_object_title(session, object)
+
+ return "%s %s" % (pred0, pred1)
+
def get_enabled(self, session, object):
return True
@@ -232,7 +239,6 @@
return conn.mconn.session(str(uuid4()))
-
class CuminActionInvocation(object):
def __init__(self, action, object):
self.action = action
@@ -258,6 +264,18 @@
print "action", self.action.name, self.object, self.when, \
self.status, self.args, self.exception
+class CuminSetAction(CuminAction):
+ def __init__(self, cls, name):
+ super(CuminSetAction, self).__init__(cls, name)
+
+ self.aggregate = True
+
+ def get_summary(self, session, object):
+ pred0 = self.get_title(session)
+ pred1 = self.cumin_class.get_plural_title(session)
+
+ return "%s %s" % (pred0, pred1)
+
class CuminStat(object):
def __init__(self, cls, name):
self.cumin_model = cls.cumin_model
@@ -405,14 +423,20 @@
def get_title(self, session):
return "Object"
+ def get_plural_title(self, session):
+ return self.get_title(session) + "s"
+
def get_icon_href(self, session):
return "resource?name=action-36.png"
def get_object_href(self, session, object):
branch = session.branch()
- self.show_object(branch, object)
+ self.show_object(branch, object).show_view(branch)
return branch.marshal()
+ def get_object_href_by_id(self, session, id):
+ return self.get_object_href(session, Identifiable(id))
+
def show_object(self, session, object):
raise Exception("Not implemented")
@@ -1505,6 +1529,11 @@
super(CuminBrokerGroup, self).__init__ \
(model, "broker_group", BrokerGroup)
+ self.add.title = "Add Group"
+
+ action = self.RemoveSet(self, "remove_set")
+ action.title = "Remove"
+
def show_object(self, session, group):
frame = self.cumin_model.show_main(session)
return frame.show_broker_group(session, group)
@@ -1515,6 +1544,18 @@
def get_icon_href(self, session):
return "resource?name=group-36.png"
+ class RemoveSet(CuminSetAction):
+ def show(self, session, groups):
+ frame = self.cumin_model.show_main(session)
+ return frame.show_broker_groups_remove(session, groups)
+
+ def do_invoke(self, groups, args, completion):
+ for group in groups:
+ group.destroySelf()
+ group.syncUpdate()
+
+ completion("yo!")
+
class CuminPool(CuminClass):
def __init__(self, model):
super(CuminPool, self).__init__ \
@@ -2137,7 +2178,7 @@
class CuminNegotiator(RemoteClass):
def __init__(self, model):
super(CuminNegotiator, self).__init__(model, "negotiator",
- Negotiator, NegotiatorStats)
+ Negotiator, NegotiatorStats)
prop = CuminProperty(self, "Name")
prop.title = "Name"
@@ -2215,7 +2256,7 @@
def do_invoke(self, negotiator, args, completion):
negotiator.Stop(self.cumin_model.data, completion)
-
+
class GetLimitCount(CuminAction):
def __init__(self, cls, name):
super(CuminNegotiator.GetLimitCount, self).__init__(cls, name)
Added: mgmt/trunk/cumin/python/cumin/modelwidgets.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/modelwidgets.py (rev 0)
+++ mgmt/trunk/cumin/python/cumin/modelwidgets.py 2008-10-08 15:46:34 UTC (rev 2606)
@@ -0,0 +1,179 @@
+from wooly import *
+from wooly.forms import *
+
+from model import *
+from widgets import *
+from util import *
+
+from wooly.widgets import Link
+
+strings = StringCatalog(__file__)
+
+class CuminActionButton(FormButton):
+ def __init__(self, app, name, action, object=None):
+ super(CuminActionButton, self).__init__(app, name)
+
+ self.action = action
+ self.object = object
+
+ def process_submit(self, session, *args):
+ branch = session.branch()
+ object = None
+
+ if self.object:
+ object = self.object.get(session)
+
+ self.action.show(branch, object)
+
+ self.page.set_redirect_url(session, branch.marshal())
+
+ def render_content(self, session, *args):
+ return self.action.get_title(session)
+
+class CuminActionLink(Link):
+ def __init__(self, app, name, action, object=None):
+ super(CuminActionLink, self).__init__(app, name)
+
+ self.action = action
+ self.object = object
+
+ def edit_session(self, session, *args):
+ object = None
+
+ if self.object:
+ object = self.object.get(session)
+
+ self.action.show(session, object)
+
+ def render_content(self, session, *args):
+ return self.action.get_title(session)
+
+class CuminActionForm(CuminFieldForm):
+ def __init__(self, app, name, action, object=None):
+ super(CuminActionForm, self).__init__(app, name)
+
+ self.action = action
+ self.object = object
+
+ def render_title(self, session, *args):
+ return self.action.get_summary(session, self.object.get(session))
+
+ def process_submit(self, session, *args):
+ object = None
+
+ if self.object:
+ object = self.object.get(session)
+
+ self.action.invoke(object)
+
+ self.process_cancel(session, *args)
+
+class CuminSetActionForm(CuminForm):
+ def __init__(self, app, name, action, object):
+ super(CuminSetActionForm, self).__init__(app, name)
+
+ assert isinstance(action, CuminAction)
+ assert action.aggregate
+ assert isinstance(object, Parameter)
+
+ self.action = action
+
+ self.objects = ListParameter(app, "param", object)
+ self.add_parameter(self.objects)
+
+ body = self.SetActionBody(app, "body")
+ self.add_child(body)
+
+ def render_title(self, session, *args):
+ return self.action.get_summary(session, self.objects.get(session))
+
+ def process_submit(self, session, *args):
+ self.action.invoke(self.objects.get(session))
+
+ self.process_cancel(session, *args)
+
+ class SetActionBody(ItemSet):
+ def render_message(self, session, *args):
+ verb = self.parent.action.get_title(session)
+ noun = self.parent.action.cumin_class.get_plural_title(session)
+
+ return "%s the following %s" % (verb, noun)
+
+ def do_get_items(self, session, *args):
+ return self.parent.objects.get(session)
+
+ def render_item_content(self, session, item):
+ cls = self.parent.action.cumin_class
+ return cls.get_object_title(session, item)
+
+class CuminClassTable(CuminTableWithControls, Form):
+ def __init__(self, app, name, cumin_class):
+ super(CuminClassTable, self).__init__(app, name)
+
+ self.cumin_class = cumin_class
+
+ self.selection = CuminClassCheckboxColumn(app, "id", self.cumin_class)
+ self.add_column(self.selection)
+
+ self.actions = WidgetSet(app, "actions")
+ self.actions.html_class = "actions"
+ self.add_child(self.actions)
+
+ actions = [x for x in self.cumin_class.actions if x.aggregate]
+
+ for action in actions:
+ button = CuminActionButton \
+ (app, action.name, action, self.selection.param)
+ self.actions.add_child(button)
+
+ self.add = None
+
+ if hasattr(self.cumin_class, "add"):
+ self.add = CuminActionLink(app, "add", self.cumin_class.add)
+ self.add.html_class = "action"
+ self.add_child(self.add)
+
+ def render_title(self, session, *args):
+ title = self.cumin_class.get_plural_title(session)
+ count = fmt_count(self.cumin_class.mint_class.select().count())
+
+ return "%s %s" % (title, count)
+
+ def render_plural_title(self, session, *args):
+ return self.cumin_class.get_plural_title(session)
+
+ def render_add_link(self, session, *args):
+ if self.add:
+ return self.add.render(session, *args)
+
+ def render_actions(self, session, *args):
+ if self.actions.children:
+ return self.actions.render(session, *args)
+
+class CuminClassCheckboxColumn(CheckboxInputColumn):
+ def __init__(self, app, name, cumin_class):
+ item = CuminObjectParameter(app, "item", cumin_class)
+
+ super(CuminClassCheckboxColumn, self).__init__(app, name, item)
+
+ self.cumin_class = cumin_class
+
+class CuminClassNameColumn(SqlTableColumn):
+ def __init__(self, app, name, cumin_class):
+ super(CuminClassNameColumn, self).__init__(app, name)
+
+ self.cumin_class = cumin_class
+
+ self.id_column = "id"
+ self.name_column = "name"
+
+ def render_title(self, session, data):
+ return "Name"
+
+ def render_content(self, session, data):
+ id = data[self.id_column]
+ name = data[self.name_column]
+
+ href = self.cumin_class.get_object_href_by_id(session, id)
+
+ return fmt_link(href, name)
Added: mgmt/trunk/cumin/python/cumin/modelwidgets.strings
===================================================================
--- mgmt/trunk/cumin/python/cumin/modelwidgets.strings (rev 0)
+++ mgmt/trunk/cumin/python/cumin/modelwidgets.strings 2008-10-08 15:46:34 UTC (rev 2606)
@@ -0,0 +1,43 @@
+[SetActionBody.html]
+<h2>{message}</h2>
+<ul>{items}</ul>
+
+[CuminClassTable.css]
+.CuminClassTable div.addlink {
+ margin: 0 0 1em 0;
+}
+
+.CuminClassTable ul.actions {
+ margin: 0;
+ display: inline;
+}
+
+.CuminClassTable ul.actions li {
+ display: inline;
+}
+
+[CuminClassTable.html]
+<form class="CuminClassTable" id="{id}" method="post"
action="?">
+ <div class="addlink">{add_link}</div>
+
+ {switches}
+
+ {filters}
+
+ <div class="sactions">Act on Selected {plural_title}:
{actions}</div>
+
+ <table class="mobjects">
+ <thead>
+ <tr>
+ <th class="setnav" colspan="{column_count}">
+ <div class="rfloat">{page}</div>
+ {count}
+ </th>
+ </tr>
+ <tr>{headers}</tr>
+ </thead>
+ <tbody>{items}</tbody>
+ </table>
+
+ <div>{hidden_inputs}</div>
+</form>
Modified: mgmt/trunk/cumin/python/cumin/page.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/page.py 2008-10-08 13:28:37 UTC (rev 2605)
+++ mgmt/trunk/cumin/python/cumin/page.py 2008-10-08 15:46:34 UTC (rev 2606)
@@ -65,6 +65,12 @@
self.__group = BrokerGroupFrame(app, "group")
self.add_mode(self.__group)
+ action = self.app.model.broker_group.remove_set
+ item = BrokerGroupParameter(app, "item")
+ self.__groups_remove = CuminSetActionForm \
+ (app, "groupsremove", action, item)
+ self.add_mode(self.__groups_remove)
+
self.__profile = BrokerProfileFrame(app, "profile")
self.add_mode(self.__profile)
@@ -144,6 +150,11 @@
frame.set_object(session, group)
return self.page.set_current_frame(session, frame)
+ def show_broker_groups_remove(self, session, groups):
+ frame = self.show_mode(session, self.__groups_remove)
+ frame.objects.set(session, groups)
+ return self.page.set_current_frame(session, frame)
+
def show_broker_profile(self, session, profile):
frame = self.show_mode(session, self.__profile)
frame.set_object(session, profile)
Modified: mgmt/trunk/cumin/python/cumin/parameters.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/parameters.py 2008-10-08 13:28:37 UTC (rev 2605)
+++ mgmt/trunk/cumin/python/cumin/parameters.py 2008-10-08 15:46:34 UTC (rev 2606)
@@ -1,6 +1,16 @@
from wooly import *
from mint import *
+class CuminObjectParameter(Parameter):
+ def __init__(self, app, name, cumin_class):
+ self.cumin_class = cumin_class
+
+ def do_unmarshal(self, string):
+ return self.cumin_class.mint_class.get(int(string))
+
+ def do_marshal(self, object):
+ return str(object.id)
+
class CuminClassParameter(Parameter):
def do_unmarshal(self, string):
return getattr(self.app.model, string, None)
Modified: mgmt/trunk/cumin/python/cumin/widgets.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/widgets.py 2008-10-08 13:28:37 UTC (rev 2605)
+++ mgmt/trunk/cumin/python/cumin/widgets.py 2008-10-08 15:46:34 UTC (rev 2606)
@@ -204,6 +204,9 @@
def render_submit_content(self, session, *args):
return "Submit"
+ def render_form_error(self, session, *args):
+ pass
+
class Cancel(FormButton):
def render_class(self, session, *args):
return "cancel"
@@ -225,9 +228,9 @@
return "resource?name=help.html#%s" % self.path
class CuminFieldForm(CuminForm, FieldForm, Frame):
- def render_form_error(self, session, *args):
- pass
-
+ def render_body(self, session, *args):
+ return self.render_fields(session, *args)
+
class CuminConfirmForm(CuminForm):
def __init__(self, app, name):
super(CuminConfirmForm, self).__init__(app, name)
@@ -453,8 +456,10 @@
def do_get_items(self, session, object):
cls = self.app.model.get_class_by_object(object)
- return [(x.get_href(session, object), x.get_title(session),
x.get_enabled(session, object))
- for x in cls.actions if x.navigable]
+ return [(x.get_href(session, object),
+ x.get_title(session),
+ x.get_enabled(session, object))
+ for x in cls.actions if x.navigable and not x.aggregate]
class CuminDetails(Widget):
def __init__(self, app, name):
@@ -617,6 +622,43 @@
start, end = self.paginator.get_bounds(session)
return "limit %i offset %i" % (end - start, start)
+class CuminTableWithControls(CuminTable):
+ def __init__(self, app, name):
+ super(CuminTableWithControls, self).__init__(app, name)
+
+ self.switches = WidgetSet(app, "switches")
+ self.switches.html_class = "switches"
+ self.add_child(self.switches)
+
+ self.filters = WidgetSet(app, "filters")
+ self.filters.html_class = "filters"
+ self.add_child(self.filters)
+
+ def get_sql_constraint(self, session, *args):
+ pass
+
+ def render_switches(self, session, *args):
+ if self.switches.children:
+ return self.switches.render(session, *args)
+
+ def render_filters(self, session, *args):
+ if self.filters.children:
+ return self.filters.render(session, *args)
+
+ def render_sql_where(self, session, *args):
+ constraints = list()
+
+ for filter in self.filters.children:
+ if filter:
+ constraints.append(filter.get_sql_constraint(session, *args))
+
+ constraint = self.get_sql_constraint(session, *args)
+
+ if constraint:
+ constraints.append(constraint)
+
+ return "where %s" % " and ".join(constraints)
+
class NullSortColumn(SqlTableColumn):
def get_orderby_sql(self, session):
key = self.get_column_key(session)
@@ -755,6 +797,24 @@
binding = Binding.get(data["id"])
return self.app.model.binding.msgMatched.value(binding)
+class CheckboxInputColumn(FormInput, ItemTableColumn):
+ def __init__(self, app, name, item_param):
+ super(CheckboxInputColumn, self).__init__(app, name, None)
+
+ self.header_class = CheckboxIdColumnHeader
+
+ self.param = ListParameter(app, "param", item_param)
+ self.add_parameter(self.param)
+
+ def do_render(self, session, data):
+ name = self.param.path
+ id = data[self.name]
+ attr = id in self.param.get(session) and
"checked=\"checked\"" or ""
+ html = "<td><input type=\"checkbox\"
name=\"%s\" " + \
+ "value=\"%i\" %s/></td>"
+
+ return html % (name, id, attr)
+
class CheckboxIdColumn(FormInput, SqlTableColumn):
def __init__(self, app, name):
super(CheckboxIdColumn, self).__init__(app, name, None)
Modified: mgmt/trunk/cumin/python/cumin/widgets.strings
===================================================================
--- mgmt/trunk/cumin/python/cumin/widgets.strings 2008-10-08 13:28:37 UTC (rev 2605)
+++ mgmt/trunk/cumin/python/cumin/widgets.strings 2008-10-08 15:46:34 UTC (rev 2606)
@@ -551,13 +551,13 @@
{tabs}
-[CuminFieldForm.html]
+[CuminForm.html]
<form id="{id}" class="mform" method="post"
action="?">
<div class="head">{title}</div>
- <div class="body">{fields}</div>
+ <div class="body">{body}</div>
{form_error}
<div class="foot">
- {help}
+ {help}
{submit}
{cancel}
</div>
@@ -907,6 +907,29 @@
<tbody>{items}</tbody>
</table>
+[CuminTableWithControls.html]
+<div class="CuminTable">
+ {switches}
+
+ {filters}
+
+ <table class="mobjects">
+ <thead>
+ <tr>
+ <th class="setnav" colspan="{column_count}">
+ <div class="rfloat">{page}</div>
+
+ {count}
+ </th>
+ </tr>
+
+ <tr>{headers}</tr>
+ </thead>
+
+ <tbody>{items}</tbody>
+ </table>
+</div>
+
[TableHeader.css]
th.selected a {
color: black;
Modified: mgmt/trunk/cumin/python/wooly/__init__.py
===================================================================
--- mgmt/trunk/cumin/python/wooly/__init__.py 2008-10-08 13:28:37 UTC (rev 2605)
+++ mgmt/trunk/cumin/python/wooly/__init__.py 2008-10-08 15:46:34 UTC (rev 2606)
@@ -108,6 +108,8 @@
if cls is Widget:
break
+ self.html_class = "_"
+
self.sealed = False
def init(self):
@@ -246,7 +248,7 @@
return self.path
def render_class(self, session, *args):
- return "noclass"
+ return self.html_class
def render_href(self, session, *args):
return session.marshal()
Modified: mgmt/trunk/cumin/python/wooly/forms.py
===================================================================
--- mgmt/trunk/cumin/python/wooly/forms.py 2008-10-08 13:28:37 UTC (rev 2605)
+++ mgmt/trunk/cumin/python/wooly/forms.py 2008-10-08 15:46:34 UTC (rev 2606)
@@ -112,7 +112,9 @@
def init(self):
super(FormInput, self).init()
- assert self.param is not None
+ if self.param is None:
+ raise Exception("Parameter not set for %s" % self)
+
assert isinstance(self.param, Parameter)
for anc in self.ancestors:
@@ -263,26 +265,6 @@
def render_item_selected_attr(self, session, item):
return None
-class FieldSet(Widget):
- def __init__(self, app, name):
- super(FieldSet, self).__init__(app, name)
-
- self.fields = list()
-
- def add_field(self, field):
- assert isinstance(field, FormField)
-
- self.fields.append(field)
- self.add_child(field)
-
- def render_fields(self, session, *args):
- writer = Writer()
-
- for field in self.fields:
- writer.write(field.render(session))
-
- return writer.to_string()
-
class FormField(Widget):
def __init__(self, app, name):
super(FormField, self).__init__(app, name)
@@ -395,10 +377,18 @@
return writer.to_string()
-class FieldForm(Form, FieldSet):
+class FieldForm(Form):
def __init__(self, app, name):
super(FieldForm, self).__init__(app, name)
+ self.fields = list()
+
+ def add_field(self, field):
+ assert isinstance(field, FormField)
+
+ self.fields.append(field)
+ self.add_child(field)
+
def validate(self, session):
errors = list()
@@ -406,3 +396,11 @@
errors.extend(field.validate(session))
return errors
+
+ def render_fields(self, session, *args):
+ writer = Writer()
+
+ for field in self.fields:
+ writer.write(field.render(session))
+
+ return writer.to_string()
Modified: mgmt/trunk/cumin/python/wooly/forms.strings
===================================================================
--- mgmt/trunk/cumin/python/wooly/forms.strings 2008-10-08 13:28:37 UTC (rev 2605)
+++ mgmt/trunk/cumin/python/wooly/forms.strings 2008-10-08 15:46:34 UTC (rev 2606)
@@ -49,12 +49,6 @@
[OptionInputSet.item_html]
<option value="{item_value}"
{item_selected_attr}>{item_content}</option>
-[FieldSet.html]
-<div class="fieldset">
- <div class="title">{title}</div>
- <div class="fields">{fields}</div>
-</div>
-
[FormField.css]
div.field {
padding: 0;
@@ -84,9 +78,3 @@
tabindex="{tab_index}" {checked_attr} {disabled_attr}/>
<label for="{id}">{title}</label>
</div>
-
-[FieldForm.html]
-<form id="{id}">
- {fields}
- <div>{hidden_inputs}</div>
-</form>
Modified: mgmt/trunk/cumin/python/wooly/tables.py
===================================================================
--- mgmt/trunk/cumin/python/wooly/tables.py 2008-10-08 13:28:37 UTC (rev 2605)
+++ mgmt/trunk/cumin/python/wooly/tables.py 2008-10-08 15:46:34 UTC (rev 2606)
@@ -128,7 +128,7 @@
def render_value(self, session, value):
return str(value)
- # in case a non-sql column is included in an sqltable
+ # in case a non-sql column is included in an sqltable # XXX ugh
def get_orderby_sql(self, session):
pass
@@ -259,6 +259,9 @@
return writer.to_string()
class SqlTableColumn(ItemTableColumn):
+ # XXX to be consistent with similar methods, rename to
+ # get_sql_order_by
+
def get_orderby_sql(self, session):
key = self.get_column_key(session)
@@ -266,7 +269,6 @@
dir = self.parent.is_reversed(session) and "desc" or
"asc"
return "order by %s %s" % (key, dir)
-class CheckboxColumn(SqlTableColumn):
- def do_render(self, session, data):
- return "<td><input type=\"checkbox\"
name=\"%s\"/></td>" % \
- data[self.name]
+class SqlTableFilter(Widget):
+ def get_sql_constraint(self, session, *args):
+ pass
Modified: mgmt/trunk/cumin/python/wooly/widgets.py
===================================================================
--- mgmt/trunk/cumin/python/wooly/widgets.py 2008-10-08 13:28:37 UTC (rev 2605)
+++ mgmt/trunk/cumin/python/wooly/widgets.py 2008-10-08 15:46:34 UTC (rev 2606)
@@ -81,6 +81,25 @@
args = tab.get_args(session)
return tab.render_title(session, *args)
+class WidgetSet(Widget):
+ def __init__(self, app, name):
+ super(WidgetSet, self).__init__(app, name)
+
+ self.__widget_tmpl = Template(self, "widget_html")
+
+ def render_widgets(self, session, *args):
+ writer = Writer()
+
+ for widget in self.children:
+ self.__widget_tmpl.render(writer, session, widget)
+
+ return writer.to_string()
+
+ def render_widget(self, session, widget):
+ return widget.render(session)
+
+# XXX get rid of this, now that we have the slightly more general
+# WidgetSet
class LinkSet(Widget):
def __init__(self, app, name):
super(LinkSet, self).__init__(app, name)
@@ -459,4 +478,4 @@
t += "&" + name + ";"
else:
t += i
- return t
\ No newline at end of file
+ return t
Modified: mgmt/trunk/cumin/python/wooly/widgets.strings
===================================================================
--- mgmt/trunk/cumin/python/wooly/widgets.strings 2008-10-08 13:28:37 UTC (rev 2605)
+++ mgmt/trunk/cumin/python/wooly/widgets.strings 2008-10-08 15:46:34 UTC (rev 2606)
@@ -49,6 +49,12 @@
[TabbedModeSet.tab_html]
<li><a href="{tab_href}"
{tab_class}>{tab_content}</a></li>
+[WidgetSet.html]
+<ul class="{class}">{widgets}</ul>
+
+[WidgetSet.widget_html]
+<li>{widget}</li>
+
[LinkSet.html]
<ul class="{class}">{links}</ul>