Exemplo n.º 1
0
class FormBoxWidget(Widget.Widget):
    """
      A widget that display a form within a form.

      A first purpose of this widget is to display addresses in
      a different order for every localisation.

      A second purpose of this widget is to represent a single value
      (ex. a number, a date) into multiple forms. We need for that
      purpose a script to assemble a value out of

      A third purpose is to display values on subobjects and,
      if necessary, create such objects ?

      WARNING: this is still pre-alpha code for experimentation. Do not
      use in production.
  """

    property_names = Widget.Widget.property_names + [
      'formbox_target_id', \
      'context_method_id', \
    ]

    # This name was changed to prevent naming collision with ProxyField
    formbox_target_id = fields.StringField(
        'formbox_target_id',
        title='Form ID',
        description=("ID of the form which must be rendered in this box."),
        default="",
        required=0)

    context_method_id = fields.StringField(
        'context_method_id',
        title='Context method ID',
        description=("ID of the method that returns a context for this box."),
        default="",
        required=0)

    default = fields.StringField('default',
                                 title='Default',
                                 description=("A default value (not used)."),
                                 default="",
                                 required=0)

    def render_view(self, field, value, REQUEST, render_prefix=None):
        """
        Render a view form in a field
    """
        return self.render(field, None, value, REQUEST, render_prefix)

    def render(self, field, key, value, REQUEST, render_prefix=None):
        """
        Render a form in a field
    """
        target_id = field.get_value('formbox_target_id')
        if target_id:
            with getFormBoxContext(field, REQUEST) as context:
                return getattr(context, target_id)(REQUEST=REQUEST,
                                                   key_prefix=key)
        return ''
Exemplo n.º 2
0
class FormBoxWidget(Widget.Widget):
    """
      A widget that display a form within a form.

      A first purpose of this widget is to display addresses in
      a different order for every localisation.

      A second purpose of this widget is to represent a single value
      (ex. a number, a date) into multiple forms. We need for that
      purpose a script to assemble a value out of

      A third purpose is to display values on subobjects and,
      if necessary, create such objects ?

      WARNING: this is still pre-alpha code for experimentation. Do not
      use in production.
  """

    property_names = Widget.Widget.property_names + [
      'formbox_target_id', \
    ]

    # This name was changed to prevent naming collision with ProxyField
    formbox_target_id = fields.StringField(
        'formbox_target_id',
        title='Form ID',
        description=("ID of the form which must be rendered in this box."),
        default="",
        required=0)

    default = fields.StringField('default',
                                 title='Default',
                                 description=("A default value (not used)."),
                                 default="",
                                 required=0)

    def render(self, field, key, value, REQUEST, render_prefix=None):
        """
        Render a form in a field
    """
        here = REQUEST['here']
        # If 'cell' is not defined, we define 'cell' just same as 'here', so
        # that we can use the same formbox for both ListBox and non-ListBox
        # using 'cell' parameter.
        if not REQUEST.has_key('cell'):
            REQUEST.set('cell', here)
        result = ''
        target_id = field.get_value('formbox_target_id')
        if target_id not in (None, ''):
            try:
                form = getattr(here, target_id)
            except AttributeError:
                LOG('FormBox', WARNING,
                    'Could not get a form from formbox %s in %s' % \
                        (field.id, field.aq_parent.id))
            else:
                result = form(REQUEST=REQUEST, key_prefix=key)
        return result
Exemplo n.º 3
0
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
Exemplo n.º 4
0
class InputButtonWidget(Widget.Widget):
    """
    InputButton widget

    Displays an input button.

    """
    property_names = Widget.Widget.property_names + ['name', 'extra', 'image']

    default = fields.StringField(
        'default',
        title='Button text',
        description=
        ("You can place text here that will be used as the value (button text)"
         ),
        default="Submit",
        required=1)

    name = fields.StringField('name',
                              title='Name',
                              description=("The Name of the submit button."),
                              default='',
                              required=0)

    css_class = fields.StringField(
        'css_class',
        title='CSS class',
        description=(
            "The CSS class of the field. This can be used to style your "
            "formulator fields using cascading style sheets. Not required."),
        default="hidden_label",
        required=0)

    image = fields.StringField(
        'image',
        title='Image',
        description=("The image of the button (if any)."),
        default='',
        required=0)

    def render(self, field, key, value, REQUEST, render_prefix=None):
        """Render input button.
        """
        render_kw = {
            'name': field.get_value('name'),
            'css_class': field.get_value('css_class'),
            'value': field.get_value('default'),
            'extra': field.get_value('extra')
        }
        image = field.get_value('image')
        if image:
            html_type = "image"
            render_kw['src'] = image
        else:
            html_type = "submit"
        return Widget.render_element('input', type=html_type, **render_kw)
Exemplo n.º 5
0
class ProxyWidget(Widget.Widget):
    """
  A widget that renders itself as a field from another form
  after changing its title and id. It is recommended to define
  a master form on which complex fields with a lot of TALES
  are defined in order to minimize code duplication.
  """

    property_names = [
        'form_id',
        'field_id',
        'target',
    ]

    form_id = fields.StringField(
                                  'form_id',
                                  title='Form ID',
                                  description= \
                                    "ID of the master form.",
                                  default="",
                                  required=1)

    field_id = fields.StringField(
                                  'field_id',
                                  title='Field ID',
                                  description= \
                                    "ID of the field in the master form.",
                                  default="",
                                  required=1)

    target = fields.HyperLinkField(
        'target',
        title='Proxy Target',
        description="Link to the master field edit form",
        default='Click to edit the target',
        href='manage_edit_target',
        required=0)

    # Field API Methods, delegated to the template field widget
    render = WidgetDelegatedMethod('render', default='')
    render_htmlgrid = WidgetDelegatedMethod('render_htmlgrid', default='')
    render_view = WidgetDelegatedMethod('render_view', default='')
    render_pdf = WidgetDelegatedMethod('render_pdf', default='')
    render_css = WidgetDelegatedMethod('render_css', default='')
    render_dict = WidgetDelegatedMethod('render_dict', default=None)
    render_odf = WidgetDelegatedMethod('render_odf', default='')
    render_odt = WidgetDelegatedMethod('render_odt', default=None)
    render_odt_view = WidgetDelegatedMethod('render_odt_view', default=None)
    render_odt_variable = WidgetDelegatedMethod('render_odt_variable',
                                                default=None)
    render_odg = WidgetDelegatedMethod('render_odg', default=None)
    get_javascript_list = WidgetDelegatedMethod('get_javascript_list',
                                                default=[])
