From bed5bbba5f39956333b6e4b5527f4633226fc8dd Mon Sep 17 00:00:00 2001 From: Romain Courteaud <romain@nexedi.com> Date: Fri, 7 Jan 2005 11:36:29 +0000 Subject: [PATCH] Add the class ListboxLine to simplify the list render mode of ListBox git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@2175 20353a03-c40f-0410-a6d1-a30d3c3de9de --- product/ERP5Form/ListBox.py | 441 ++++++++++++++++++++++++++++++++---- 1 file changed, 400 insertions(+), 41 deletions(-) diff --git a/product/ERP5Form/ListBox.py b/product/ERP5Form/ListBox.py index 7a6f69871b..4e74e46772 100755 --- a/product/ERP5Form/ListBox.py +++ b/product/ERP5Form/ListBox.py @@ -44,6 +44,9 @@ from copy import copy from Acquisition import aq_base, aq_inner, aq_parent, aq_self from zLOG import LOG +from Globals import InitializeClass, Persistent, Acquisition +from Products.PythonScripts.Utility import allow_class + import random import md5 @@ -478,6 +481,10 @@ class ListBoxWidget(Widget.Widget): # Make sure list_result_item is defined list_result_item = [] + if render_format == 'list': + # initialize the result + listboxline_list = [] + # Make sure that the title is not UTF-8. field_title = unicode(field_title, 'utf-8') @@ -1210,8 +1217,10 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')"> # Build the tuple of columns if render_format == 'list': c_name_list = [] + c_property_id_list = [] for cname in columns: c_name_list.append(cname[1]) + c_property_id_list.append(cname[0]) ############################################################### # @@ -1219,16 +1228,19 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')"> # ############################################################### - if render_format == 'list': - current_section_category_max_depth = max([x[2] for x in report_sections]) # Build Lines list_body = '' + + if render_format == 'list': - if report_tree: - list_result =[( [''] * (current_section_category_max_depth+1) ) + [x.encode('utf-8') for x in c_name_list]] - else: - list_result = [[x.encode('utf-8') for x in c_name_list]] # Create initial list for list render format + # initialize the title line + title_listboxline = ListBoxLine() + title_listboxline.markTitleLine() + for cname in columns: + title_listboxline.addColumn( cname[0].encode('utf-8'), cname[1].encode('utf-8')) + listboxline_list.append(title_listboxline) + section_index = 0 current_section_base_index = 0 if len(report_sections) > section_index: @@ -1242,6 +1254,13 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')"> object_list = current_section[3] #if current_section is not None: for i in range(start,end): + + if render_format == 'list': + # Create a ListBoxLine object + current_listboxline = ListBoxLine() + current_listboxline.markDataLine() + + # Set the selection index. selection.edit(index = i) @@ -1276,28 +1295,44 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')"> section_name = current_section[0] else: section_name = '' + if current_section[5]: if section_name != '': section_char = '-' list_body = list_body + \ """<td class="%s" align="left" valign="middle"><a href="portal_selections/foldReport?report_url=%s&form_id=%s&list_selection_name=%s">%s%s%s</a></td> """ % (td_css, getattr(current_section[3][0],'domain_url',''), form.id, selection_name, ' ' * current_section[2], section_char, section_name) + if render_format == 'list': - list_category_item = (current_section_category_max_depth+1) * [''] - if section_name != '': - list_category_item[current_section[2]] = '-'+section_name - list_result_item += [x.encode('utf-8') for x in list_category_item] + + if is_summary: + current_listboxline.markSummaryLine() + # XXX temporary correction (I dont some '' which havent signification) + if section_name == '': + section_name = None + + current_listboxline.setSectionDepth( current_section[2]+1 ) + current_listboxline.setSectionName( section_name ) + current_listboxline.setSectionFolded( 0 ) + else: if section_name != '': section_char = '+' list_body = list_body + \ """<td class="%s" align="left" valign="middle"><a href="portal_selections/unfoldReport?report_url=%s&form_id=%s&list_selection_name=%s">%s%s%s</a></td> """ % (td_css, getattr(current_section[3][0],'domain_url',''), form.id, selection_name, ' ' * current_section[2], section_char, section_name) + if render_format == 'list': - list_category_item = (current_section_category_max_depth+1) * [''] - if section_name != '': - list_category_item[current_section[2]] = '+'+section_name - list_result_item += [x.encode('utf-8') for x in list_category_item] + + if is_summary: + current_listboxline.markSummaryLine() + # XXX temporary correction (I dont some '' which havent signification) + if section_name == '': + section_name = None + + current_listboxline.setSectionDepth( current_section[2]+1 ) + current_listboxline.setSectionName( section_name ) + current_listboxline.setSectionFolded( 1 ) if select: if o.uid in checked_uids: @@ -1314,7 +1349,20 @@ 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': + if selected == '': + current_listboxline.setObjectUid( o.uid ) + current_listboxline.checkLine( 0 ) + else: + current_listboxline.setObjectUid( o.uid ) + current_listboxline.checkLine( 1 ) + for cname in extended_columns: + # add attribute_original_value, because I need to know the type of the attribute + attribute_original_value = None + sql = cname[0] # (sql, title, alias) alias = cname[2] # (sql, title, alias) if '.' in sql: @@ -1335,6 +1383,7 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')"> real_o = o.getObject() field_kw = {'cell':real_o} attribute_value = my_field.__of__(real_o).get_value('default',**field_kw) + attribute_original_value = attribute_value else: # Prepare stat_column is this is a summary if is_summary: @@ -1347,8 +1396,10 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')"> if hasattr(aq_self(o),alias) and (not is_summary or stat_column is None or stat_column[0] == stat_column[1]): # Block acquisition to reduce risks # First take the indexed value attribute_value = getattr(o,alias) # We may need acquisition in case of method call + attribute_original_value = attribute_value elif is_summary: attribute_value = getattr(here, stat_column[1]) + attribute_original_value = attribute_value #LOG('ListBox', 0, 'column = %s, value = %s' % (repr(column), repr(value))) if callable(attribute_value): try: @@ -1359,6 +1410,7 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')"> params = dict(kw) selection.edit(params=params) attribute_value=attribute_value(selection=selection) + attribute_original_value = attribute_value # reset report and closed_summary if report_tree == 1 : selection.edit(report=None) @@ -1380,36 +1432,48 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')"> try: try: attribute_value = getattr(real_o,property_id, None) + attribute_original_value = attribute_value #LOG('Look up attribute %s' % cname_id,0,str(attribute_value)) if not callable(attribute_value): #LOG('Look up accessor %s' % cname_id,0,'') attribute_value = real_o.getProperty(property_id) + attribute_original_value = attribute_value + #LOG('Look up accessor %s' % cname_id,0,str(attribute_value)) except: attribute_value = getattr(real_o,property_id) + attribute_original_value = attribute_value #LOG('Fallback to attribute %s' % cname_id,0,str(attribute_value)) except: attribute_value = 'Can not evaluate attribute: %s' % sql + attribute_original_value = None else: attribute_value = 'Object does not exist' + attribute_original_value = None if callable(attribute_value): try: try: attribute_value = attribute_value(brain = o, selection = selection) + attribute_original_value = attribute_value except TypeError: attribute_value = attribute_value() + attribute_original_value = attribute_value except: LOG('ListBox', 0, 'Could not evaluate', error=sys.exc_info()) attribute_value = "Could not evaluate" + attribute_original_value = None #LOG('ListBox', 0, 'o = %s' % repr(dir(o))) if type(attribute_value) is type(0.0): + attribute_original_value = attribute_value if sql in editable_column_ids and form.has_field('%s_%s' % (field.id, alias) ): # Do not truncate if editable pass else: + #attribute_original_value = attribute_value attribute_value = "%.2f" % attribute_value td_align = "right" elif type(attribute_value) is type(1): + attribute_original_value = attribute_value td_align = "right" else: td_align = "left" @@ -1417,7 +1481,9 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')"> # it might be utf-8. if type(attribute_value) == type(''): attribute_value = unicode(attribute_value, 'utf-8') + attribute_original_value = attribute_value elif attribute_value is None: + attribute_original_value = None attribute_value = '' if sql in editable_column_ids and form.has_field('%s_%s' % (field.id, alias) ): key = my_field.id + '_%s' % o.uid @@ -1444,9 +1510,12 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')"> cell_body = unicode(cell_body, 'utf-8') #LOG('ListBox', 0, 'cell_body = %r, error_message = %r' % (cell_body, error_message)) 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)) + current_listboxline.addColumn(property_id , my_field._get_default(self.generate_field_key(), attribute_original_value, o)) + else: # Check if url_columns defines a method to retrieve the URL. url_method = None @@ -1486,23 +1555,27 @@ 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': # Make sure that attribute value is UTF-8 - if type(attribute_value) == type(u''): - list_result_item.append(attribute_value.encode('utf-8')) - elif type(attribute_value) == type(''): - list_result_item.append(attribute_value) - else: - list_result_item.append(str(attribute_value).encode('utf-8')) + attribute_value_tmp = attribute_original_value + if type(attribute_value_tmp) == type(u''): + attribute_value_tmp = attribute_original_value.encode('utf-8') + # XXX this is horrible, but it would be better without those .... + if type(attribute_value_tmp) == type(''): + if 'nbsp' in attribute_value_tmp: + attribute_value_tmp = None + + current_listboxline.addColumn( property_id , attribute_value_tmp) list_body = list_body + '</tr>' - if render_format == 'list': - list_result.append(list_result_item) - # We need a list_result_item again - list_result_item = [] + + if render_format == 'list': + listboxline_list.append(current_listboxline) + ############################################################### # # Build statistics @@ -1512,17 +1585,19 @@ onChange="submitAction(this.form,'%s/portal_selections/setReportRoot')"> # Call the stat method if show_stat: + if render_format == 'list': + # Create a ListBoxLine object + current_listboxline = ListBoxLine() + current_listboxline.markStatLine() + kw['select_expression'] = select_expression selection.edit( params = kw ) count_results = selection(method = stat_method, context=here, REQUEST=REQUEST) list_body = list_body + '<tr>' - if render_format == 'list': - if report_tree: - list_result_item = [''] * (current_section_category_max_depth+1) - else: - list_result_item = [] + + if report_tree: list_body += '<td class="Data"> </td>' if select: @@ -1556,30 +1631,42 @@ 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': # Make sure that attribute value is UTF-8 + value_tmp = value if type(value) == type(u''): - list_result_item.append(value.encode('utf-8')) - elif type(value) == type(''): - list_result_item.append(value) - else: - list_result_item.append(str(value).encode('utf-8')) + value_tmp = value.encode('utf-8') + + # XXX this is horrible, but it would be better without those .... + if type(value_tmp) == type(''): + if 'nbsp' in value_tmp: + value_tmp = None + + current_listboxline.addColumn( column[1] , value_tmp ) + else: list_body += '<td class="Data"> </td>' - if render_format == 'list': list_result_item.append('') + if render_format == 'list': current_listboxline.addColumn( column[1] , None) except: list_body += '<td class="Data"> </td>' - if render_format == 'list': list_result_item.append('') + if render_format == 'list': current_listboxline.addColumn( column[1] , None) list_body += '</tr>' + if render_format == 'list': + listboxline_list.append(current_listboxline) + #LOG('ListBox', 0, 'header = %r, selection_list = %r, list_header = %r, list_search = %r, list_body = %r, footer = %r' % (header, selection_line, list_header, list_search, list_body, footer)) #LOG('ListBox', 0, 'header = %r, selection_list = %r, list_header = %r, list_search = %r, footer = %r' % (header, selection_line, list_header, list_search, 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 + #listboxline_list.append(current_listboxline) + LOG('ListBox', 0, 'listboxline_list: %s' % str(listboxline_list) ) + + return listboxline_list #Create DomainTree Selector and DomainTree box if domain_tree: @@ -1811,6 +1898,278 @@ class ListBox(ZMIField): else: return ZMIField.get_value(self, id, **kw) + + +class ListBoxLine: + meta_type = "ListBoxLine" + security = ClassSecurityInfo() + #security.declareObjectPublic() + + def __init__(self): + """ + Initialize the line and set the default values + Selected columns must be defined in parameter of listbox.render... + """ + + self.is_title_line = 0 + self.is_data_line = 1 + self.is_stat_line = 0 + self.is_summary_line = 0 + + self.is_section_folded = 1 + + self.config_dict = { + 'is_checked' : 0, + 'uid' : None, + 'section_name' : None, + 'section_depth' : 0, + 'content_mode' : 'DataLine' + } + self.config_display_list = [] + + self.column_dict = {} + self.column_id_list = [] + + security.declarePublic('__getitem__') + def __getitem__(self, column_id): + return getColumnProperty(self, column_id) + + #security.declarePublic('View') + def setConfigProperty(self, config_id, config_value): + self.config_dict[config_id] = config_value + + #security.declarePublic('View') + def getConfigProperty(self, config_id): + return self.config_dict[config_id] + + #security.declarePublic('View') + def setListboxLineContentMode(self, content_mode): + """ + Toogle the content type of the line + content_mode can be 'TitleLine' 'StatLine' 'DataLine' + Default value is 'DataLine' + """ + if content_mode == 'TitleLine': + self.is_title_line = 1 + self.is_data_line = 0 + self.is_stat_line = 0 + self.is_summary_line = 0 + elif content_mode == 'DataLine': + self.is_title_line = 0 + self.is_data_line = 1 + self.is_stat_line = 0 + self.is_summary_line = 0 + elif content_mode == 'StatLine': + self.is_title_line = 0 + self.is_data_line = 0 + self.is_stat_line = 1 + self.is_summary_line = 0 + elif content_mode == 'SummaryLine': + self.is_title_line = 0 + self.is_data_line = 0 + self.is_stat_line = 0 + self.is_summary_line = 1 + self.setConfigProperty('content_mode',content_mode) + + #security.declarePublic('View') + def markTitleLine(self): + """ + Set content of the line to 'TitleLine' + """ + self.setListboxLineContentMode('TitleLine') + + security.declarePublic('isTitleLine') + def isTitleLine(self): + """ + Returns 1 is this line contains no data but only title of columns + """ + return self.is_title_line + + #security.declarePublic('View') + def markStatLine(self): + """ + Set content of the line to 'StatLine' + """ + self.setListboxLineContentMode('StatLine') + + security.declarePublic('isStateLine') + def isStateLine(self): + """ + Returns 1 is this line contains no data but only stats + """ + return self.is_stat_line + + #security.declarePublic('View') + def markDataLine(self): + """ + Set content of the line to 'DataLine' + """ + self.setListboxLineContentMode('DataLine') + + security.declarePublic('isDataLine') + def isDataLine(self): + """ + Returns 1 is this line contains data + """ + return self.is_data_line + + #security.declarePublic('View') + def markSummaryLine(self): + """ + Set content of the line to 'SummaryLine' + """ + self.setListboxLineContentMode('SummaryLine') + + security.declarePublic('isSummaryLine') + def isSummaryLine(self): + """ + Returns 1 is this line is a summary line + """ + return self.is_summary_line + + #security.declarePublic('View') + def checkLine(self, is_checked): + """ + Set line to checked if is_checked=1 + Default value is 0 + """ + self.setConfigProperty('is_checked',is_checked) + + security.declarePublic('isLineChecked') + def isLineChecked(self): + """ + Returns 1 is this line is checked + """ + return self.getConfigProperty('is_checked') + + #security.declarePublic('View') + def setObjectUid(self, object_uid): + """ + Define the uid of the object + Default value is None + """ + self.setConfigProperty('uid',object_uid) + + security.declarePublic('getObjectUid') + def getObjectUid(self): + """ + Get the uid of the object related to the line + """ + return self.getConfigProperty('uid') + + #security.declarePublic('View') + def setSectionName(self, section_name): + """ + Set the section name of this line + Default value is None + """ + self.setConfigProperty('section_name',section_name) + + security.declarePublic('getSectionName') + def getSectionName(self): + """ + Returns the section name of this line + Default value is None + """ + return self.getConfigProperty('section_name') + + #security.declarePublic('View') + def setSectionDepth(self, depth): + """ + Set the section depth of this line + default value is 0 and means no depth + """ + self.setConfigProperty('section_depth',depth) + + security.declarePublic('getSectionDepth') + def getSectionDepth(self): + """ + Returns the section depth of this line + 0 means no depth + """ + return self.getConfigProperty('section_depth') + + #security.declarePublic('View') + def setSectionFolded(self, is_section_folded): + """ + Set the section mode of this line to 'Folded' if is_section_folded=1 + """ + self.is_section_folded = is_section_folded + + + security.declarePublic('isSectionFolded') + def isSectionFolded(self): + """ + Returns 1 if section is in 'Folded' Mode + """ + return self.is_section_folded + + #security.declarePublic('View') + def addColumn(self, column_id, column_value): + """ + Add a new column + """ + self.column_dict[column_id] = column_value + self.column_id_list.append(column_id) + + security.declarePublic('getColumnProperty') + def getColumnProperty(self, column_id): + """ + Returns the property of a column + """ + return self.column_dict[column_id] + + + security.declarePublic('getColumnPropertyList') + def getColumnPropertyList(self, column_id_list = None): + """ + Returns a list of the property + column_id_list selects the column_id returned + """ + + if column_id_list == None: + column_id_list = self.column_id_list + + if self.isTitleLine(): + config_column = [None] * len(self.config_display_list) + else: + config_column = [self.config_dict[column_id] for column_id in self.config_display_list] + + + return config_column + [self.column_dict[column_id] for column_id in column_id_list] + + security.declarePublic('getColumnItemList') + def getColumnItemList(self, column_id_list = None ): + """ + Returns a list of property tuple + column_id_list selects the column_id returned + """ + + if column_id_list == None: + column_id_list = self.column_id_list + + """ + if self.isTitleLine(): + config_column = [None] * len(self.config_display_list) + else: + config_column = [(config_id, self.config_dict[column_id]) for config_id in self.config_display_list] + """ + config_column = [(config_id, self.config_dict[config_id]) for config_id in self.config_display_list] + + return config_column + [(column_id , self.column_dict[column_id]) for column_id in column_id_list] + + security.declarePublic('setListboxLineDisplayListMode') + def setListboxLineDisplayListMode(self, display_list): + """ + Set the config columns displayable + display_list can content the key of self.config_dict + Default value of display_list is [] + """ + self.config_display_list = display_list + +InitializeClass(ListBoxLine) +allow_class(ListBoxLine) + # Psyco import psyco psyco.bind(ListBoxWidget.render) -- 2.30.9