From fca499c4ba0d9f582fdbc6770ba67bf27586b01b Mon Sep 17 00:00:00 2001 From: Jean-Paul Smets <jp@nexedi.com> Date: Tue, 20 Jul 2004 08:35:23 +0000 Subject: [PATCH] Added large comments and implemented list rendering git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@1257 20353a03-c40f-0410-a6d1-a30d3c3de9de --- product/ERP5Form/ListBox.py | 166 ++++++++++++++++++++++++++++-------- 1 file changed, 129 insertions(+), 37 deletions(-) diff --git a/product/ERP5Form/ListBox.py b/product/ERP5Form/ListBox.py index b414d30d1a..7c20aa431d 100755 --- a/product/ERP5Form/ListBox.py +++ b/product/ERP5Form/ListBox.py @@ -27,6 +27,7 @@ ############################################################################## import string, types, sys +from AccessControl import ClassSecurityInfo from Products.Formulator.DummyField import fields from Products.Formulator import Widget, Validator from Products.Formulator.Field import ZMIField @@ -317,13 +318,17 @@ class ListBoxWidget(Widget.Widget): default='', 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 of items """ - # First grasp the variables we may need - + ############################################################### + # + # First, grasp and intialize the variables we may need later + # + ############################################################### + here = REQUEST['here'] reset = REQUEST.get('reset', 0) form = field.aq_parent @@ -480,10 +485,15 @@ class ListBoxWidget(Widget.Widget): params['meta_type'] = filtered_meta_types params['portal_type'] = filtered_portal_types + ############################################################### + # # Build the columns selections + # # The idea is: instead of selecting *, listbox is able to # provide what should be selected. This should allow to reduce # the quantity of data transfered between MySQL and Zope + # + ############################################################### extended_columns = [] sql_columns = [] for (sql, title) in columns: @@ -505,7 +515,12 @@ class ListBoxWidget(Widget.Widget): sql_columns_string = string.join(sql_columns,' , ') params['select_columns'] = sql_columns_string + ############################################################### + # # Execute the query + # + ############################################################### + kw = params # XXX Remove selection_expression if present. @@ -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__)))) - # 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) + # + ############################################################### report_query = '' if report_tree: original_query = kw.get('query') @@ -658,7 +679,7 @@ class ListBoxWidget(Widget.Widget): else: # If list_method is None, use already selected values. 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]) ] if original_query is not None: kw['query'] = original_query @@ -673,50 +694,73 @@ class ListBoxWidget(Widget.Widget): else: # If list_method is None, use already selected values. 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), ) - 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. # 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 # 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 # 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.sort() md5_string = md5.new(str(sorted_object_uid_list)).hexdigest() #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 # PERFORMANCE ANALYSIS: the result of the query should be # if possible a lazy sequence - + # + ############################################################### + + #LOG("Selection", 0, str(selection.__dict__)) total_size = 0 for s in report_sections: total_size += s[4] - try: - start = REQUEST.get('list_start') - start = int(start) - except: - start = params.get('list_start',0) - start = int(start) - end = min(start + lines, total_size) - #object_list = object_list[start:end] - total_pages = int(max(total_size-1,0) / lines) + 1 - current_page = int(start / lines) - start = max(start, 0) - start = min(start, max(0, total_pages * lines - lines) ) - kw['list_start'] = start - kw['list_lines'] = lines - - # Store the resulting selection if list_method is not None - if list_method is not None: + if render_format == 'list': + start = 0 + end = total_size + else: + try: + start = REQUEST.get('list_start') + start = int(start) + except: + start = params.get('list_start',0) + start = int(start) + end = min(start + lines, total_size) + #object_list = object_list[start:end] + total_pages = int(max(total_size-1,0) / lines) + 1 + current_page = int(start / lines) + start = max(start, 0) + start = min(start, max(0, total_pages * lines - lines) ) + 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: 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))) @@ -731,6 +775,12 @@ class ListBoxWidget(Widget.Widget): #LOG("Selection kw", 0, str(selection.selection_params)) here.portal_selections.setSelectionFor(selection_name, selection, REQUEST=REQUEST) + ############################################################### + # + # Build HTML header and footer + # + ############################################################### + # Provide the selection name selection_line = """\ <input type="hidden" name="list_selection_name" value="%s" /> @@ -937,9 +987,22 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')"> list_search = list_search + "</tr>" else: 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 list_body = '' + if render_format == 'list': list_result = [c_name_list] # Create initial list for list render format section_index = 0 current_section_base_index = 0 current_section = report_sections[section_index] @@ -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> """ % (td_css, selected, o.uid , o.uid) error_list = [] + if render_format == 'list': list_result_item = [] # Start a new item for list render format for cname in extended_columns: sql = cname[0] # (sql, title, alias) alias = cname[2] # (sql, title, alias) @@ -1090,6 +1154,9 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')"> # This prevents from using standard display process list_body = list_body + \ ('<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: # Check if this object provides a specific URL method url_method = getattr(o, 'getListItemUrl', None) @@ -1112,11 +1179,20 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')"> except: list_body = list_body + \ ("<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>' - - - # Call the stat_method + if render_format == 'list': + list_result.append(list_result_item) + + ############################################################### + # + # Build statistics + # + ############################################################### + + # Call the stat method if show_stat: stats = here.portal_selections.getSelectionStats(selection_name, REQUEST=REQUEST) select_expression = '' @@ -1146,6 +1222,7 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')"> count_results = selection(selection_method = stat_method, context=here, REQUEST=REQUEST) list_body = list_body + '<tr>' + if render_format == 'list': list_result_item = [] if report_tree: list_body += '<td class="Data"> </td>' if select: @@ -1178,16 +1255,23 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')"> list_body += '<td class="Data" align="right">%.2f</td>' % value else: list_body += '<td class="Data">' + str(value) + '</td>' + if render_format == 'list': list_result_item.append(value) else: list_body += '<td class="Data"> </td>' + if render_format == 'list': list_result_item.append(None) except: list_body += '<td class="Data"> </td>' + if render_format == 'list': list_result_item.append(None) list_body += '</tr>' 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 - if domain_tree: select_tree_options = '' for c in domain_root_list: @@ -1407,7 +1491,15 @@ class ListBox(ZMIField): widget = ListBoxWidgetInstance 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 import psyco psyco.bind(ListBoxWidget.render) -- 2.30.9