Exemplo n.º 6
0
class GadgetWidget(Widget.TextWidget):
    """
  A widget that displays a renderjs gadget
  """
    property_names = Widget.TextWidget.property_names + \
         ['gadget_url', 'js_sandbox']

    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 = {}
        kw['data-gadget-url'] = field.get_value('gadget_url')
        kw['data-gadget-scope'] = field.id
        if key is not None:
            kw['data-gadget-editable'] = key
        kw['class'] = "gadget"
        kw['data-gadget-value'] = value
        kw['data-gadget-sandbox'] = field.get_value('js_sandbox')
        return Widget.render_element("div", **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
Exemplo n.º 7
0
class PatternValidator(StringValidator):
    # does the real work
    checker = PatternChecker.PatternChecker()

    property_names = StringValidator.property_names + ['pattern']
    message_names = StringValidator.message_names + ['pattern_not_matched']

    pattern = fields.StringField(
        'pattern',
        title="Pattern",
        required=1,
        default="",
        description=(
            "The pattern the value should conform to. Patterns are "
            "composed of digits ('d'), alphabetic characters ('e') and "
            "alphanumeric characters ('f'). Any other character in the pattern "
            "should appear literally in the value in that place. Internal "
            "whitespace is checked as well but may be included in any amount. "
            "Example: 'dddd ee' is a Dutch zipcode (postcode). "))

    pattern_not_matched = _("The entered value did not match the pattern.")

    def check(self, field, value, failover=False):
        value = StringValidator.check(self, field, value, failover)
        if not failover and value:
            result = self.checker.validate_value([field.get_value('pattern')],
                                                 value)
            if result is None:
                self.raise_error('pattern_not_matched', field)
            return result
        return value
Exemplo n.º 8
0
class TextWidget(Widget):
    """Text widget
    """
    property_names = Widget.property_names +\
                     ['display_width', 'display_maxwidth', 'extra']

    default = fields.StringField(
        'default',
        title='Default',
        description=(
            "You can place text here that will be used as the default "
            "value of the field, unless the programmer supplies an override "
            "when the form is being generated."),
        default="",
        required=0)

    display_width = fields.IntegerField(
        'display_width',
        title='Display width',
        description=("The width in characters. Required."),
        default=20,
        required=1)

    display_maxwidth = fields.IntegerField(
        'display_maxwidth',
        title='Maximum input',
        description=(
            "The maximum input in characters that the widget will allow. "
            "Required. If set to 0 or is left empty, there is no maximum. "
            "Note that is client side behavior only."),
        default="",
        required=0)

    def render(self, field, key, value, REQUEST):
        """Render text input field.
        """
        extra = field.get_value('extra')
        css_class = field.get_value('css_class')
        kw = {
            'type': "text",
            'name': key,
            'css_class': css_class,
            'value': value,
            'size': field.get_value('display_width'),
            'extra': extra
        }
        if not extra or not id_value_re.search(extra):
            kw['id'] = field.generate_field_html_id(key)
        display_maxwidth = field.get_value('display_maxwidth') or 0
        if display_maxwidth > 0:
            kw['maxlength'] = display_maxwidth
        contents = render_element("input", **kw)
        return render_element("div", contents=contents, css_class=css_class)

    def render_view(self, field, value):
        return render_value(value)
Exemplo n.º 9
0
class ReportBoxWidget(Widget.Widget):

    property_names = list(Widget.Widget.property_names)
    property_names.append('report_method')

    # XXX this is only needed on bootstrap
    default = fields.StringField('default',
                                 title='Default',
                                 description="",
                                 default="",
                                 required=0)

    report_method = fields.StringField('report_method',
                                       title='Report Method',
                                       description="",
                                       default="",
                                       required=0)

    def render_view(self,
                    field,
                    value,
                    REQUEST=None,
                    key='reportbox',
                    render_prefix=None):
        """
    """
        if REQUEST is None:
            REQUEST = get_request()
        return self.render(field, key, value, REQUEST)

    def render(self, field, key, value, REQUEST, render_prefix=None):
        """
    """
        form = getattr(field, 'aq_parent', None)
        if form is not None:
            obj = getattr(form, 'aq_parent', None)
        else:
            obj = None
        if obj is not None:
            report_method = guarded_getattr(obj, field['report_method'])
            if callable(report_method):
                return report_method()
Exemplo n.º 10
0
def create_settings_form():
    form = Form_create_settings_form()
    report_method = fields.StringField(
        'report_method',
        title='Report Method',
        description=('The method to get a list of items (object, form,'
                     ' parameters) to aggregate in a single Report'),
        default='',
        required=0)

    form.add_fields([report_method])
    return form
Exemplo n.º 11
0
class FormBoxValidator(Validator.Validator):
  """
    Validate all fields of the form and return
    the result as a single variable.
  """
  validator_form_field_prefix = fields.StringField(
    'validator_form_field_prefix',
    title='Validator Form Field Prefix',
    description= "Field prefix value used when validating fields",
    default="my_",
    display_width=40,
    required=1
  )

  property_names = Validator.Validator.property_names + \
                   ['validator_form_field_prefix']
  message_names = Validator.Validator.message_names + \
                  ['form_invalidated', 'required_not_found']

  form_invalidated = "Form invalidated."
  required_not_found = 'Input is required but no input given.'

  def validate(self, field, key, REQUEST):
    # TODO: Handle 'cell' for validation inside listboxes,
    #       like it is done for rendering.
    formbox_target_id = field.get_value('formbox_target_id')
    if not formbox_target_id:
      return None
    # Get current error fields
    current_field_errors = REQUEST.get('field_errors', [])

    with getFormBoxContext(field, REQUEST) as here:
      # XXX Hardcode script name
      result, result_type = here.Base_edit(formbox_target_id, silent_mode=1, key_prefix=key,
                                           field_prefix=field.get_value('validator_form_field_prefix'))
      if result_type == 'edit':
        return FormBoxEditor(result, here)
      elif result_type == 'form':
        formbox_field_errors = REQUEST.get('field_errors', [])
        current_field_errors.extend(formbox_field_errors)
        REQUEST.set('field_errors', current_field_errors)
        getattr(here, formbox_target_id).validate_all_to_request(REQUEST, key_prefix=key)
      else:
        raise NotImplementedError(result_type)
Exemplo n.º 12
0
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)
Exemplo n.º 13
0
class LinesTextAreaWidget(TextAreaWidget):
    property_names = Widget.property_names +\
                     ['width', 'height', 'view_separator', 'extra']

    default = fields.LinesField(
        'default',
        title='Default',
        description=("Default value of the lines in the widget."),
        default=[],
        width=20,
        height=3,
        required=0)

    view_separator = fields.StringField(
        'view_separator',
        title='View separator',
        description=(
            "When called with render_view, this separator will be used to "
            "render individual items."),
        width=20,
        default='<br />\n',
        whitespace_preserve=1,
        required=1)

    def render(self, field, key, value, REQUEST):
        if is_sequence(value):
            value = string.join(value, "\n")
        return TextAreaWidget.render(self, field, key, value, REQUEST)

    def render_view(self, field, value):
        return render_value(value, field.get_value('view_separator'))

    def render_hidden(self, field, key, value, REQUEST):
        if value is None:
            return ''
        if is_sequence(value):
            value = '\n'.join(value)
        # reuse method from base class
        return Widget.render_hidden(self, field, key, value, REQUEST)
Exemplo n.º 14
0
Arquivo: Form.py Projeto: poses/erp5
def create_settings_form():
    """Create settings form for ZMIForm.
    """
    form = BasicForm('manage_settings')

    title = fields.StringField('title',
                               title="Title",
                               required=0,
                               default="")
    description = fields.TextAreaField('description',
                               title="Description",
                               required=0,
                               default="")
    row_length = fields.IntegerField('row_length',
                                     title='Number of groups in row (in order tab)',
                                     required=1,
                                     default=4)
    name = fields.StringField('name',
                              title="Form name",
                              required=0,
                              default="")
    pt = fields.StringField('pt',
                              title="Page Template",
                              required=0,
                              default="")
    action = fields.StringField('action',
                                title='Form action',
                                required=0,
                                default="")
    update_action = fields.StringField('update_action',
                                title='Form update action',
                                required=0,
                                default="")
    update_action_title = fields.StringField('update_action_title',
                               title="Update Action Title",
                               required=0,
                               default="")
    method = fields.ListField('method',
                              title='Form method',
                              items=[('POST', 'POST'),
                                     ('GET', 'GET')],
                              required=1,
                              size=1,
                              default='POST')
    enctype = fields.ListField('enctype',
                               title='Form enctype',
                               items=[('No enctype', ""),
                                      ('application/x-www-form-urlencoded',
                                       'application/x-www-form-urlencoded'),
                                      ('multipart/form-data',
                                       'multipart/form-data')],
                               required=0,
                               size=1,
                               default=None)
    encoding = fields.StringField('encoding',
                                  title='Encoding of pages the form is in',
                                  default="UTF-8",
                                  required=1)
    stored_encoding = fields.StringField('stored_encoding',
                                      title='Encoding of form properties',
                                      default='UTF-8',
                                      required=1)
    unicode_mode = fields.CheckBoxField('unicode_mode',
                                        title='Form properties are unicode',
                                        default=0,
                                        required=1)
    edit_order = fields.LinesField('edit_order',
                                   title='Setters for these properties should be'
                                   '<br /> called by edit() in the defined order')

    form.add_fields([title, description, row_length, name, pt, action, update_action, update_action_title,
                     method, enctype, encoding, stored_encoding, unicode_mode, edit_order])
    return form
Exemplo n.º 15
0
 def getExtraPropertyList(self):
     return [
         fields.StringField(**self._dynamic_property_list[0]),
         fields.PasswordField(**self._dynamic_property_list[1]),
         fields.CheckBoxField(**self._dynamic_property_list[2])
     ]
Exemplo n.º 16
0
class MultiItemsWidget(ItemsWidget):
    """A widget with a number of items that has multiple selectable
    items.
    """
    default = fields.LinesField(
        'default',
        title='Default',
        description=(
            "The initial selections of the widget. This is a list of "
            "zero or more values. If you override this property from Python "
            "your code should return a Python list."),
        width=20,
        height=3,
        default=[],
        required=0)

    view_separator = fields.StringField(
        'view_separator',
        title='View separator',
        description=(
            "When called with render_view, this separator will be used to "
            "render individual items."),
        width=20,
        default='<br />\n',
        whitespace_preserve=1,
        required=1)

    def render_items(self, field, key, value, REQUEST):
        # need to deal with single item selects
        if not is_sequence(value):
            value = [value]

        items = field.get_value('items')
        css_class = field.get_value('css_class')
        extra_item = field.get_value('extra_item')
        field_html_id = field.generate_field_html_id(key)
        index = 0
        rendered_items = []
        for item in items:
            index += 1
            if is_sequence(item):
                item_text, item_value = item
            else:
                item_text = item
                item_value = item

            if item_value in value:
                rendered_item = self.render_selected_item(
                    item_text, item_value, key, css_class, extra_item,
                    field_html_id + str(index))
            else:
                rendered_item = self.render_item(item_text, item_value, key,
                                                 css_class, extra_item,
                                                 field_html_id + str(index))

            rendered_items.append(rendered_item)

        return rendered_items

    def render_items_view(self, field, value):
        if not is_sequence(value):
            value = [value]

        items = field.get_value('items')
        d = {}
        for item in items:
            if is_sequence(item):
                item_text, item_value = item
            else:
                item_text = item
                item_value = item
            d[item_value] = item_text
        result = []
        for e in value:
            result.append(d[e])
        return result

    def render_view(self, field, value):
        if value is None:
            return ''
        return render_value(self.render_items_view(field, value),
                            field.get_value('view_separator'))

    def render_hidden(self, field, key, value, REQUEST):
        if value is not None and not is_sequence(value):
            value = [value]
        # reuse method from base class
        render_item_hidden = Widget.render_hidden
        result = []
        for v in value:
            result.append(render_item_hidden(self, field, key, v, REQUEST))
        return ''.join(result)
Exemplo n.º 17
0
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>"
Exemplo n.º 18
0
class VideoWidget(Widget.TextWidget):
    """
  A widget that displays a Video HTML element.
  This widget is intended to be used in
  conjunction with WebSite.
  """
    property_names = Widget.TextWidget.property_names + \
            ['video_controls', 'video_error_message', 'video_loop', \
                'video_width', 'video_height', 'video_preload', \
                'video_autoplay', 'js_enabled', 'video_player']

    video_controls = fields.CheckBoxField(
        'video_controls',
        title='Video Controls',
        description=("Controls to be used in Video Player."),
        default=1,
        required=0)

    video_error_message = fields.StringField(
        'video_error_message',
        title='Video Error Message',
        description=("Error message to be showed when \
          user's browser does not support the video tag."),
        default='Your browser does not support video tag.',
        required=0)

    video_loop = fields.CheckBoxField(
        'video_loop',
        title='Video Loop',
        description=("Specifies that the video file \
          will start over again, every time it is finished."),
        default=0,
        required=0)

    video_width = fields.IntegerField(
        'video_width',
        title='Video Width',
        description=("The width to be used when playing the video."),
        default=160,
        required=0)

    video_height = fields.IntegerField(
        'video_height',
        title='Video Height',
        description=("The height to be used when playing the video."),
        default=85,
        required=0)

    video_preload = fields.CheckBoxField(
        'video_preload',
        title='Video Preload',
        description=("Configure that you would like to \
      start downloading the video file as soon as possible."),
        default=1,
        required=0)

    video_autoplay = fields.CheckBoxField(
        'video_autoplay',
        title='Video Autoplay',
        description=("Configure that you would like to \
      start downloading and playing the video file as soon as possible."),
        default=0,
        required=0)

    js_enabled = fields.CheckBoxField(
        'js_enabled',
        title='Enable on the fly video player change (based on java script)',
        description=
        'Define if javascript is enabled or not on the current Video',
        default=1,
        required=0)

    video_player = fields.ListField(
        'video_player',
        title='Video Player',
        description=("The video player to be used to show video."),
        default="html5_video",
        required=1,
        size=1,
        items=[
            ('HTML5 Video', 'html5_video'),
            ('Flowplayer', 'flowplayer'),
        ])

    def render(self, field, key, value, REQUEST, render_prefix=None):
        return self.render_view(field, value, REQUEST, render_prefix)

    def render_view(self, field, value, REQUEST=None, render_prefix=None):
        if value is None:
            return ''
        video_player = field.get_value('video_player')
        if video_player == 'html5_video':
            extra_kw = {}
            if field.get_value('video_autoplay'):
                extra_kw['autoplay'] = 'autoplay'
            if field.get_value('video_controls'):
                extra_kw['controls'] = 'controls'
            if field.get_value('video_loop'):
                extra_kw['loop'] = 'loop'
            if field.get_value('video_preload'):
                extra_kw['preload'] = 'preload'
            return Widget.render_element(
                "video",
                src=value,
                extra=field.get_value('extra'),
                width=field.get_value('video_width'),
                height=field.get_value('video_height'),
                contents=field.get_value('video_error_message'),
                **extra_kw)
        elif video_player == 'flowplayer':
            a_element = Widget.render_element("a",
                              href="%s" % value,
                              style="display:block;width:%spx;height:%spx;" % \
                                              (field.get_value('video_width'),
                                               field.get_value('video_height'),),
                              id="player")

            script_element = """<script language="JavaScript">
                             flowplayer("player", "%s/flowplayer.swf");
                         </script>""" % self.getContext(
                field, REQUEST).getPortalObject().portal_url()
            return ' '.join([a_element, script_element])

    def get_javascript_list(self, field, REQUEST=None):
        """
    Returns list of javascript needed by the widget
    """
        if field.get_value('js_enabled'):
            video_player = field.get_value('video_player')
            context = self.getContext(field, REQUEST)
            if video_player == 'html5_video':
                # XXX Instead of harcoding library name
                # it should be better to call a python script, as
                # it is done on type base method.
                return ['%s/html5media.min.js' % context.portal_url()]
            elif video_player == 'flowplayer':
                return ['%s/flowplayer.min.js' % context.portal_url()]
        else:
            return []

    def getContext(self, field, REQUEST):
        """Return the context of rendering this Field.
    """
        value = REQUEST.get('here')
        if value is None:
            value = self.getForm(field).aq_parent
        return value

    def getForm(self, field):
        """Return the form which contains the Field.
    """
        return field.aq_parent
Exemplo n.º 19
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 = 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 += '&nbsp;%s&nbsp;' % \
                                          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 += '&nbsp;&nbsp;%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 += '&nbsp;&nbsp;%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 '&nbsp;<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 = '&amp;selection_name=%s&amp;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 += '&amp;ignore_layout:int=%s' % int(
                    REQUEST.get('ignore_layout', 0))
            # Generate plan link
            html_string += '<a href="%s/%s?field_id=%s&amp;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
Exemplo n.º 20
0
class DateTimeWidget(Widget):
    property_names = Widget.property_names +\
                     ['default_now', 'date_separator', 'time_separator',
                      'input_style', 'input_order',
                      'date_only', 'hide_day', 'ampm_time_style', 'calendar_picker', 'calendar_start']

    default = fields.DateTimeField('default',
                                   title="Default",
                                   description=("The default datetime."),
                                   default=None,
                                   display_style="text",
                                   display_order="ymd",
                                   input_style="text",
                                   required=0)

    default_now = fields.CheckBoxField(
        'default_now',
        title="Default to now",
        description=(
            "Default date and time will be the date and time at showing of "
            "the form (if the default is left empty)."),
        default=0)

    date_separator = fields.StringField(
        'date_separator',
        title='Date separator',
        description=("Separator to appear between year, month, day."),
        default="/",
        required=0,
        display_width=2,
        display_maxwith=2,
        max_length=2)

    time_separator = fields.StringField(
        'time_separator',
        title='Time separator',
        description=("Separator to appear between hour and minutes."),
        default=":",
        required=0,
        display_width=2,
        display_maxwith=2,
        max_length=2)

    input_style = fields.ListField(
        'input_style',
        title="Input style",
        description=("The type of input used. 'text' will show the date part "
                     "as text, while 'list' will use dropdown lists instead."),
        default="text",
        items=[("text", "text"), ("list", "list")],
        size=1)

    input_order = fields.ListField(
        'input_order',
        title="Input order",
        description=("The order in which date input should take place. Either "
                     "year/month/day, day/month/year or month/day/year."),
        default="ymd",
        items=[("year/month/day", "ymd"), ("day/month/year", "dmy"),
               ("month/day/year", "mdy")],
        required=1,
        size=1)

    date_only = fields.CheckBoxField(
        'date_only',
        title="Display date only",
        description=("Display the date only, not the time."),
        default=0)

    hide_day = fields.CheckBoxField('hide_day',
                                    title="Hide day field",
                                    description=("Hide the day field."),
                                    default=0)

    ampm_time_style = fields.CheckBoxField(
        'ampm_time_style',
        title="AM/PM time style",
        description=("Display time in am/pm format."),
        default=0)
    calendar_picker = fields.CheckBoxField(
        'calendar_picker',
        title="Enable calendar picker",
        description=
        ("Displays a floating calendar to select the date.  "
         "The js calendar is located here: http://www.dynarch.com/projects/calendar/old/"
         ),
        default=0)

    calendar_start = fields.ListField(
        'calendar_start',
        title="Starting day of week",
        description=(
            "The starting day of the week for the floating calendar."),
        default="Sunday",
        items=[
            ("Sunday", "0"),
            ("Monday", "1"),
            ("Tuesday", "2"),
            ("Wednesday", "3"),
            ("Thursday", "4"),
            ("Friday", "5"),
            ("Saturday", "6"),
        ],
        required=0,
        size=1)

    has_html_id = False

    # FIXME: do we want to handle 'extra'?

    def render(self, field, key, value, REQUEST):
        use_ampm = field.get_value('ampm_time_style')
        hide_day = field.get_value('hide_day')
        calendar_picker = field.get_value('calendar_picker')
        start_day = field.get_value('calendar_start')
        # FIXME: backwards compatibility hack:
        if not hasattr(field, 'sub_form'):
            from StandardFields import create_datetime_text_sub_form
            field.sub_form = create_datetime_text_sub_form()

        if value is None and field.get_value('default_now'):
            value = DateTime()

        # Allow subfields to get their values even when default_now is set.
        if REQUEST is not None and \
                   REQUEST.form.has_key(field.generate_subfield_key('year')):
            value = None

        if value is None:
            year = None
            month = None
            day = None
            hour = None
            minute = None
            ampm = None
        else:
            if not isinstance(value, DateTime):
                value = DateTime(value)
            year = "%04d" % value.year()
            month = "%02d" % value.month()
            day = "%02d" % value.day()
            if use_ampm:
                hour = "%02d" % value.h_12()
            else:
                hour = "%02d" % value.hour()
            minute = "%02d" % value.minute()
            ampm = value.ampm()

        input_order = field.get_value('input_order')
        if input_order == 'ymd':
            order = [('year', year), ('month', month), ('day', day)]
        elif input_order == 'dmy':
            order = [('day', day), ('month', month), ('year', year)]
        elif input_order == 'mdy':
            order = [('month', month), ('day', day), ('year', year)]
        result = []
        hidden_day_part = ""
        for sub_field_name, sub_field_value in order:
            if hide_day and (sub_field_name == 'day'):
                dayvalue = sub_field_value
                if dayvalue is None:
                    dayvalue = "01"
                sub_key = field.generate_subfield_key(sub_field_name)
                sub_field = field.sub_form.get_field(sub_field_name)
                hidden_day_part = sub_field.widget.\
                                  render_hidden(sub_field, sub_key,
                                                dayvalue, REQUEST)
            else:
                result.append(
                    field.render_sub_field(sub_field_name, sub_field_value,
                                           REQUEST))
        date_result = string.join(result, field.get_value('date_separator'))

        day_id = field.sub_form.get_field('day').generate_field_html_id(
            "subfield_" + field.id + "_day")
        month_id = field.sub_form.get_field('month').generate_field_html_id(
            "subfield_" + field.id + "_month")
        year_id = field.sub_form.get_field('year').generate_field_html_id(
            "subfield_" + field.id + "_year")

        select_day = ''
        if hidden_day_part:
            date_result += hidden_day_part
        else:
            #get the proper html id
            select_day = 'document.getElementById("' + day_id + '").value = RegExp.$3;'
        calendar_popup = ''
        html_id = field.generate_field_html_id(key)
        if calendar_picker:
            calendar_popup = '&nbsp;' + render_element(
                'button',
                css_class='kupu-button kupu-link-reference calendar-button',
                style='padding: 0px 0px 0px 0px',
                id=html_id + '_calendar',
                title='set date',
                contents=' ') + """<script type="text/javascript">
setTimeout(function(){Calendar.setup({inputField : '%s_hiddeninput',
                ifFormat : '%%Y/%%m/%%d %%%s:%%M %%P',
                showsTime : '%s',
                button : '%s_calendar',
                weekNumbers: false,
                timeFormat: '%s',
                date: (new Date()).setHours(0,0,0,0),
                firstDay: '%s'})},100);</script>""" % (
                    html_id,
                    use_ampm and 'I' or 'H',
                    field.get_value('date_only') and 'false' or 'true',
                    html_id,
                    use_ampm and '12' or '24',
                    start_day,
                )
        if not field.get_value('date_only'):
            time_result = (field.render_sub_field('hour', hour, REQUEST) +
                           field.get_value('time_separator') +
                           field.render_sub_field('minute', minute, REQUEST))

            hour_id = field.sub_form.get_field('hour').generate_field_html_id(
                "subfield_" + field.id + "_hour")
            minute_id = field.sub_form.get_field(
                'minute').generate_field_html_id("subfield_" + field.id +
                                                 "_minute")
            ampm_id = field.sub_form.get_field('ampm').generate_field_html_id(
                "subfield_" + field.id + "_ampm")
            if use_ampm:
                time_result += '&nbsp;' + field.render_sub_field(
                    'ampm', ampm, REQUEST)
            calendar_popup += calendar_picker and render_element(
                'input',
                type='hidden',
                id=html_id + '_hiddeninput',
                onchange=
                'var pattern = /(\d{4})\/(\d{2})\/(\d{2}) (\d{2}):(\d{2}) (am|pm)/; if (pattern.exec(this.value)) { document.getElementById("'
                + year_id + '").value = RegExp.$1; document.getElementById("' +
                month_id + '").value = RegExp.$2; ' + select_day +
                ' document.getElementById("' + hour_id +
                '").value = RegExp.$4; document.getElementById("' + minute_id +
                '").value = RegExp.$5; ' +
                str(use_ampm and 'document.getElementById("' + ampm_id +
                    '").value = RegExp.$6;' or '') + ' }') or ''
            return date_result + '&nbsp;&nbsp;&nbsp;' + time_result + calendar_popup
        else:
            calendar_popup += calendar_picker and render_element(
                'input',
                type='hidden',
                id=html_id + '_hiddeninput',
                onchange=
                'var pattern = /(\d{4})\/(\d{2})\/(\d{2}) (\d{2}):(\d{2}) (am|pm)/; if (pattern.exec(this.value)) { document.getElementById("'
                + year_id + '").value = RegExp.$1; document.getElementById("' +
                month_id + '").value = RegExp.$2; ' + select_day + ' }') or ''
            return date_result + calendar_popup

    def render_hidden(self, field, key, value, REQUEST):
        result = []
        if value is None and field.get_value('default_now'):
            value = DateTime()
        sub_values = {}
        subfields = ['year', 'month', 'day']
        if value is not None:
            if not isinstance(value, DateTime):
                value = DateTime(value)
            sub_values['year'] = '%04d' % value.year()
            sub_values['month'] = "%02d" % value.month()
            sub_values['day'] = "%02d" % value.day()
            if not field.get_value('date_only'):
                use_ampm = field.get_value('ampm_time_style')
                subfields.extend(['hour', 'minute'])
                if use_ampm: subfields.append('ampm')
                if value is not None:
                    if use_ampm:
                        sub_values['hour'] = "%02d" % value.h_12()
                        sub_values['ampm'] = value.ampm()
                    else:
                        sub_values['hour'] = "%02d" % value.hour()
                    sub_values['minute'] = "%02d" % value.minute()
        for subfield in subfields:
            # XXX it would be nicer to pass the hidden value somewhere
            # to the subfields, but ...
            sub_key = field.generate_subfield_key(subfield)
            sub_field = field.sub_form.get_field(subfield)
            result.append(
                sub_field.widget.render_hidden(sub_field, sub_key,
                                               sub_values.get(subfield),
                                               REQUEST))
        return ''.join(result)

    def render_view(self, field, value):
        if value is None:
            return ''

        use_ampm = field.get_value('ampm_time_style')

        if not isinstance(value, DateTime):
            value = DateTime(value)
        year = "%04d" % value.year()
        month = "%02d" % value.month()
        day = "%02d" % value.day()
        if use_ampm:
            hour = "%02d" % value.h_12()
        else:
            hour = "%02d" % value.hour()
        minute = "%02d" % value.minute()
        ampm = value.ampm()

        order = field.get_value('input_order')
        if order == 'ymd':
            output = [year, month, day]
        elif order == 'dmy':
            output = [day, month, year]
        elif order == 'mdy':
            output = [month, day, year]
        date_result = string.join(output, field.get_value('date_separator'))

        if not field.get_value('date_only'):
            time_result = hour + field.get_value('time_separator') + minute
            if use_ampm:
                time_result += '&nbsp;' + ampm
            return date_result + '&nbsp;&nbsp;&nbsp;' + time_result
        else:
            return date_result
