Commit fca499c4 authored by Jean-Paul Smets's avatar Jean-Paul Smets

Added large comments and implemented list rendering


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@1257 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent f3eb09bf
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
############################################################################## ##############################################################################
import string, types, sys import string, types, sys
from AccessControl import ClassSecurityInfo
from Products.Formulator.DummyField import fields from Products.Formulator.DummyField import fields
from Products.Formulator import Widget, Validator from Products.Formulator import Widget, Validator
from Products.Formulator.Field import ZMIField from Products.Formulator.Field import ZMIField
...@@ -317,13 +318,17 @@ class ListBoxWidget(Widget.Widget): ...@@ -317,13 +318,17 @@ class ListBoxWidget(Widget.Widget):
default='', default='',
required=1) required=1)
def render(self, field, key, value, REQUEST): def render(self, field, key, value, REQUEST, render_format='html'):
""" """
This is where most things happen. This method renders a list This is where most things happen. This method renders a list
of items of items
""" """
# First grasp the variables we may need ###############################################################
#
# First, grasp and intialize the variables we may need later
#
###############################################################
here = REQUEST['here'] here = REQUEST['here']
reset = REQUEST.get('reset', 0) reset = REQUEST.get('reset', 0)
form = field.aq_parent form = field.aq_parent
...@@ -480,10 +485,15 @@ class ListBoxWidget(Widget.Widget): ...@@ -480,10 +485,15 @@ class ListBoxWidget(Widget.Widget):
params['meta_type'] = filtered_meta_types params['meta_type'] = filtered_meta_types
params['portal_type'] = filtered_portal_types params['portal_type'] = filtered_portal_types
###############################################################
#
# Build the columns selections # Build the columns selections
#
# The idea is: instead of selecting *, listbox is able to # The idea is: instead of selecting *, listbox is able to
# provide what should be selected. This should allow to reduce # provide what should be selected. This should allow to reduce
# the quantity of data transfered between MySQL and Zope # the quantity of data transfered between MySQL and Zope
#
###############################################################
extended_columns = [] extended_columns = []
sql_columns = [] sql_columns = []
for (sql, title) in columns: for (sql, title) in columns:
...@@ -505,7 +515,12 @@ class ListBoxWidget(Widget.Widget): ...@@ -505,7 +515,12 @@ class ListBoxWidget(Widget.Widget):
sql_columns_string = string.join(sql_columns,' , ') sql_columns_string = string.join(sql_columns,' , ')
params['select_columns'] = sql_columns_string params['select_columns'] = sql_columns_string
###############################################################
#
# Execute the query # Execute the query
#
###############################################################
kw = params kw = params
# XXX Remove selection_expression if present. # XXX Remove selection_expression if present.
...@@ -593,10 +608,16 @@ class ListBoxWidget(Widget.Widget): ...@@ -593,10 +608,16 @@ class ListBoxWidget(Widget.Widget):
#LOG('ListBox', 0, 'list_method = %s, list_method.__dict__ = %s' % (repr(list_method), repr((list_method.__dict__)))) #LOG('ListBox', 0, 'list_method = %s, list_method.__dict__ = %s' % (repr(list_method), repr((list_method.__dict__))))
# When we build the body, we have to go through ###############################################################
# All report lines #
# This is made as a list of tuples # Build the report tree
#
# When we build the body, we have to go through all report lines
#
# Each report line is a tuple of the form:
# (section_id, object_list, object_list_size, is_summary) # (section_id, object_list, object_list_size, is_summary)
#
###############################################################
report_query = '' report_query = ''
if report_tree: if report_tree:
original_query = kw.get('query') original_query = kw.get('query')
...@@ -658,7 +679,7 @@ class ListBoxWidget(Widget.Widget): ...@@ -658,7 +679,7 @@ class ListBoxWidget(Widget.Widget):
else: else:
# If list_method is None, use already selected values. # If list_method is None, use already selected values.
object_list = here.portal_selections.getSelectionValueList(selection_name, context=here, REQUEST=REQUEST) object_list = here.portal_selections.getSelectionValueList(selection_name, context=here, REQUEST=REQUEST)
# PERFORMANCE # # PERFORMANCE ? is len(object_list) fast enough ?
report_sections += [ (None, 0, s[2], object_list, len(object_list), s[3]) ] report_sections += [ (None, 0, s[2], object_list, len(object_list), s[3]) ]
if original_query is not None: if original_query is not None:
kw['query'] = original_query kw['query'] = original_query
...@@ -673,50 +694,73 @@ class ListBoxWidget(Widget.Widget): ...@@ -673,50 +694,73 @@ class ListBoxWidget(Widget.Widget):
else: else:
# If list_method is None, use already selected values. # If list_method is None, use already selected values.
object_list = here.portal_selections.getSelectionValueList(selection_name, context=here, REQUEST=REQUEST) object_list = here.portal_selections.getSelectionValueList(selection_name, context=here, REQUEST=REQUEST)
# PERFORMANCE # PERFORMANCE PROBLEM ? is len(object_list) fast enough ?
report_sections = ( (None, 0, 0, object_list, len(object_list), 0), ) report_sections = ( (None, 0, 0, object_list, len(object_list), 0), )
object_uid_list = map(lambda x: getattr(x, 'uid', None), object_list)
#LOG('ListBox.render, object_uid_list:',0,object_uid_list) ###############################################################
# Then construct the md5 corresponding this uid list #
# Build an md5 signature of the selection
#
# It is calculated based on the selection uid list
# It is used in order to do some checks in scripts. # It is used in order to do some checks in scripts.
# For example, if we do delete objects, then we do have a list of # For example, if we do delete objects, then we do have a list of
# objects to delete, but it is possible that on another tab the selection # objects to delete, but it is possible that on another tab the selection
# change, and then when we confirm the deletion, we don't delete what # change, and then when we confirm the deletion, we don't delete what
# we want, so this is really dangerous. with this md5 we can check if the # we want, so this is really dangerous. with this md5 we can check if the
# selection is the same # selection is the same
#
###############################################################
object_uid_list = map(lambda x: getattr(x, 'uid', None), object_list)
#LOG('ListBox.render, object_uid_list:',0,object_uid_list)
sorted_object_uid_list = copy(object_uid_list) sorted_object_uid_list = copy(object_uid_list)
sorted_object_uid_list.sort() sorted_object_uid_list.sort()
md5_string = md5.new(str(sorted_object_uid_list)).hexdigest() md5_string = md5.new(str(sorted_object_uid_list)).hexdigest()
#md5_string = md5.new(str(object_uid_list)).digest() #md5_string = md5.new(str(object_uid_list)).digest()
#LOG("Selection", 0, str(selection.__dict__)) ###############################################################
#
# Calculate list start and stop
#
# Build the real list by slicing it # Build the real list by slicing it
# PERFORMANCE ANALYSIS: the result of the query should be # PERFORMANCE ANALYSIS: the result of the query should be
# if possible a lazy sequence # if possible a lazy sequence
#
###############################################################
#LOG("Selection", 0, str(selection.__dict__))
total_size = 0 total_size = 0
for s in report_sections: for s in report_sections:
total_size += s[4] total_size += s[4]
try: if render_format == 'list':
start = REQUEST.get('list_start') start = 0
start = int(start) end = total_size
except: else:
start = params.get('list_start',0) try:
start = int(start) start = REQUEST.get('list_start')
end = min(start + lines, total_size) start = int(start)
#object_list = object_list[start:end] except:
total_pages = int(max(total_size-1,0) / lines) + 1 start = params.get('list_start',0)
current_page = int(start / lines) start = int(start)
start = max(start, 0) end = min(start + lines, total_size)
start = min(start, max(0, total_pages * lines - lines) ) #object_list = object_list[start:end]
kw['list_start'] = start total_pages = int(max(total_size-1,0) / lines) + 1
kw['list_lines'] = lines current_page = int(start / lines)
start = max(start, 0)
# Store the resulting selection if list_method is not None start = min(start, max(0, total_pages * lines - lines) )
if list_method is not None: kw['list_start'] = start
kw['list_lines'] = lines
###############################################################
#
# Store new selection values
#
# Store the resulting selection if list_method is not None and render_format is not list
#
###############################################################
if list_method is not None and render_format != 'list':
try: try:
method_path = getPath(here) + '/' + list_method.method_name method_path = getPath(here) + '/' + list_method.method_name
#LOG('ListBox', 0, 'method_path = %s, getPath = %s, list_method.method_name = %s' % (repr(method_path), repr(getPath(here)), repr(list_method.method_name))) #LOG('ListBox', 0, 'method_path = %s, getPath = %s, list_method.method_name = %s' % (repr(method_path), repr(getPath(here)), repr(list_method.method_name)))
...@@ -731,6 +775,12 @@ class ListBoxWidget(Widget.Widget): ...@@ -731,6 +775,12 @@ class ListBoxWidget(Widget.Widget):
#LOG("Selection kw", 0, str(selection.selection_params)) #LOG("Selection kw", 0, str(selection.selection_params))
here.portal_selections.setSelectionFor(selection_name, selection, REQUEST=REQUEST) here.portal_selections.setSelectionFor(selection_name, selection, REQUEST=REQUEST)
###############################################################
#
# Build HTML header and footer
#
###############################################################
# Provide the selection name # Provide the selection name
selection_line = """\ selection_line = """\
<input type="hidden" name="list_selection_name" value="%s" /> <input type="hidden" name="list_selection_name" value="%s" />
...@@ -937,9 +987,22 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')"> ...@@ -937,9 +987,22 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')">
list_search = list_search + "</tr>" list_search = list_search + "</tr>"
else: else:
list_search = '' list_search = ''
# Build the tuple of columns
if render_format == 'list':
c_name_list = []
for cname in columns:
c_name_list.append(cname[1])
###############################################################
#
# Build lines
#
###############################################################
# Build Lines # Build Lines
list_body = '' list_body = ''
if render_format == 'list': list_result = [c_name_list] # Create initial list for list render format
section_index = 0 section_index = 0
current_section_base_index = 0 current_section_base_index = 0
current_section = report_sections[section_index] current_section = report_sections[section_index]
...@@ -1002,6 +1065,7 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')"> ...@@ -1002,6 +1065,7 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')">
<input type="checkbox" %s value="%s" id="cb_%s" name="uids:list"/></td> <input type="checkbox" %s value="%s" id="cb_%s" name="uids:list"/></td>
""" % (td_css, selected, o.uid , o.uid) """ % (td_css, selected, o.uid , o.uid)
error_list = [] error_list = []
if render_format == 'list': list_result_item = [] # Start a new item for list render format
for cname in extended_columns: for cname in extended_columns:
sql = cname[0] # (sql, title, alias) sql = cname[0] # (sql, title, alias)
alias = cname[2] # (sql, title, alias) alias = cname[2] # (sql, title, alias)
...@@ -1090,6 +1154,9 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')"> ...@@ -1090,6 +1154,9 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')">
# This prevents from using standard display process # This prevents from using standard display process
list_body = list_body + \ list_body = list_body + \
('<td class=\"%s%s\">%s%s</td>' % (td_css, error_css, cell_body, error_message)) ('<td class=\"%s%s\">%s%s</td>' % (td_css, error_css, cell_body, error_message))
# Add item to list_result_item for list render format
if render_format == 'list':
list_result_item.append(my_field._get_default(self.generate_field_key(), display_value, o))
else: else:
# Check if this object provides a specific URL method # Check if this object provides a specific URL method
url_method = getattr(o, 'getListItemUrl', None) url_method = getattr(o, 'getListItemUrl', None)
...@@ -1112,11 +1179,20 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')"> ...@@ -1112,11 +1179,20 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')">
except: except:
list_body = list_body + \ list_body = list_body + \
("<td class=\"%s\" align=\"%s\">%s</td>" % (td_css, td_align, attribute_value) ) ("<td class=\"%s\" align=\"%s\">%s</td>" % (td_css, td_align, attribute_value) )
# Add item to list_result_item for list render format
if render_format == 'list': list_result_item.append(attribute_value)
list_body = list_body + '</tr>' list_body = list_body + '</tr>'
if render_format == 'list':
list_result.append(list_result_item)
# Call the stat_method
###############################################################
#
# Build statistics
#
###############################################################
# Call the stat method
if show_stat: if show_stat:
stats = here.portal_selections.getSelectionStats(selection_name, REQUEST=REQUEST) stats = here.portal_selections.getSelectionStats(selection_name, REQUEST=REQUEST)
select_expression = '' select_expression = ''
...@@ -1146,6 +1222,7 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')"> ...@@ -1146,6 +1222,7 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')">
count_results = selection(selection_method = stat_method, count_results = selection(selection_method = stat_method,
context=here, REQUEST=REQUEST) context=here, REQUEST=REQUEST)
list_body = list_body + '<tr>' list_body = list_body + '<tr>'
if render_format == 'list': list_result_item = []
if report_tree: if report_tree:
list_body += '<td class="Data">&nbsp;</td>' list_body += '<td class="Data">&nbsp;</td>'
if select: if select:
...@@ -1178,16 +1255,23 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')"> ...@@ -1178,16 +1255,23 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')">
list_body += '<td class="Data" align="right">%.2f</td>' % value list_body += '<td class="Data" align="right">%.2f</td>' % value
else: else:
list_body += '<td class="Data">' + str(value) + '</td>' list_body += '<td class="Data">' + str(value) + '</td>'
if render_format == 'list': list_result_item.append(value)
else: else:
list_body += '<td class="Data">&nbsp;</td>' list_body += '<td class="Data">&nbsp;</td>'
if render_format == 'list': list_result_item.append(None)
except: except:
list_body += '<td class="Data">&nbsp;</td>' list_body += '<td class="Data">&nbsp;</td>'
if render_format == 'list': list_result_item.append(None)
list_body += '</tr>' list_body += '</tr>'
list_html = header + selection_line + list_header + list_search + list_body + footer list_html = header + selection_line + list_header + list_search + list_body + footer
# Return list of brains here is render_as_list = 1
if render_format == 'list':
list_result.append(list_result_item)
return list_result
#Create DomainTree Selector and DomainTree box #Create DomainTree Selector and DomainTree box
if domain_tree: if domain_tree:
select_tree_options = '' select_tree_options = ''
for c in domain_root_list: for c in domain_root_list:
...@@ -1407,7 +1491,15 @@ class ListBox(ZMIField): ...@@ -1407,7 +1491,15 @@ class ListBox(ZMIField):
widget = ListBoxWidgetInstance widget = ListBoxWidgetInstance
validator = ListBoxValidatorInstance validator = ListBoxValidatorInstance
security = ClassSecurityInfo()
security.declareProtected('Access contents information', 'get_value')
def get_value(self, id, **kw):
if id == 'default' and kw.get('render_format') in ('list', ):
return self.widget.render(self, self.generate_field_key() , None , kw.get('REQUEST'), render_format=render_format)
else:
ZMIField.get_value(self, id, **kw)
# Psyco # Psyco
import psyco import psyco
psyco.bind(ListBoxWidget.render) psyco.bind(ListBoxWidget.render)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment