class GadgetWidget(Widget.Widget): """ A widget that displays a renderjs gadget """ property_names = Widget.Widget.property_names + \ ['gadget_url', 'js_sandbox', 'extra', 'renderjs_extra'] default = Widget.TextWidget.default renderjs_extra = fields.ListTextAreaField('renderjs_extra', title="RenderJS extra", description=( "More parameters passed to the renderJS's render method."), default=[], required=0) gadget_url = fields.StringField('gadget_url', title='Gadget Url', description=("The url of the html page containing the \ gadget"), default='', required=0) js_sandbox = fields.StringField('js_sandbox', title='Gadget Sandbox', description=("Gadget sandbox"), default='', required=0) def render(self, field, key, value, REQUEST, render_prefix=None): return self.render_view(field, value, REQUEST, render_prefix, key) def render_view(self, field, value, REQUEST=None, render_prefix=None, key=None): kw = { 'data-gadget-sandbox': field.get_value('js_sandbox'), 'data-gadget-url': field.get_value('gadget_url'), 'data-gadget-value': value, 'data-gadget-renderjs-extra': dumps(dict(field.get_value('renderjs_extra'))) } if key is not None: kw['data-gadget-editable'] = key return Widget.render_element("div", extra=field.get_value('extra'), **kw) def get_javascript_list(self, field, REQUEST=None): """ Returns list of javascript needed by the widget """ js_list = ['rsvp.js', 'renderjs.js', 'erp5_gadgetfield.js'] result = [] try: for js_file in js_list: result.append(field.restrictedTraverse(js_file).absolute_url()) except KeyError: LOG('keyError:', ERROR, 'Error Value: %s' % js_file) return [] return result
class ListTextAreaWidget(Widget.TextAreaWidget): default = fields.ListTextAreaField('default', title='Default', default=[], required=0) def render(self, field, key, value, REQUEST): if value is None: value = field.get_value('default') if isinstance(value, basestring): # This happens while redisplaying a value from the request # i.e. _get_default(field, None, request) value = split_value(value.splitlines()) lines = [] for element_text, element_value in value: lines.append("%s | %s" % (element_text, element_value)) lines = '\n'.join(lines) return Widget.TextAreaWidget.render(self, field, key, lines, REQUEST)
class ItemsWidget(Widget): """A widget that has a number of items in it. """ items = fields.ListTextAreaField( 'items', title='Items', description= ("Items in the field. Each row should contain an " "item. Use the | (pipe) character to separate what is shown " "to the user from the submitted value. If no | is supplied, the " "shown value for the item will be identical to the submitted value. " "Internally the items property returns a list. If a list item " "is a single value, that will be used for both the display and " "the submitted value. A list item can also be a tuple consisting " "of two elements. The first element of the tuple should be a string " "that is name of the item that should be displayed. The second " "element of the tuple should be the value that will be submitted. " "If you want to override this property you will therefore have " "to return such a list."), default=[], width=20, height=5, required=0) # NOTE: for ordering reasons (we want extra at the end), # this isn't in the base class property_names list, but # instead will be referred to by the subclasses. extra_item = fields.StringField( 'extra_item', title='Extra per item', description= ("A string containing extra HTML code for attributes. This " "string will be literally included each of the rendered items of the " "field. This property can be useful if you want " "to add a disabled attribute to disable all contained items, for " "instance."), default="", required=0)
class MultiRelationStringFieldWidget(Widget.LinesTextAreaWidget, Widget.TextWidget, Widget.ListWidget): """ RelationStringField widget Works like a string field but includes one buttons - one search button which updates the field and sets a relation - creates object if not there """ local_property_names = [ 'update_method', 'jump_method', 'allow_jump', 'base_category', 'portal_type', 'allow_creation', 'container_getter_id', 'context_getter_id', 'catalog_index', 'relation_setter_id', 'relation_form_id', 'columns', 'sort', 'parameter_list', 'list_method', 'first_item', 'items', 'proxy_listbox_ids', 'size', 'extra_item', ] property_names = ( lambda name_list, name_set=set(): # delete double (but preserve order) in order to keep a usable ZMI... [x for x in name_list if not (x in name_set or name_set.add(x))] )(Widget.LinesTextAreaWidget.property_names + Widget.TextWidget.property_names + local_property_names) # XXX Field to remove... update_method = fields.StringField( 'update_method', title='Update Method', description=("The method to call to set the relation. Required."), default="Base_validateRelation", required=1) jump_method = fields.StringField( 'jump_method', title='Jump Method', description=("The method to call to jump to the relation. Required."), default="Base_jumpToRelatedDocument", required=1) allow_jump = fields.CheckBoxField( 'allow_jump', title='Allow Jump', description=("Do we allow to jump to the relation ?"), default=1, required=0) base_category = fields.StringField( 'base_category', title='Base Category', description=("The method to call to set the relation. Required."), default="", required=1) portal_type = fields.ListTextAreaField( 'portal_type', title='Portal Type', description=("The method to call to set the relation. Required."), default="", required=0) allow_creation = fields.CheckBoxField( 'allow_creation', title='Allow Creation', description=("Do we allow to create new objects ?"), default=1, required=0) container_getter_id = fields.StringField( 'container_getter_id', title='Container Getter Method', description=("The method to call to get a container object."), default="", required=0) context_getter_id = fields.StringField( 'context_getter_id', title='Context Getter Method', description=("The method to call to get the context."), default="", required=0) catalog_index = fields.StringField( 'catalog_index', title='Catalog Index', description=("The method to call to set the relation. Required."), default="", required=1) # XXX Is it a good idea to keep such a field ?? # User can redefine setter method with a script (and so, don't use the API) relation_setter_id = fields.StringField( 'relation_setter_id', title='Relation Update Method', description=("The method to invoke in order to update the relation"), default="", required=0) relation_form_id = fields.StringField( 'relation_form_id', title='Relation Form', description=("Form to display relation choices"), default="", required=0) size = fields.IntegerField( 'size', title='Size', description=( "The display size in rows of the field. If set to 1, the " "widget will be displayed as a drop down box by many browsers, " "if set to something higher, a list will be shown. Required."), default=1, required=1) columns = fields.ListTextAreaField( 'columns', title="Columns", description=("A list of attributes names to display."), default=[], required=0) sort = fields.ListTextAreaField( 'sort', title='Default Sort', description=('The default sort keys and order'), default=[], required=0) parameter_list = fields.ListTextAreaField( 'parameter_list', title="Parameter List", description=("A list of paramters used for the portal_catalog."), default=[], required=0) list_method = fields.MethodField('list_method', title='List Method', description=('The method to use to list' 'objects'), default='', required=0) proxy_listbox_ids = fields.ListTextAreaField( 'proxy_listbox_ids', title='Proxy Listbox IDs', description=('A list of listbox that can be used as proxy'), default='', required=0) default_widget_rendering_instance = Widget.LinesTextAreaWidgetInstance def _getContextValue(self, field, REQUEST): """Return result of evaluated method defined by context_getter_id or here. """ context_getter_id = field.get_value('context_getter_id') here = REQUEST['here'] if context_getter_id: return getattr(here, context_getter_id)() return here def _generateRenderValueList(self, field, key, value_list, REQUEST): if isinstance(value_list, basestring): # Value is a string, reformat it correctly value_list = value_list.split("\n") else: # We get a list # rather than displaying nothing, display a marker when the # property is not set # XXX Translate ? value_list = [(x or NO_VALUE) for x in value_list] generate_subfield_key = field.generate_subfield_key need_validation = False result_list = [] for index, value in enumerate(value_list): relation_item_list = REQUEST.get( generate_subfield_key( "%s_%s" % (ITEM_ID, index), key=key, ), None, ) # If we get a empty string, display nothing ! if value: need_validation |= relation_item_list is not None result_list.append(( Widget.TextWidgetInstance, generate_subfield_key( "%s_%s" % (SUB_FIELD_ID, index), key=key, ), relation_item_list, value, index, ), ) if need_validation: return result_list return [(Widget.LinesTextAreaWidgetInstance, None, [], value_list, None)] def render(self, field, key, value, REQUEST, render_prefix=None): """ Render text input field. """ portal = self._getContextValue(field, REQUEST).getPortalObject() autocomplete_enabled = getattr( portal.portal_skins, 'erp5_autocompletion_ui', None, ) is not None relation_field_index = REQUEST.get('_v_relation_field_index', 0) html_string_list = [] for (widget_instance, relation_field_id, relation_item_list, value_instance, sub_index) in self._generateRenderValueList( field, key, value, REQUEST, ): sub_html_string = widget_instance.render( field, key, value_instance, REQUEST, ) if autocomplete_enabled: sub_html_string += self.render_autocomplete(field, key) if relation_item_list is not None: if not autocomplete_enabled: sub_html_string += self.render_wheel( field, value_instance, REQUEST, relation_index=relation_field_index, sub_index=sub_index, ) if relation_item_list: REQUEST['relation_item_list'] = relation_item_list sub_html_string += NBSP + Widget.ListWidgetInstance.render( field, relation_field_id, None, REQUEST, ) + NBSP REQUEST['relation_item_list'] = None html_string_list.append(sub_html_string) html_string = '<br/>'.join(html_string_list) if (value == field.get_value('default')): # XXX Default rendering with value... relation_html_string = self.render_relation_link( field, value, REQUEST) if relation_html_string: html_string += NBSP + NBSP + relation_html_string REQUEST.set('_v_relation_field_index', relation_field_index + 1) return html_string def render_view(self, field, value, REQUEST=None, render_prefix=None): """ Render read only field. """ if (value not in ((), [], None, '')) and field.get_value('allow_jump'): if not isinstance(value, (list, tuple)): value = value, html_string = '<br />'.join( '<a class="relationfieldlink" href="%s">%s</a>' % ( escape(jump_reference.absolute_url()), escape(display_value), ) for jump_reference, display_value in zip( getattr( self._getContextValue(field, REQUEST), 'get%sValueList' % ''.join(part.capitalize() for part in field.get_value( 'base_category').split('_')))( portal_type=[ x[0] for x in field.get_value('portal_type') ], filter=dict(field.get_value('parameter_list')), ), value, )) else: html_string = self.default_widget_rendering_instance.render_view( field, value, REQUEST=REQUEST, ) if REQUEST is None: REQUEST = get_request() relation_html_string = self.render_relation_link( field, value, REQUEST) if relation_html_string: html_string += NBSP + NBSP + relation_html_string extra = field.get_value('extra') if extra not in (None, ''): html_string = "<div %s>%s</div>" % (extra, html_string) css_class = field.get_value('css_class') if css_class not in ('', None): html_string = '<span class="%s">%s</span>' % ( escape(css_class), html_string, ) return html_string def render_autocomplete(self, field, key): """ Use jquery-ui autocompletion for all relation fields by default, requiring only erp5_autocompletion_ui bt5 to be installed """ # XXX: Allow to specify more parameters to jquery-ui autocomplete widget? return """ <script type="text/javascript"> $(document).ready(function() { $("input[name='%s']").ERP5Autocomplete({search_portal_type: %s, search_catalog_key: "%s"}); }); </script>""" % ( escape(key), escape(json.dumps([x[0] for x in field.get_value('portal_type')])), escape(field.get_value('catalog_index')), ) def render_wheel(self, field, value, REQUEST, relation_index=0, sub_index=None, render_prefix=None): """ Render wheel used to display a listbox """ here = self._getContextValue(field, REQUEST) portal_url = here.getPortalObject().portal_url if sub_index is None: sub_index_string = '' else: sub_index_string = '_%s' % sub_index return ' <input type="image" ' \ 'src="%s/images/exec16.png" alt="update..." ' \ 'name="%s/viewSearchRelatedDocumentDialog%s%s' \ ':method"/>' % ( escape(portal_url()), escape(portal_url.getRelativeContentURL(here.portal_selections)), escape(str(relation_index)), escape(sub_index_string), ) def render_relation_link(self, field, value, REQUEST, render_prefix=None): """ Render link to the related object. """ if value not in ((), [], None, '') and field.get_value('allow_jump'): # If we this relation field is used as a listbox/matrixbox editable # field, then the context of this cell is set in REQUEST. XXX this is not # 100% reliable way, maybe we need something to know that the field is # beeing rendered as an editable field. cell = REQUEST.get('cell') here = (cell if cell is not None else self._getContextValue( field, REQUEST)) # Keep the selection name in the URL selection_name = REQUEST.get('selection_name') if selection_name is not None: selection_name_html = '&selection_name=%s&selection_index=%s' % ( escape(selection_name), escape(str(REQUEST.get('selection_index', 0))), ) else: selection_name_html = '' ignore_layout = REQUEST.get('ignore_layout') if ignore_layout is not None: selection_name_html += '&ignore_layout:int=%s' % int( ignore_layout) # Generate plan link return '<a href="%s/%s?field_id=%s&form_id=%s%s">' \ '<img src="%s/images/jump.png" alt="jump" />' \ '</a>' % ( escape(here.absolute_url()), escape(field.get_value('jump_method')), escape(field.id), escape(field.aq_parent.id), escape(selection_name_html), escape(here.getPortalObject().portal_url()), ) return ''
class OOoChartWidget(Widget.Widget): """ This class is capabale of producing ODF charts based on data obtained through a listbox. Some properties are useless http://books.evc-cit.info/odbook/ch08.html#chart-plot-area-example - mean-value - error-margin - error-upper-limit - error-lower-limit - error-category - error-percentage - chart-japanese-candle-stick and stock-with-volume,chart:stock-updown-bars. These attributs are used with a chart:stock """ property_names = list(Widget.Widget.property_names) # XXX The description says it's not used # but removing 'default' breaks ODT/ODS rendering ... default = fields.StringField( 'default', title='Default', description=("A default value (not used)."), default="", required=0) listbox_form_id = fields.StringField( 'listbox_form_id', title='ListBox Form ID', description=("ID of the master form."), default="", required=0) property_names.append('listbox_form_id') listbox_id = fields.StringField( 'listbox_id', title='ListBox ID', description=("ID of the listbox in the master form."), default="", required=0) property_names.append('listbox_id') image_display = fields.ListField('image_display', title='Image Display', description=("Render size of this chart in HTML mode."), default='medium', items=[('thumbnail','thumbnail'), ('xsmall', 'xsmall'), ('small', 'small'), ('medium', 'medium'), ('large', 'large'), ('xlarge', 'xlarge'), ], size=1) property_names.append('image_display') image_format = fields.StringField('image_format', title='Image Format', description=( "The format in which the chart should be converted to."), default='png', required=0) property_names.append('image_format') ooo_template = fields.StringField('ooo_template', title='OOo Template', description=('The ID of a OOo Page Template' 'to render the ListBox'), default='ERP5Site_viewChart', required=0) property_names.append('ooo_template') chart_type = fields.ListField('chart_type', title='Chart Type', description=('Type of the Chart'), default='chart:bar', items=[('bar', 'chart:bar'), ('circle', 'chart:circle'), ('line', 'chart:line'), ('scatter', 'chart:scatter'), ('area', 'chart:area'), ], size=0) property_names.append('chart_type') colour_column_list = fields.ListTextAreaField('colour_column_list', title="Data Color", description=( "A list of colors for each data associated to a column."), default=[], required=0) property_names.append('colour_column_list') # vertical ="true" chart_position = fields.ListField('chart_position', title='Bar Position', description=( 'Render the bar in horizontal position or vertical position'), default='false', items=[('horizontal', 'true'), ('vertical', 'false'), ], size=0) property_names.append('chart_position') #legend of the chart or not chart_legend = fields.CheckBoxField('chart_legend', title='Chart Legend', description=('Show Chart Legend or no'), default=1, required=0) property_names.append('chart_legend') position_legend = fields.ListField('position_legend', title='Legend Position', description=( 'Legend Position according to the graph'), default='end', items=[('bottom', 'bottom'), ('end', 'end'), ('start', 'start'), ('top', 'top'), ], size=1) property_names.append('position_legend') #legend of the chart or not chart_title_or_no = fields.CheckBoxField('chart_title_or_no', title='Chart Title ', description=('Show Title on Graph or no '), default=1, required=0) property_names.append('chart_title_or_no') # Axis x_axis_property_list = fields.ListTextAreaField('x_axis_property_list', title="X-Axis Properties", description="Examples of recognized properties:" " 'chart:visible'," " 'chart:display-label'," " 'chart:label-arrangement'," " 'chart:tick-marks-major-inner'," " 'chart:reverse-direction'," " 'chart:logarithmic'," " 'chart:text-overlap'," " 'chart:origin'," " 'text:line-break'," " 'style:rotation-angle'...", default=(), required=0) property_names.append('x_axis_property_list') y_axis_property_list = fields.ListTextAreaField('y_axis_property_list', title="Y-Axis Properties", default=(), required=0) property_names.append('y_axis_property_list') #grid or not grid_graph = fields.CheckBoxField('grid_graph', title='Chart Grid ', description=('Show Grid or no'), default=1, required=0) property_names.append('grid_graph') grid_size = fields.ListField('grid_size', title='Grid Size', description=( 'Render a big grid size or a small grid size'), default='major', items=[('major', 'major'), ('minor', 'minor'), ], size=0) property_names.append('grid_size') user_data_title = fields.StringField('user_data_title', title="Overide Labelled Column ID", description=( "Column Id choose by user to define the label."), required=0) property_names.append('user_data_title') user_column_id_list = fields.ListTextAreaField('user_column_id_list', title="Overide Column Ids", description=( "A list of column Ids choose by user to draw the graph."), default=[], required=0) property_names.append('user_column_id_list') chart_stacked = fields.CheckBoxField('chart_stacked', title='Stacked Data', description=('stacked data or not'), default=0, required=0) property_names.append('chart_stacked') #connect-bars="false" connect_bars = fields.CheckBoxField('connect_bars', title='Connect Bars', description=(''), default=0, required=0) property_names.append('connect_bars') chart_three_dimensional = fields.CheckBoxField('chart_three_dimensional', title='3D', description=( 'Render the chart in three dimensions rather in flat mode'), default=0, required=0) property_names.append('chart_three_dimensional') #deep="false" deep = fields.CheckBoxField('deep', title='Deep', description=('Deep'), default=0, required=0) property_names.append('deep') # sector_pie_offset Default:0 sector_pie_offset = fields.IntegerField('sector_pie_offset', title='Sector Pie Offset', description=(''), default=0, required=0) property_names.append('sector_pie_offset') #interpolation="none", cubic-spline, b-spline interpolation = fields.ListField('interpolation', title='Interpolation', description=(''), default='none', items=[('none', 'none'), ('cubic-spline', 'cubic-spline'), ('b-spline', 'b-spline')], size=1) property_names.append('interpolation') #symbol-type="none", automatic symbol_type = fields.ListField('symbol_type', title='Symbol Type', description=(''), default='none', items=[('none', 'none'), ('automatic', 'automatic'),], size=1) property_names.append('symbol_type') #lines-used="0" lines_used = fields.ListField('lines_used', title='Lines Used', description=(''), default='0', items=[('0', '0'), ('1', '1')], size=1) property_names.append('lines_used') #series-source=columns or rows series_source = fields.ListField('series_source', title='Series Source', description=(''), default='columns', items=[('columns', 'columns'), ('rows', 'rows'),], size=1) property_names.append('series_source') #regression-type="none" linear logarithmic exponential power regression_type = fields.ListField('regression_type', title='Regression Type', description=(''), default='none', items=[('none', 'none'), ('linear', 'linear'), ('logarithmic', 'logarithmic'), ('exponential', 'exponential'), ('power', 'power')], size=1) property_names.append('regression_type') #data-label-number="none" value percentage data_label_number = fields.ListField('data_label_number', title='Data Label Number', description=(''), default='none', items=[('none', 'none'), ('value', 'value'), ('percentage', 'percentage')], size=1) property_names.append('data_label_number') #data-label-text="false" data_label_text = fields.CheckBoxField('data_label_text', title='Data Label Text', description=(''), default=0, required=0) property_names.append('data_label_text') #data-label-symbol="false" data_label_symbol = fields.CheckBoxField('data_label_symbol', title='Data Label Symbol', description=(''), default=0, required=0) property_names.append('data_label_symbol') def getArgumentDict(self, field, REQUEST): """ Build argument Dict """ def stringBoolean(value): return str(bool(value)).lower() form = field.aq_parent listbox_form_id = field.get_value('listbox_form_id') if listbox_form_id in ('', None): listbox_form_id = form.getId() listbox_id = field.get_value('listbox_id') if listbox_id in ('', None): listbox_id = 'listbox' render_prefix = REQUEST.get('render_prefix') extra_argument_dict = dict( render_prefix = render_prefix, chart_form_id = listbox_form_id, chart_field_id = listbox_id, chart_title = field.get_value('title'), chart_type = field.get_value('chart_type'), colour_column_list = field.get_value('colour_column_list'), user_column_id_list = field.get_value('user_column_id_list'), user_data_title= field.get_value('user_data_title'), chart_position = field.get_value('chart_position'), chart_legend = stringBoolean(field.get_value('chart_legend')), chart_title_or_no = stringBoolean(field.get_value('chart_title_or_no')), x_axis_property_dict = dict(field.get_value('x_axis_property_list')), y_axis_property_dict = dict(field.get_value('y_axis_property_list')), grid_graph = stringBoolean(field.get_value('grid_graph')), grid_size=field.get_value('grid_size'), chart_three_dimensional = stringBoolean(field.get_value('chart_three_dimensional')), deep = stringBoolean(field.get_value('deep')), chart_stacked = stringBoolean(field.get_value('chart_stacked')), sector_pie_offset = field.get_value('sector_pie_offset'), interpolation = field.get_value('interpolation'), symbol_type = field.get_value('symbol_type'), lines_used = field.get_value('lines_used'), connect_bars = stringBoolean(field.get_value('connect_bars')), series_source = field.get_value('series_source'), regression_type = field.get_value('regression_type'), data_label_number = field.get_value('data_label_number'), data_label_text = stringBoolean(field.get_value('data_label_text')), data_label_symbol = stringBoolean(field.get_value('data_label_symbol')), position_legend=field.get_value('position_legend'), ) for k, v in extra_argument_dict.items(): if REQUEST.get(k) is None: REQUEST.form[k] = v return extra_argument_dict def render_view(self, field, value, REQUEST=None, key=None, render_format='html', render_prefix=None): """ Render a Chart in read-only. """ if REQUEST is None: REQUEST=get_request() return self.render(field, key, value, REQUEST, render_format=render_format, render_prefix=render_prefix) def render_odf(self, field, key, value, REQUEST, render_format='ooo', render_prefix=None): """ Render a Chart for ODT Style. """ if REQUEST is None: REQUEST=get_request() form = field.aq_parent here = getattr(form, 'aq_parent', REQUEST) REQUEST.set('render_prefix', render_prefix) #needed to update REQUEST argument_dict = self.getArgumentDict(field, REQUEST) from xml.marshal.generic import dumps dump_args = dumps(argument_dict) #remove xml declaration (first processing node) dump_args = dump_args[dump_args.index('?>')+2:] content = '''<office:include path="%s/ERP5Site_buildChart" xlink:type="simple" xlink:actuate="onLoad" xlink:show="embed">%s</office:include> ''' % (here.getPath(), dump_args) return content def render(self, field, key, value, REQUEST, render_format='html', render_prefix=None): """ Render a chart. render_format -- If the format is set to html, render the chart as a URL to ourselves with a png render_format If the format is set to 'raw', render the chart as raw XML. If the format is set to an image type (ex. png) render the chart using that format. """ title = field.get_value('title') alt = field.get_value('description') or title form = field.aq_parent if not render_prefix: render_prefix = REQUEST.get('render_prefix') # Find the applicable context here = getattr(form, 'aq_parent', REQUEST) # Update the render format based on REQUEST parameters render_format = getattr(REQUEST, 'render_format', render_format) if render_format == 'html': css_class = field.get_value('css_class') format = field.get_value('image_format') or 'png' query_dict = dict(REQUEST.form.items()) query_dict.update(render_format=format != 'raw' and format or '', render_prefix=render_prefix, display=field.get_value('image_display')) # XXX make_query does not handle tuples properly so listbox should be # not editable (otherwise, REQUEST.form may contain listbox=()). url = '%s/%s/%s?%s' % (here.absolute_url(), form.getId(), field.getId(), make_query(query_dict)) if format in VALID_IMAGE_FORMAT_LIST: return '''<div class="OOoChartContent"> <img class="%s" src="%s" title="%s" alt="%s"/"> </div>''' % (css_class, url, title, alt) elif format == 'raw': UrlIconOOo = '%s/misc_/ERP5OOo/OOo.png' % REQUEST['BASEPATH1'] return '''<div class="OOoChartContent"> <a href="%s"><img src="%s" alt="OOo"/></a> </div>''' % (url, UrlIconOOo) elif format == 'pdf': UrlIconPdf = '%s/misc_/ERP5Form/PDF.png' % REQUEST['BASEPATH1'] return '''<div class="OOoChartContent"> <a href="%s"><img src="%s" alt="PDF" /></a> </div>''' % (url, UrlIconPdf) else: raise NotImplementedError, 'Format: %s not handled' % format extra_context = self.getArgumentDict(field, REQUEST) method_id = field.get_value('ooo_template') # Find the page template ooo_template = getattr(here, method_id) # Render the chart return ooo_template(format=render_format, **extra_context)
class MatrixBoxWidget(Widget.Widget): """ An UI widget which displays a matrix Don't forget that you can use tales expressions for every field, so this is really usefull if you want to use fonctions instead of predefined variables. A function is provided to - access a cell - modify a cell """ property_names = Widget.Widget.property_names +\ ['cell_base_id', 'cell_portal_type', 'lines', 'columns', 'tabs', 'as_cell_range_script_id', 'getter_method', 'editable_attributes', 'global_attributes', 'cell_getter_method', 'update_cell_range', 'url_cells' ] default = fields.TextAreaField( 'default', title='Default', description=("Default value of the text in the widget."), default="", width=20, height=3, required=0) as_cell_range_script_id = fields.StringField( 'as_cell_range_script_id', title='Cell range method', description=( "Method returning columns, lines and tabs. The method is passed" " matrixbox=True, base_id=base_id as arguments."), default='', required=0) columns = fields.ListTextAreaField( 'columns', title="Columns", description=( "This defines columns of the matrixbox. " "This should be a list of couples, " "couple[0] is the variation, and couple[1] is the name displayed " "to the user.\n" "For example (('color/blue', 'Bleu'), ('color/red','Red')).\n" " Deprecated, use cell range method instead"), default=[], required=0) lines = fields.ListTextAreaField( 'lines', title="Lines", description= ("This defines lines of the matrixbox. This should be a list of couples, " "couple[0] is the variation, and couple[1] is the name displayed " "to the user.\n" "For example (('size/baby/02','baby/02'),('size/baby/03','baby/03')).\n" "Deprecated, use cell range method instead"), default=[], required=0) tabs = fields.ListTextAreaField( 'tabs', title="Tabs", description=( "This defines tabs. You can use it with the same way as Lines " "and Columns.\n" "This is used only if you have more than 2 kinds of variations.\n" "Deprecated, use cell range method instead"), default=[], required=0) # XXX ListTextAreaField ? cell_range = fields.ListTextAreaField( 'cell_range', title="Cell Range", description=("This defines the range of the matrix."), default=[], required=0) getter_method = fields.StringField( 'getter_method', title='Getter method', description= ("You can specify a specific method in order to retrieve the context. " "This field can be empty, if so the MatrixBox will use the default " "context."), default='', required=0) cell_getter_method = fields.StringField( 'cell_getter_method', title='Cell Getter method', description= ("You can specify a method in order to retrieve cells. This field can " "be empty, if so the MatrixBox will use the default method : getCell." ), default='', required=0) new_cell_method = fields.MethodField( 'new_cell_method', title='New Cell method', description=( "You can specify a specific method in order to create cells. " "This field can be empty, if so the MatrixBox will use the default " "method : newCell."), default='', required=0) editable_attributes = fields.ListTextAreaField( 'editable_attributes', title="Editable Properties", description=( "A list of attributes which are set by hidden fields called " "matrixbox_attribute_name. This is used " "when we want to specify a computed value for each cell"), default=[], required=0) global_attributes = fields.ListTextAreaField( 'global_attributes', title="Global Properties", description=( "An optional list of globals attributes which are set by hidden " "fields and which are applied to each cell. " "This is used if we want to set the same value for every cell"), default=[], required=0) cell_base_id = fields.StringField( 'cell_base_id', title='Base id for cells', description=( "The Base id for cells : this is the name used to store cells, " "we usually use names like : 'movement', 'path', ... "), default='cell', required=0) cell_portal_type = fields.StringField( 'cell_portal_type', title='Portal Type for cells', description=( "The Portal Type for cells : This is the portal type used to " "create a new cell."), default='Mapped Value', required=0) update_cell_range = fields.CheckBoxField( 'update_cell_range', title="Update Cell Range", description=("The cell range should be updated upon edit."), default=0) url_cells = fields.ListTextAreaField( 'url_cells', title="URL Cells", description=( "An optional list of cells which can provide a custom URL." "If no url cell is used, then no link is displayed."), default=[], required=0) def render(self, field, key, value, REQUEST, render_format='html', render_prefix=None): """ This is where most things happen. This method renders a list of items """ # First grasp the variables we may need here = REQUEST['here'] form = field.aq_parent field_title = field.get_value('title') cell_base_id = field.get_value('cell_base_id') context = here getter_method_id = field.get_value('getter_method') if getter_method_id not in (None, ''): context = getattr(here, getter_method_id)() if context is None: return '' as_cell_range_script_id = field.get_value('as_cell_range_script_id') extra_dimension_category_list_list = [None] if as_cell_range_script_id: lines = [] columns = [] tabs = [] dimension_list = guarded_getattr(context, as_cell_range_script_id)( matrixbox=True, base_id=cell_base_id) len_dimension_list = len(dimension_list) if len_dimension_list: if len_dimension_list == 1: lines, = dimension_list elif len_dimension_list == 2: lines, columns = dimension_list elif len_dimension_list >= 3: lines, columns, tabs = dimension_list[:3] if len_dimension_list > 3: extra_dimension_list = dimension_list[3:] extra_dimension_category_label_dict = {} extra_dimension_category_index_dict = {} for extra_dimension in extra_dimension_list: for index, (category, label) in enumerate(extra_dimension): extra_dimension_category_label_dict[ category] = label extra_dimension_category_index_dict[ category] = index from Products.ERP5Type.Utils import cartesianProduct extra_dimension_category_list_list = cartesianProduct( [[category for category, label in extra_dimension] for extra_dimension in extra_dimension_list]) else: lines = field.get_value('lines') columns = field.get_value('columns') tabs = field.get_value('tabs') field_errors = REQUEST.get('field_errors', {}) cell_getter_method_id = field.get_value('cell_getter_method') if cell_getter_method_id not in (None, ''): cell_getter_method = getattr(context, cell_getter_method_id) else: cell_getter_method = context.getCell editable_attributes = field.get_value('editable_attributes') url_cells = field.get_value('url_cells') url_cell_dict = dict(url_cells) # This is required when we have no tabs if len(tabs) == 0: tabs = [(None, None)] # This is required when we have no columns if len(columns) == 0: columns = [(None, None)] column_ids = [x[0] for x in columns] line_ids = [x[0] for x in lines] tab_ids = [x[0] for x in tabs] editable_attribute_ids = [x[0] for x in editable_attributes] # THIS MUST BE REMOVED - WHY IS THIS BAD ? # IT IS BAD BECAUSE TAB_IDS DO NOT DEFINE A RANGE.... # here.setCellRange(line_ids, column_ids, base_id=cell_base_id) # result for the list render list_result = [] url = REQUEST.URL list_html = '' for extra_dimension_category_list in extra_dimension_category_list_list: if extra_dimension_category_list is None: extra_dimension_label = '' extra_dimension_position = () extra_dimension_index = '' extra_dimension_category_list = [] else: extra_dimension_label = ',' + ','.join([ extra_dimension_category_label_dict[category] for category in extra_dimension_category_list ]) extra_dimension_position = tuple([ extra_dimension_category_index_dict[category] for category in extra_dimension_category_list ]) extra_dimension_index = '_' + '_'.join( map(str, extra_dimension_position)) # Create one table per tab k = 0 kwd = dict(base_id=cell_base_id) for tab in tabs: tab_id = tab[0] if (tab_id is not None) and \ (not isinstance(tab_id, (list, tuple))): tab_id = [tab_id] if render_format == 'list': list_result_tab = [[tab[1]]] # Create the header of the table - this should probably become DTML first_tab = tab[1] or '' header = """\ <!-- Matrix Content --> <div class="matrixbox_label_tab">%s</div> <div class="MatrixContent"> <table> """ % (first_tab + extra_dimension_label) # Create the footer. This should be replaced by DTML # And work as some kind of parameter footer = """\ <tr> <td colspan="%i" class="Data footer"> </td> </tr> </table> </div> """ % (len(columns) + 1) list_header = """\ <tr class="matrixbox_label_line"><td class=\"Data\"></td> """ for cname in columns: first_column = cname[1] or '' list_header = list_header + ( "<td class=\"Data\">%s</td>\n" % first_column) if render_format == 'list': list_result_tab[0].append(cname[1]) list_header = list_header + "</tr>" # Build Lines i = 0 j = 0 list_body = '' for l in lines: if not i % 2: td_css = 'DataA' else: td_css = 'DataB' list_body = list_body + '\n<tr class=\"%s\"><td class=\"matrixbox_label_column\">%s</td>' % ( td_css, str(l[1])) j = 0 if render_format == 'list': list_result_lines = [str(l[1])] for c in columns: has_error = False column_id = c[0] if (column_id is not None) and \ (not isinstance(column_id, (list, tuple))): column_id = [column_id] if column_id is None: kw = [l[0]] elif tab_id is None: kw = [l[0], c[0]] else: kw = [l[0], c[0] ] + tab_id + extra_dimension_category_list cell = cell_getter_method(*kw, **kwd) REQUEST['cell'] = cell REQUEST['cell_index'] = kw cell_body = '' cell_url = None for attribute_id in editable_attribute_ids: if attribute_id in url_cell_dict: url_method_id = url_cell_dict[attribute_id] if url_method_id not in (None, ''): url_method = getattr( cell, url_method_id, None) if url_method is not None: try: cell_url = url_method( brain=cell, cell_index=kw, cell_position=( (i, j, k) + extra_dimension_position)) except (ConflictError, RuntimeError): raise except: LOG('MatrixBox', WARNING, 'Could not evaluate the url ' 'method %r with %r' % (url_method, cell), error=sys.exc_info()) else: LOG( 'MatrixBox', WARNING, 'Could not find the url method %s' % (url_method_id, )) my_field_id = '%s_%s' % (field.id, attribute_id) if form.has_field(my_field_id): my_field = form.get_field(my_field_id) key = my_field.id + '_cell_%s_%s_%s%s' % ( i, j, k, extra_dimension_index) default_value = my_field.get_value( 'default', cell=cell, cell_index=kw, cell_position=((i, j, k) + extra_dimension_position)) display_value = default_value if field_errors: # Display previous value in case of any error in this form because # we have no cell to get value from display_value = REQUEST.get( 'field_%s' % key, default_value) if cell is not None: if render_format == 'html': cell_html = my_field.render( value=display_value, REQUEST=REQUEST, key=key) if cell_url: # don't make a link if widget is editable if not my_field.get_value( 'editable', cell=cell, cell_index=kw, cell_position=( (i, j, k) + extra_dimension_position )): cell_html = "<a href='%s'>%s</a>" % ( cell_url, cell_html) if key in field_errors: # Display error message if this cell has an error has_error = True cell_body += '<span class="input">%s</span>%s' % ( cell_html, translateString( field_errors[key]. error_text)) else: cell_body += '<span class="input">%s</span>' % ( cell_html) else: if render_format == 'html': if key in field_errors: # Display error message if this cell has an error has_error = True cell_body += '<span class="input">%s</span>%s' % ( my_field.render( value=display_value, REQUEST=REQUEST, key=key), translateString( field_errors[key]. error_text)) else: cell_body += '<span class="input">%s</span>' %\ my_field.render( value=display_value, REQUEST=REQUEST, key=key) if render_format == 'list': # list rendering doesn't make difference when cell exists or not list_result_lines.append({ 'default': default_value, 'value': display_value, 'key': key, 'type': my_field.meta_type if my_field.meta_type != "ProxyField" else my_field. getRecursiveTemplateField().meta_type, 'field_id': my_field.id, 'error_text': u"%s" % (translateString( field_errors[key].error_text) if key in field_errors else '') }) css = td_css if has_error: css = 'error' list_body = list_body + \ ('<td class=\"%s\">%s</td>' % (css, cell_body)) j += 1 list_body = list_body + '</tr>' i += 1 if render_format == 'list': list_result_tab.append(list_result_lines) list_html += header + list_header + \ list_body + footer k += 1 if render_format == 'list': list_result.append(list_result_tab) # XXX Does not leave garbage in REQUEST['cell'], because some other # fields also use that key... REQUEST.other.pop('cell', None) REQUEST.other.pop('cell_index', None) if render_format == 'list': return list_result return list_html
class MultiRelationStringFieldWidget(Widget.LinesTextAreaWidget, Widget.TextWidget, Widget.ListWidget): """ RelationStringField widget Works like a string field but includes one buttons - one search button which updates the field and sets a relation - creates object if not there """ local_property_names = [ 'update_method', 'jump_method', 'allow_jump', 'base_category', 'portal_type', 'allow_creation', 'container_getter_id', 'context_getter_id', 'catalog_index', 'relation_setter_id', 'relation_form_id', 'columns', 'sort', 'parameter_list', 'list_method', 'first_item', 'items', 'proxy_listbox_ids', 'size', 'extra_item', ] property_names = Widget.LinesTextAreaWidget.property_names + \ Widget.TextWidget.property_names + \ local_property_names # XXX Field to remove... update_method = fields.StringField( 'update_method', title='Update Method', description=("The method to call to set the relation. Required."), default="Base_validateRelation", required=1) jump_method = fields.StringField( 'jump_method', title='Jump Method', description=("The method to call to jump to the relation. Required."), default="Base_jumpToRelatedDocument", required=1) allow_jump = fields.CheckBoxField( 'allow_jump', title='Allow Jump', description=("Do we allow to jump to the relation ?"), default=1, required=0) base_category = fields.StringField( 'base_category', title='Base Category', description=("The method to call to set the relation. Required."), default="", required=1) portal_type = fields.ListTextAreaField( 'portal_type', title='Portal Type', description=("The method to call to set the relation. Required."), default="", required=1) allow_creation = fields.CheckBoxField( 'allow_creation', title='Allow Creation', description=("Do we allow to create new objects ?"), default=1, required=0) container_getter_id = fields.StringField( 'container_getter_id', title='Container Getter Method', description=("The method to call to get a container object."), default="", required=0) context_getter_id = fields.StringField( 'context_getter_id', title='Context Getter Method', description=("The method to call to get the context."), default="", required=0) catalog_index = fields.StringField( 'catalog_index', title='Catalog Index', description=("The method to call to set the relation. Required."), default="", required=1) # XXX Is it a good idea to keep such a field ?? # User can redefine setter method with a script (and so, don't use the API) relation_setter_id = fields.StringField( 'relation_setter_id', title='Relation Update Method', description=("The method to invoke in order to update the relation"), default="", required=0) relation_form_id = fields.StringField( 'relation_form_id', title='Relation Form', description=("Form to display relation choices"), default="", required=0) size = fields.IntegerField( 'size', title='Size', description=( "The display size in rows of the field. If set to 1, the " "widget will be displayed as a drop down box by many browsers, " "if set to something higher, a list will be shown. Required."), default=1, required=1) columns = fields.ListTextAreaField( 'columns', title="Columns", description=("A list of attributes names to display."), default=[], required=0) sort = fields.ListTextAreaField( 'sort', title='Default Sort', description=('The default sort keys and order'), default=[], required=0) parameter_list = fields.ListTextAreaField( 'parameter_list', title="Parameter List", description=("A list of paramters used for the portal_catalog."), default=[], required=0) list_method = fields.MethodField('list_method', title='List Method', description=('The method to use to list' 'objects'), default='', required=0) proxy_listbox_ids = fields.ListTextAreaField( 'proxy_listbox_ids', title='Proxy Listbox IDs', description=('A list of listbox that can be used as proxy'), default='', required=0) # delete double in order to keep a usable ZMI... # XXX need to keep order ! #property_names = dict([(i,0) for i in property_names]).keys() _v_dict = {} _v_property_name_list = [] for property_name in property_names: if not _v_dict.has_key(property_name): _v_property_name_list.append(property_name) _v_dict[property_name] = 1 property_names = _v_property_name_list default_widget_rendering_instance = Widget.LinesTextAreaWidgetInstance def _getContextValue(self, field, REQUEST): """Return result of evaluated method defined by context_getter_id or here. """ context_getter_id = field.get_value('context_getter_id') here = REQUEST['here'] if context_getter_id: return getattr(here, context_getter_id)() return here def _generateRenderValueList(self, field, key, value_list, REQUEST): result_list = [] need_validation = 0 #################################### # Check value #################################### if isinstance(value_list, StringType): # Value is a string, reformat it correctly value_list = value_list.split("\n") else: # We get a list # rather than displaying nothing, display a marker when the # property is not set # XXX Translate ? value_list = [(x or NO_VALUE) for x in value_list] # Check all relation for i in range(len(value_list)): ################################### # Sub field ################################### relation_field_id = field.generate_subfield_key("%s_%s" % \ (SUB_FIELD_ID, i), key=key) relation_item_id = field.generate_subfield_key("%s_%s" % \ (ITEM_ID, i), key=key) relation_item_list = REQUEST.get(relation_item_id, None) value = value_list[i] if (relation_item_list is not None) and \ (value != ''): need_validation = 1 # If we get a empty string, display nothing ! if value != '': result_list.append( (Widget.TextWidgetInstance, relation_field_id, relation_item_list, value, i)) if not need_validation: ################################### # Main field ################################### result_list = [(Widget.LinesTextAreaWidgetInstance, None, [], value_list, None)] return result_list def render(self, field, key, value, REQUEST, render_prefix=None): """ Render text input field. """ html_string = '' relation_field_index = REQUEST.get('_v_relation_field_index', 0) render_parameter_list = self._generateRenderValueList( field, key, value, REQUEST) #################################### # Render subfield #################################### html_string_list = [] for widget_instance, relation_field_id, relation_item_list, \ value_instance, sub_index in render_parameter_list: sub_html_string = widget_instance.render(field, key, value_instance, REQUEST) here = self._getContextValue(field, REQUEST) portal = here.getPortalObject() autocomplete_enabled = getattr(portal.portal_skins, 'erp5_autocompletion_ui', None) if autocomplete_enabled: sub_html_string += self.render_autocomplete(field, key) if relation_item_list is not None: #################################### # Render wheel #################################### if not autocomplete_enabled: sub_html_string += self.render_wheel( field, value_instance, REQUEST, relation_index=relation_field_index, sub_index=sub_index) if relation_item_list: #################################### # Render listfield #################################### REQUEST['relation_item_list'] = relation_item_list sub_html_string += ' %s ' % \ Widget.ListWidgetInstance.render( field, relation_field_id, None, REQUEST) REQUEST['relation_item_list'] = None html_string_list.append(sub_html_string) #################################### # Generate html #################################### html_string = '<br/>'.join(html_string_list) #################################### # Render jump #################################### if (value == field.get_value('default')): # XXX Default rendering with value... relation_html_string = self.render_relation_link( field, value, REQUEST) if relation_html_string != '': html_string += ' %s' % relation_html_string #################################### # Update relation field index #################################### REQUEST.set('_v_relation_field_index', relation_field_index + 1) return html_string def render_view(self, field, value, REQUEST=None, render_prefix=None): """ Render read only field. """ html_string = '' here = self._getContextValue(field, REQUEST) portal_url = here.getPortalObject().portal_url portal_url_string = portal_url() if (value not in ((), [], None, '')) and \ field.get_value('allow_jump'): string_list = [] base_category = field.get_value('base_category') portal_type = map(lambda x: x[0], field.get_value('portal_type')) kw = {} for k, v in field.get_value('parameter_list'): kw[k] = v accessor_name = 'get%sValueList' % ''.join( [part.capitalize() for part in base_category.split('_')]) jump_reference_list = getattr(here, accessor_name)( portal_type=portal_type, filter=kw) if not isinstance(value, (list, tuple)): value = value, for jump_reference, display_value in zip(jump_reference_list, value): string_list.append('<a class="relationfieldlink" href="%s">%s</a>' % \ (jump_reference.absolute_url(), display_value)) html_string = '<br />'.join(string_list) else: html_string = self.default_widget_rendering_instance.render_view( field, value, REQUEST=REQUEST) if REQUEST is None: REQUEST = get_request() relation_html_string = self.render_relation_link( field, value, REQUEST) if relation_html_string != '': html_string += ' %s' % relation_html_string extra = field.get_value('extra') if extra not in (None, ''): html_string = "<div %s>%s</div>" % (extra, html_string) css_class = field.get_value('css_class') if css_class not in ('', None): # All strings should be escaped before rendering in HTML # except for editor field html_string = "<span class='%s'>%s</span>" % (css_class, html_string) return html_string def render_autocomplete(self, field, key): """ Use jquery-ui autocompletion for all relation fields by default, requiring only erp5_autocompletion_ui bt5 to be installed """ # XXX: Allow to specify more parameters to jquery-ui autocomplete widget? import json return """ <script type="text/javascript"> $(document).ready(function() { $("input[name='%s']").ERP5Autocomplete({search_portal_type: %s, search_catalog_key: "%s"}); }); </script>""" % (key, json.dumps(map(lambda x: x[0], field.get_value('portal_type'))), field.get_value('catalog_index')) def render_wheel(self, field, value, REQUEST, relation_index=0, sub_index=None, render_prefix=None): """ Render wheel used to display a listbox """ here = self._getContextValue(field, REQUEST) portal_url = here.getPortalObject().portal_url portal_url_string = portal_url() portal_selections_url_string = here.portal_url.getRelativeContentURL( here.portal_selections) if sub_index is None: sub_index_string = '' else: sub_index_string = '_%s' % sub_index return ' <input type="image" ' \ 'src="%s/images/exec16.png" value="update..." ' \ 'name="%s/viewSearchRelatedDocumentDialog%s%s' \ ':method"/>' % \ (portal_url_string, portal_selections_url_string, relation_index, sub_index_string) def render_relation_link(self, field, value, REQUEST, render_prefix=None): """ Render link to the related object. """ html_string = '' here = REQUEST.get('cell', self._getContextValue(field, REQUEST)) portal_url = here.getPortalObject().portal_url portal_url_string = portal_url() if (value not in ((), [], None, '')) and \ field.get_value('allow_jump'): # Keep the selection name in the URL if REQUEST.get('selection_name') is not None: selection_name_html = '&selection_name=%s&selection_index=%s' % \ (REQUEST.get('selection_name'), REQUEST.get('selection_index')) else: selection_name_html = '' if REQUEST.get('ignore_layout') is not None: selection_name_html += '&ignore_layout:int=%s' % int( REQUEST.get('ignore_layout', 0)) # Generate plan link html_string += '<a href="%s/%s?field_id=%s&form_id=%s%s">' \ '<img src="%s/images/jump.png" alt="jump" />' \ '</a>' % \ (here.absolute_url(), field.get_value('jump_method'), field.id, field.aq_parent.id, selection_name_html, portal_url_string) return html_string
class ZGDChartWidget(Widget.Widget): """ This is the class used in order to include inside ERP5 some very nice charts """ property_names = Widget.Widget.property_names +\ ['selection_name','default_params','chart_title', 'data_method','chart_style','x_title','y_title', 'bg_transparent'] default = fields.TextAreaField( 'default', title='Default', description=("Default value of the text in the widget."), default="", width=20, height=3, required=0) selection_name = fields.StringField( 'selection_name', title='Selection Name', description=('The name of the selection to store' 'params of selection'), default='', required=0) data_method = fields.StringField( 'data_method', title='Data Method', description=('The method wich returns data'), default='', required=0) chart_style = fields.StringField('chart_style', title='Chart Style', description=('The kind of Chart we want'), default='bar_3d', required=0) chart_title = fields.StringField( 'chart_title', title='Chart Title', description=('The Title on the top of the chart'), default='', required=0) x_title = fields.StringField('x_title', title='X Title', description=('The Title for the X axis'), default='', required=0) y_title = fields.StringField('y_title', title='Y Title', description=('The Title for the Y axis'), default='', required=0) default_params = fields.ListTextAreaField( 'default_params', title="Default Parameters", description=("Default Parameters for the List Method."), default=[], required=0) bg_transparent = fields.CheckBoxField( 'bg_transparent', title='Transparent Background', description=('Allows to set the background transparent'), default='', required=0) def render(self, field, key, value, REQUEST, render_prefix=None): """ This is where most things happens """ main_content = "" here = REQUEST['here'] selection_name = field.get_value('selection_name') default_params = field.get_value('default_params') chart_title = field.get_value('chart_title') data_method = field.get_value('data_method') chart_style = field.get_value('chart_style') x_title = field.get_value('x_title') y_title = field.get_value('y_title') bg_transparent = field.get_value('bg_transparent') selection = here.portal_selections.getSelectionFor(selection_name, REQUEST=REQUEST) LOG( 'ZGDChart.render', 0, 'selection: %s, selection_name: %s' % (str(selection), str(selection_name))) # This is the default data, this is just in the case there is not method given data = {'chart_data': []} # Retrieve the data with the data_method if hasattr(here, data_method): LOG('ZGDChart.render', 0, 'found method') data_method = getattr(here, data_method) data['chart_data'] = data_method() data['chart_parameter'] = { 'zgdchart_runtime_title': chart_title, 'zgdchart_runtime_xtitle': x_title, 'zgdchart_runtime_ytitle': y_title, 'zgdchart_runtime_type': 'Line_3D', 'zgdchart_runtime_bg_transparent': bg_transparent } # Creation selection if needed if selection is None: selection = Selection(selection_name, params=data) else: LOG('ZGDChart.render', 0, 'selection is not None') kw = {'params': data} selection.edit(**kw) here.portal_selections.setSelectionFor(selection_name, selection, REQUEST=REQUEST) if len(data['chart_data']) > 0: main_content = """\ <div class="ChartContent"> <table border="0" cellpadding="0" cellspacing="0""> <tr> <td valign="middle" align="center" nowrap> <img src="%s" title="Chart" border="0" alt="img"/"> </td> </tr> </table> </div>""" % str(chart_style + '?selection_name=' + selection_name) return main_content
class POSBoxWidget(Widget.Widget): """ A widget that display a point of sales UI. """ property_names = Widget.Widget.property_names + [ 'html_ZPT', \ 'javascript_ZPT', \ 'css_ZPT', \ 'getResourceByReference_ZPT', \ 'createOrder_script', \ 'portal_types', \ 'display_fastResourceEntry', \ 'portal_type_fastResourceEntry', \ 'resource_category_fastResourceEntry', \ 'barcodeStartString', \ 'pos_layout', \ 'barcodeStopString', \ 'display_bgcolor', \ 'display_txtcolor', \ 'order_summary_aLine', \ 'order_summary_anotherLine' ] default = fields.StringField( 'default', title='Default', description=( "Default value of the text in the widget."), default="", required=0) html_ZPT = fields.StringField( 'html_ZPT', title='Page Template for HTML', description=( "Page Template for generating POSBox UI HTML"), default="POSBox", required=1) javascript_ZPT = fields.StringField( 'javascript_ZPT', title='Page Template for JavaScript', description=( "Page Template for generating JavaScript's options"), default="POSBox_js", required=1) css_ZPT = fields.StringField( 'css_ZPT', title="Page Template for CSS", description=( "Page Template for generating dynamic CSS"), default="POSBox_css", required=1) getResourceByReference_ZPT = fields.StringField( 'getResourceByReference_ZPT', title="Page Template for generating resource's XML", description=( "Page template which generates the XML of the resource when asking for a referencce"), default="getResourceByReference", required=1) createOrder_script = fields.StringField( 'createOrder_script', title="Python script for creating the order", description=( "Python script which create the order from the XML sended by POS"), default="createOrder", required=1) display_fastResourceEntry = fields.ListField( 'display_fastResourceEntry', title='Display Fast Resource Entry Block', description=( "Is the fast resource entry block displayed ?"), default='False', items=['True', 'False'], size=1, required=1, group="Fast Product Entry") portal_type_fastResourceEntry = fields.StringField( 'portal_type_fastResourceEntry', title='Portal Type of resources', description=( "What is the portal type of resources in fast resource entry block"), default='', required=0, group="Fast Product Entry") portal_types = fields.ListTextAreaField( 'portal_types', title='Portal Types', description=( "The allowed resource to be requested by reference. Required."), default=[], required=1) resource_category_fastResourceEntry = fields.StringField( 'resource_category_fastResourceEntry', title='Top level Resource Category', description=( "The ProductLine that is a the top level of fast resource entry"), default='', required=0, group="Fast Product Entry") pos_layout = fields.ListField( 'pos_layout', title='Layout', description=( "How is the layout organised"), default='', items=[ 'Summary of the order on the left' , 'Summary of the order on the right' , ], size=1, required=1) barcodeStartString = fields.StringField( 'barcodeStartString', title='Barcode Prefix String', description=( "The string which is prefixed by the barcode while reading"), default="#", required=1, group="barcode") barcodeStopString = fields.StringField( 'barcodeStopString', title='Barcode Suffix String', description=( "The string which is prefixed by the barcode while reading"), default="#", required=1, group="barcode") display_bgcolor = fields.StringField( 'display_bgcolor', title='Background color', description=( "Color in html hex format (#000000 by ex.)"), default="#ffffcc", required=0, group="display area") display_txtcolor = fields.StringField( 'display_txtcolor', title='Text color', description=( "Color in html hex format (#000000 by ex.)"), default="#000000", required=0, group="display area") order_summary_aLine = fields.StringField( 'order_summary_aLine', title="Order line background color 1", description=( "Background color of a order line in order summary view"), default="#e3e3e3", required=0, group="order summary") order_summary_anotherLine = fields.StringField( 'order_summary_anotherLine', title="Order line background color 2", description=( "Background color of another order line in order summary view"), default="#ffffff", required=0, group="order summary") def render(self, field, key, value, REQUEST, render_prefix=None): """ Render point of sales widget. """ here = REQUEST['here'] page_template = getattr(here,field.get_value("html_ZPT")) return "<!-- Generated by render -->\n%s" % page_template() def render_css(self, field, key, value, REQUEST): here = REQUEST['here'] page_template = getattr(here,field.get_value("css_ZPT")) return "<!-- Generated by render_css -->\n%s" % page_template( display_txtcolor = field.get_value("display_txtcolor"), display_bgcolor = field.get_value("display_bgcolor"), pos_layout_left = (field.get_value("pos_layout") == 'Summary of the order on the left'), order_summary_aLine = field.get_value("order_summary_aLine"), order_summary_anotherLine = field.get_value("order_summary_anotherLine"), fastResourceEntry_display = field.get_value("display_fastResourceEntry"), ) def render_javascript(self, field, key, value, REQUEST, render_prefix=None): here = REQUEST['here'] page_template = getattr(here,field.get_value("javascript_ZPT")) return "<!-- Generated by render_javascript -->\n%s" % page_template( getResourceByReference_ZPT = field.get_value('getResourceByReference_ZPT'), createOrder_script = field.get_value('createOrder_script'), portal_types = "portal_type:list=" + "&portal_type:list=".join([url_quote_plus(x[0]) for x in field.get_value('portal_types')]), barcodeStartString = field.get_value('barcodeStartString'), barcodeStopString = field.get_value('barcodeStopString'), fastResourceEntry_display = field.get_value("display_fastResourceEntry"), portal_type_fastResourceEntry = field.get_value('portal_type_fastResourceEntry'), resource_category_fastResourceEntry = field.get_value('resource_category_fastResourceEntry') ) def render_view(self, field, value, REQUEST=None, render_prefix=None): """ Render point of sales widget """ return "<p>Generated by render_view</p>"