Exemplo n.º 21
0
class ParallelListWidget(Widget.MultiListWidget, Widget.ListWidget):
    """
      Make the MultilistField more usable for the user.

      ParallelListWidget display a list of (Multi)ListField.
      Each can be required.

      Separation of items list is made with a Hash Script, which take
      the items list in input, and return a list of dictionnaries.

      Each dictionnary describes a (Multi)ListField.
      The keys are:
        - key:
            default: default
        - required: {1, 0}
            default: 0
        - field_type: {ListField, MultiListField}
            default: MultiListField
        - item_list: [(display, value), ...]
            default: []
        - value:
            default: []
        - is_right_display: {1, 0}
            default: 0
    """

    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.MultiListWidget.property_names +
      Widget.ListWidget.property_names + ['hash_script_id'])

    hash_script_id = fields.StringField(
        'hash_script_id',
        title='Hash script',
        description=("The method to call to hash items list."),
        required=0)

    def __init__(self):
        """
      Generate some subwidget used for rendering.
      """
        self.sub_widget = {
            'ListField': Widget.ListWidgetInstance,
            'MultiListField': Widget.MultiListWidgetInstance,
        }

    def render(self, field, key, value, REQUEST, render_prefix=None):
        hash_list = generateSubForm(field, value, REQUEST)
        # Call render on each sub field
        sub_field_render_list = []
        for sub_field_property_dict in hash_list:
            sub_field_render_list.append(
                self.render_sub_field(field, key,
                                      sub_field_property_dict['value'],
                                      REQUEST, sub_field_property_dict))
        # Aggregate all renders
        html_string = field.get_value('view_separator').\
                                  join(sub_field_render_list)
        return html_string

    def render_htmlgrid(self, field, key, value, REQUEST, render_prefix=None):
        hash_list = generateSubForm(field, value, REQUEST)
        # Call render on each sub field
        sub_field_render_list = []
        for sub_field_property_dict in hash_list:
            sub_field_render_list.append(
                (sub_field_property_dict['title'],
                 self.render_sub_field(field, key,
                                       sub_field_property_dict['value'],
                                       REQUEST, sub_field_property_dict)))
        return sub_field_render_list

    def render_sub_field(self,
                         field,
                         key,
                         value,
                         REQUEST,
                         sub_field_property_dict,
                         render_prefix=None):
        """
      Render dynamically a subfield
      """
        for parameter in ('title', 'required', 'size'):
            REQUEST.set(KEYWORD % parameter,
                        sub_field_property_dict[parameter])
        REQUEST.set(KEYWORD % 'default', "")
        REQUEST.set(KEYWORD % 'first_item', 0)
        REQUEST.set(KEYWORD % 'items', sub_field_property_dict['item_list'])
        sub_widget = self.sub_widget[sub_field_property_dict['field_type']]
        if sub_field_property_dict.get('editable', 1):
            result = sub_widget.render(field,
                                       field.generate_subfield_key(
                                           sub_field_property_dict['key'],
                                           key=key),
                                       sub_field_property_dict['value'],
                                       REQUEST=REQUEST)
        else:
            result = sub_widget.render_view(field,
                                            sub_field_property_dict['value'],
                                            REQUEST)
        for parameter in ('title', 'required', 'size', 'default', 'first_item',
                          'items'):
            # As it doesn't seem possible to delete value in the REQUEST,
            # use a marker
            REQUEST.set(KEYWORD % parameter, MARKER)
        return result

    def render_odt(self, field, value, as_string, ooo_builder, REQUEST,
                   render_prefix, attr_dict, local_name):
        """
      """
        return Widget.MultiListWidget.render_odt(self, field, value, as_string,
                                                 ooo_builder, REQUEST,
                                                 render_prefix, attr_dict,
                                                 local_name)

    def render_odt_view(self, field, value, as_string, ooo_builder, REQUEST,
                        render_prefix, attr_dict, local_name):
        """
      """
        return Widget.MultiListWidget.render_odt_view(self, field, value,
                                                      as_string, ooo_builder,
                                                      REQUEST, render_prefix,
                                                      attr_dict, local_name)
Exemplo n.º 22
0
class ImageFieldWidget(Widget.TextWidget):
    """ImageField widget.

    Renders an HTML <img> element where the src is the 'default' field value.
    The 'description' field value is used as 'alt' attribute.
    The image size is calculated using 'image_display'.
    """
    property_names = Widget.TextWidget.property_names + \
      ['image_display', 'image_format','image_quality', 'image_pre_converted_only']

    image_display = fields.StringField(
        'image_display',
        title='Image Display',
        description=
        ("The display size. See erp5.component.document.Image.default_displays_id_list "
         "for possible values. This is only used with ERP5 Images."),
        default='thumbnail',
        required=0)

    image_format = fields.StringField(
        'image_format',
        title='Image Format',
        description=("The format in which the image should be converted to. "
                     "This is only used with ERP5 Images."),
        default='',
        required=0)

    image_quality = fields.IntegerField(
        'image_quality',
        title='Image Quality',
        description=("The quality used when converting the image. "
                     "This is only used with ERP5 Images."),
        default=75,
        required=0)

    image_pre_converted_only = fields.CheckBoxField(
        'image_pre_converted_only',
        title='Image Pre Converted Only',
        description=(
            "Return image only if it is already pre converted in cache. "
            "This is only used with ERP5 Images."),
        default=False,
        required=0)

    def render(self, field, key, value, REQUEST, render_prefix=None):
        """Render image field as a link to the image
        """
        return self.render_view(field, value, REQUEST=REQUEST)

    def render_view(self, field, value, REQUEST=None, render_prefix=None):
        """Render image field as a link to the image
        """
        # Url is already defined in value
        if value is None:
            return ''
        image = value
        alt = field.get_value('description') or \
              field.get_value('title')
        css_class = field.get_value('css_class')
        extra = field.get_value('extra')
        options = {}
        options['display'] = field.get_value('image_display')
        options['format'] = field.get_value('image_format')
        options['quality'] = field.get_value('image_quality')
        pre_converted_only = field.get_value('image_pre_converted_only')
        if pre_converted_only:
            # only add if it's True as conversion machine assume that if it is missing
            # then conversion should happen "on the fly"
            options['pre_converted_only'] = pre_converted_only
        parameters = '&'.join(['%s=%s' % (k, v) for k, v in options.items() \
                               if v])
        if parameters:
            image = '%s?%s' % (image, parameters)
        return Widget.render_element(
            "img",
            alt=alt,
            src=image,
            css_class=css_class,
            extra=extra,
        )

    def render_odg_view(self, field, value, as_string, ooo_builder, REQUEST,
                        render_prefix, attr_dict, local_name):
        """
        return an image xml node rendered in odg format
        if as_string is True (default) the returned value is a string (xml
        reprensation of the node), if it's False, the value returned is the node
        object.
        attr_dict can be used for additional parameters (like style).
      """
        if attr_dict is None:
            attr_dict = {}
        draw_frame_node = None
        if value in ('', None):
            return None
        path = '/'.join(REQUEST.physicalPathFromURL(value))
        path = path.encode()
        image_object = field.getPortalObject().restrictedTraverse(path)
        display = field.get_value('image_display')
        format = field.get_value('image_format')
        quality = field.get_value('image_quality')
        image_parameter_dict = {'format': format}
        if display:
            image_parameter_dict['display'] = display
        if quality:
            image_parameter_dict['quality'] = quality
        # convert the image using fields parameters. In this way, if an image
        # is displayed in the form as a thumbnail, it will be added in the odg
        # document as thumbnail size/quality
        content_type, image_data = image_object.convert(**image_parameter_dict)
        image = OFSImage('', '', image_data)
        width = image.width
        height = image.height
        if image_data is None:
            return draw_frame_node

        # Big images are cut into smaller chunks, so it's required to cast to
        # str. See OFS/Image -> _read_data method for more information
        image_data = str(image_data)

        format = content_type.split('/')[-1]
        # add the image to the odg document
        picture_path = ooo_builder.addImage(image=image_data,
                                            format=format,
                                            content_type=content_type)

        # create the xml nodes related to the image
        draw_frame_tag_name = '{%s}%s' % (DRAW_URI, 'frame')
        draw_frame_node = Element(draw_frame_tag_name, nsmap=NSMAP)
        draw_frame_node.attrib.update(
            attr_dict.get(draw_frame_tag_name, {}).pop(0))

        # set the size of the image
        if display is not None:
            # if the image width and height are not on defined, use current
            # width and height
            if (image_object.getWidth(), image_object.getHeight()) not in \
              ((-1, -1), (0,0)):
                width, height = image_object._getAspectRatioSize(width, height)
                if draw_frame_node.attrib.get('{%s}width' % SVG_URI) and \
                  draw_frame_node.attrib.get('{%s}height' % SVG_URI):
                    # if a size already exist from attr_dict, try to resize the image to
                    # fit this size (image should not be biger than size from attr_dict)
                    # devide the value by 20 to have cm instead of px
                    width, height = self._getPictureSize(
                        width / 20.,
                        height / 20.,
                        target_width=draw_frame_node.attrib.get(
                            '{%s}width' % SVG_URI, ''),
                        target_height=draw_frame_node.attrib.get(
                            '{%s}height' % SVG_URI, ''))

                draw_frame_node.set('{%s}width' % SVG_URI, str(width))
                draw_frame_node.set('{%s}height' % SVG_URI, str(height))

        image_tag_name = '{%s}%s' % (DRAW_URI, 'image')
        image_node = Element(image_tag_name, nsmap=NSMAP)
        image_node.attrib.update(attr_dict.get(image_tag_name, []).pop())
        image_node.set('{%s}href' % XLINK_URI, picture_path)

        draw_frame_node.append(image_node)
        if as_string:
            return etree.tostring(draw_frame_node)
        return draw_frame_node

    def _getPictureSize(self, picture_width, picture_height, target_width,
                        target_height):
        # if not match causes exception
        width_tuple = re.match("(\d[\d\.]*)(.*)", target_width).groups()
        height_tuple = re.match("(\d[\d\.]*)(.*)", target_height).groups()
        unit = width_tuple[1]
        w = float(width_tuple[0])
        h = float(height_tuple[0])
        aspect_ratio = 1
        try:  # try image properties
            aspect_ratio = picture_width / picture_height
        except (TypeError, ZeroDivisionError):
            try:  # try Image Document API
                height = picture_height
                if height:
                    aspect_ratio = picture_width / height
            except AttributeError:  # fallback to Photo API
                height = float(picture_height)
                if height:
                    aspect_ratio = picture_width / height
        resize_w = h * aspect_ratio
        resize_h = w / aspect_ratio
        if resize_w < w:
            w = resize_w
        elif resize_h < h:
            h = resize_h
        return (str(w) + unit, str(h) + unit)
Exemplo n.º 23
0
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
Exemplo n.º 24
0
class GadgetFieldValidator(Validator.Validator):

    property_names = Validator.Validator.property_names + [
        'data_url', 'validator_form_id', 'validator_field_id'
    ]

    data_url = fields.CheckBoxField(
        'data_url',
        title='Data Url',
        description=("Checked if gadget return data url."),
        default=0)

    validator_form_id = fields.StringField(
        'validator_form_id',
        title='Validator Form ID',
        description=
        "ID of the validator field's form. Default is the current form",
        default="",
        display_width=40,
        required=0)

    validator_field_id = fields.StringField(
        'validator_field_id',
        title='Validator Field ID',
        description="ID of the validator field.",
        default="",
        display_width=40,
        required=0)

    message_names = Validator.Validator.message_names + ['no_validator']

    no_validator = 'Does not support this operation.'

    def getValidatorField(self, field):
        """Get an external validator field located in the same form.
      """
        field_id = field.id
        validator_form_id = field.get_value('validator_form_id')
        validator_field_id = field.get_value('validator_field_id')

        validator_form = field.aq_parent
        if (validator_form_id):
            if '/' in validator_form_id:
                portal = field.getPortalObject()
                portal_skins = portal.portal_skins
                # If a / is in the form_id, it means that skin_folder is explicitly
                # defined. If so, prevent acquisition to get the form.
                aq_validator_form = aq_base(portal_skins).unrestrictedTraverse(
                    validator_form_id, None)
                if aq_validator_form is not None:
                    validator_form = portal_skins.unrestrictedTraverse(
                        validator_form_id)
            else:
                validator_form = getattr(validator_form, validator_form_id,
                                         None)

        if (validator_form is not None) and validator_field_id:
            if validator_form.has_field(validator_field_id,
                                        include_disabled=1):
                return validator_form.get_field(validator_field_id,
                                                include_disabled=1)
        return None

    def validate(self, field, key, REQUEST):
        validator_field = self.getValidatorField(field)
        if validator_field is None:
            # not editable if no validator
            self.raise_error('no_validator', field)
        else:
            value = validator_field._validate_helper(key, REQUEST)
            if value is not None:
                if field.get_value('data_url'):
                    value = value.split(",")[1]
                    return StringIO(value.decode('base64'))
                return value
Exemplo n.º 25
0
class DurationWidget(Widget.IntegerWidget):
    """
  Duration Widget is used to enter time duration.
  It may be used in movement of Labour (in Task, Calendat Period, ...).

  Time duration in ERP5 are saved ALWAYS IN SECOND.

  The field purpose is to display second quantity in hour, minute and second,
  in order to make it more readable.

  XXX This field is experimental, and unstable.
  Do not use it.
  """

    title = fields.StringField('title',
        title='Title. ' \
            '(Warning! Do not use this field!)',
                               description=(
        "The title of this field. This is the title of the field that "
        "will appear in the form when it is displayed. Required."),
                               default="",
                               required=1)

    def render_view(self, field, value, REQUEST=None, render_prefix=None):
        sub_field_render_list = []
        for title, sub_key, convertion in (('Hour', 'hour', HOUR_IN_SECOND),
                                           ('Minute', 'minute',
                                            MINUTE_IN_SECOND)):
            if value == '':
                sub_value = ''
            else:
                sub_value, value = divmod(value, convertion)

            sub_field_render_list.append(
                self.render_sub_field_view(field, sub_value, REQUEST=REQUEST))
        # Render second
        sub_field_render_list.append(
            self.render_sub_field_view(field, value, REQUEST=REQUEST))
        return ':'.join(sub_field_render_list)

    def render(self, field, key, value, REQUEST, render_prefix=None):
        sub_field_render_list = []
        for title, sub_key, convertion in (('Hour', 'hour', HOUR_IN_SECOND),
                                           ('Minute', 'minute',
                                            MINUTE_IN_SECOND)):
            if value == '':
                sub_value = ''
            else:
                sub_value, value = divmod(value, convertion)
            sub_field_render_list.append(
                self.render_sub_field(field, key, sub_value, REQUEST, sub_key))
        # Render second
        sub_field_render_list.append(
            self.render_sub_field(field, key, value, REQUEST, 'second'))
        return ':'.join(sub_field_render_list)

    def render_sub_field_view(self,
                              field,
                              value,
                              REQUEST=None,
                              render_prefix=None):
        """
    Render dynamically a subfield
    """
        return self.render_view(field, value, REQUEST=REQUEST)

    def render_sub_field(self,
                         field,
                         key,
                         value,
                         REQUEST,
                         keyword,
                         render_prefix=None):
        """
    Render dynamically a subfield
    """
        return Widget.IntegerWidget.render(
            self, field, field.generate_subfield_key(keyword, key=key), value,
            REQUEST)
Exemplo n.º 26
0
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
Exemplo n.º 27
0
class GadgetWidget(Widget.TextWidget):
    """
  A widget that displays a renderjs gadget 
  """
    property_names = Widget.TextWidget.property_names + \
         ['gadget_html', 'gadget_cached', 'gadget_cache_id', 'gadget_property',
          'gadget_connection', 'gadget_id']

    gadget_html = fields.StringField(
        'gadget_html',
        title='Gadget Html',
        description=("The id of the html page containing the \
                                      gadget"),
        default='',
        required=0)

    gadget_id = fields.StringField('gadget_id',
                                   title='Gadget Id',
                                   description=("The id of the gadget"),
                                   default='',
                                   required=0)

    gadget_cache_id = fields.StringField(
        'gadget_cache_id',
        title='Gadget Cache Id',
        description=("The id of the cache in localstorage"),
        default='',
        required=0)

    gadget_property = fields.StringField(
        'gadget_property',
        title='Gadget Properties',
        description=("Json Data used to initialize the gadget"),
        default='',
        required=0)

    gadget_connection = fields.StringField(
        'gadget_connection',
        title='Gadget Connections',
        description=("Json Data used to define interactions"),
        default='',
        required=0)

    gadget_cached = fields.CheckBoxField(
        'gadget_cached',
        title='Gadget Cached',
        description=("The rendering of the gadget will be \
                                       cached in localstorage."),
        default=0,
        required=0)

    def render(self, field, key, value, REQUEST, render_prefix=None):
        return self.render_view(field, value, REQUEST, render_prefix)

    def render_view(self, field, value, REQUEST=None, render_prefix=None):
        kw = {}
        gadget_mapping = {
            "gadget_cached": "data-gadget-cacheable",
            "gadget_cache_id": "data-gadget-cache-id",
            "gadget_html": "data-gadget",
            "gadget_id": "id",
            "gadget_connection": "data-gadget-connection",
            "gadget_property": "data-gadget-property"
        }
        for property_name in gadget_mapping.keys():
            property_value = field.get_value(property_name)
            if property_value or property_name == "gadget_html":
                kw[gadget_mapping[property_name]] = property_value
        return Widget.render_element("div", **kw)
Exemplo n.º 28
0
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)
Exemplo n.º 29
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 '&nbsp;<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 = '&amp;selection_name=%s&amp;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 += '&amp;ignore_layout:int=%s' % int(
                    ignore_layout)
            # Generate plan link
            return '<a href="%s/%s?field_id=%s&amp;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 ''
Exemplo n.º 30
0
class ZPyChartWidget(Widget.Widget):
    """
    A widget to generate pychart charts in multiple formats
    
    Chart definition is defined in a script. Some parameters
    are defined through Web UI. Web UI parameters are intended
    to be specialised through Proxy fields.
  """
    property_names = Widget.Widget.property_names+\
                     [ 'selection_name',
                       'data_method',
                       'chart_title',
                       'x_title',
                       'y_title',]

    default = fields.StringField(
        'default',
        title='Default',
        description=("Default value of the text in the widget."),
        default="",
        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_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)

    def render(self, field, key, value, REQUEST, render_prefix=None):
        """
      Here, we just generate tags which will later call download
    """
        # Get standard parameters
        selection_name = field.get_value('selection_name')
        chart_title = field.get_value('chart_title')
        data_method = field.get_value('data_method')
        x_title = field.get_value('x_title')
        y_title = field.get_value('y_title')

        # Retrieve the data and set the selection if data_method is not None
        if data_method:
            here = REQUEST.get('here', self)
            if getattr(here, data_method, None) is not None:
                data_method = getattr(here, data_method)
                # Retrieve selection
                selection = here.portal_selections.getSelectionFor(
                    selection_name, REQUEST=REQUEST)
                # Define the new selection data_method
                selection.edit(
                    method_id=data_method)  # XXX This is probably wrong

        # Return an image field
        return """<img src="%s/download?selection_name=%s&chart_title=%s&data_method=%s&x_title=%s&y_title=%s"/>""" % (
            field.absolute_url(), selection_name, chart_title, data_method,
            x_title, y_title)