Exemplo n.º 1
0
    def _setup_image_slave(self):
        event_box = gtk.EventBox()
        event_box.show()

        field_name = self.model.field_name
        model = sysparam.get_object(self.store, field_name)

        self.container.add(event_box)
        self._image_slave = ImageSlave(self.store, model)
        self._image_slave.connect('image-changed',
                                  self._on_image_slave__image_changed)
        self._image_slave.show()
        self.attach_slave('image_slave', self._image_slave, event_box)

        # Images can have field_value as None
        self._block_none_value = False
Exemplo n.º 2
0
    def _setup_image_slave(self):
        event_box = gtk.EventBox()
        event_box.show()

        field_name = self.model.field_name
        model = sysparam.get_object(self.store, field_name)

        self.container.add(event_box)
        self._image_slave = ImageSlave(self.store, model)
        self._image_slave.connect("image-changed", self._on_image_slave__image_changed)
        self._image_slave.show()
        self.attach_slave("image_slave", self._image_slave, event_box)

        # Images can have field_value as None
        self._block_none_value = False
Exemplo n.º 3
0
class SystemParameterEditor(BaseEditor):
    gladefile = "SystemParameterEditor"
    proxy_widgets = ("parameter_name",
                     "parameter_desc",
                     "parameter_group")
    model_type = ParameterData
    help_section = 'param'

    def __init__(self, store, param_detail):
        if not param_detail:
            raise ValueError("This editor can't be called without a model")
        # By default, if the user sets a value to None (e.g. selecting nothing
        # on a comboentry) we block it's update. Change this to False if the
        # param itself can accept None.
        self._block_none_value = True
        self.sensitive = True
        # TODO: After we migrate those parameters to set is_editable
        # to False we can probably remove this if
        if param_detail.key in ['DEMO_MODE', 'LOCAL_BRANCH',
                                'SYNCHRONIZED_MODE', 'USER_HASH']:
            self.sensitive = False

        self.detail = param_detail
        model = self._get_model(store, param_detail)
        BaseEditor.__init__(self, store, model)
        self._setup_widgets()

    #
    # Helper methods
    #

    def _get_model(self, store, detail):
        model = store.find(ParameterData, field_name=detail.key).one()
        if not model:
            value = sysparam.get(detail.key)
            if detail.type is bool:
                value = int(value)
            if value is not None:
                value = unicode(value)
            model = ParameterData(store=store,
                                  field_name=detail.key,
                                  field_value=value)
        return model

    def _setup_widgets(self):
        self.parameter_name.set_underline(True)
        self.parameter_desc.set_size("small")
        self.parameter_group.set_label(self.detail.group)

    def _setup_entry_slave(self, box=None):
        widget = ProxyEntry()
        # Try to simulate insensitive appearance for non-editable entries
        # while keeping them selectable
        widget.set_editable(self.sensitive)
        if not self.sensitive:
            style = widget.get_style()
            widget.modify_text(
                gtk.STATE_NORMAL, style.text[gtk.STATE_INSENSITIVE])
            widget.modify_base(
                gtk.STATE_NORMAL, style.base[gtk.STATE_INSENSITIVE])
        widget.data_type = unicode
        widget.model_attribute = "field_value"
        self.proxy.add_widget("field_value", widget)
        if box is None:
            self.container.add(widget)
        else:
            box.pack_start(widget)

        widget.show()
        widget.connect('validate', self._on_entry__validate)
        widget.connect('validation-changed',
                       self._on_entry__validation_changed)

        self._entry = widget

    def _setup_spin_entry_slave(self, box=None):
        data_type = self.detail.get_parameter_type()
        widget = ProxySpinButton(data_type=data_type)
        widget.props.sensitive = self.sensitive
        widget.set_range(self.detail.range[0], self.detail.range[1])
        widget.set_value(data_type(self.model.field_value))
        widget.set_increments(1, 10)
        if issubclass(data_type, Decimal):
            widget.props.digits = 2

        widget.connect('value-changed', self._on_spin__value_changed)
        if box is None:
            self.container.add(widget)
        else:
            box.pack_start(widget)

        widget.show()
        widget.connect('validate', self._on_entry__validate)
        widget.connect('validation-changed',
                       self._on_entry__validation_changed)
        self._entry = widget

    def _setup_text_view_slave(self):
        sw = gtk.ScrolledWindow()
        sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
        sw.set_policy(gtk.POLICY_AUTOMATIC,
                      gtk.POLICY_AUTOMATIC)
        widget = ProxyTextView()
        widget.props.sensitive = self.sensitive
        widget.data_type = unicode
        widget.model_attribute = "field_value"
        if self.detail.wrap:
            widget.set_wrap_mode(gtk.WRAP_WORD)
        self.proxy.add_widget("field_value", widget)
        sw.add(widget)
        sw.show()
        self.container.add(sw)

        widget.show()
        self._entry = widget

    def _setup_entry_with_filechooser_button_slave(self, dir_only=False):
        hbox = gtk.HBox(spacing=6)
        hbox.props.sensitive = self.sensitive
        self._setup_entry_slave(hbox)
        title = _(u'Cat 52 directory selection')
        filechooser_button = gtk.FileChooserButton(title)
        filechooser_button.connect('selection-changed',
                                   self._on_filechooser_button__selection_changed)

        if dir_only:
            filechooser_button.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)

        hbox.pack_start(filechooser_button, expand=False)
        filechooser_button.show()

        self.container.add(hbox)
        hbox.show()

    def _setup_image_slave(self):
        event_box = gtk.EventBox()
        event_box.show()

        field_name = self.model.field_name
        model = sysparam.get_object(self.store, field_name)

        self.container.add(event_box)
        self._image_slave = ImageSlave(self.store, model)
        self._image_slave.connect('image-changed',
                                  self._on_image_slave__image_changed)
        self._image_slave.show()
        self.attach_slave('image_slave', self._image_slave, event_box)

        # Images can have field_value as None
        self._block_none_value = False

    def _setup_comboboxentry_slave(self, data=None):
        widget = ProxyComboEntry()
        widget.props.sensitive = self.sensitive
        widget.model_attribute = "field_value"
        widget.data_type = unicode

        detail = sysparam.get_detail_by_name(self.model.field_name)
        is_mandatory = not detail.allow_none
        self._block_none_value = is_mandatory
        widget.set_property('mandatory', is_mandatory)

        if not data:
            field_type = detail.get_parameter_type()
            # FIXME: DEFAULT_PAYMENT_METHOD needs to filter information from
            # domain because it cannot be any non-creatable method.
            # Find a way to implement this in a generic on ParameterDetails
            if self.model.field_name == "DEFAULT_PAYMENT_METHOD":
                result = PaymentMethod.get_creatable_methods(
                    self.store, Payment.TYPE_IN, False)
            else:
                result = self.store.find(field_type)
            data = [(res.get_description(), unicode(res.id)) for res in result]
        widget.prefill(data)
        self.proxy.add_widget("field_value", widget)
        self.container.add(widget)
        widget.show()
        widget.connect('validation-changed',
                       self._on_entry__validation_changed)

    def _setup_radio_slave(self):
        box = gtk.HBox()
        box.props.sensitive = self.sensitive
        yes_widget = gtk.RadioButton()
        yes_widget.set_label(_("Yes"))
        yes_widget.connect("toggled", self._on_yes_radio__toggled)
        group = yes_widget.get_group()[0]
        box.pack_start(yes_widget)
        yes_widget.show()
        no_widget = gtk.RadioButton()
        no_widget.set_label(_("No"))
        no_widget.set_group(group)
        box.pack_start(no_widget)
        no_widget.show()
        self.container.add(box)
        no_widget.set_active(self.model.field_value == "0")
        yes_widget.set_active(self.model.field_value == "1")
        box.show()

    def _setup_options_combo_slave(self):
        widget = ProxyComboBox()
        widget.props.sensitive = self.sensitive
        widget.model_attribute = "field_value"
        widget.data_type = unicode

        data = [(value, unicode(key))
                for key, value in self.detail.options.items()]
        widget.prefill(data)
        self.proxy.add_widget("field_value", widget)
        self.container.add(widget)
        widget.show()

    #
    # BaseEditor hooks
    #

    def get_title(self, model):
        return _("Edit '%s' Parameter") % self.detail.short_desc

    def setup_proxies(self):
        self.add_proxy(self.detail,
                       SystemParameterEditor.proxy_widgets)
        self.proxy = self.add_proxy(self.model)

    def setup_slaves(self):
        field_type = self.detail.get_parameter_type()
        if issubclass(field_type, Image):
            self._setup_image_slave()
        elif issubclass(field_type, Domain):
            self._setup_comboboxentry_slave()
        elif self.detail.editor == 'file-chooser':
            self._setup_entry_with_filechooser_button_slave()
        elif self.detail.editor == 'directory-chooser':
            self._setup_entry_with_filechooser_button_slave(dir_only=True)
        elif issubclass(field_type, bool):
            self._setup_radio_slave()
        elif issubclass(field_type, (int, float, Decimal)):
            if self.detail.options:
                self._setup_options_combo_slave()
            elif self.detail.range:
                self._setup_spin_entry_slave()
            else:
                self._setup_entry_slave()
        elif issubclass(field_type, basestring):
            if self.detail.multiline:
                self._setup_text_view_slave()
            elif self.detail.combo_data:
                self._setup_comboboxentry_slave(data=self.detail.combo_data())
            else:
                self._setup_entry_slave()
        else:
            raise TypeError("ParameterData for `%s' has an invalid "
                            "type: %r" % (self.model.field_name,
                                          field_type))

    def validate_confirm(self):
        if self._block_none_value and self.model.field_value is None:
            return False

        change_callback = self.detail.get_change_callback()
        if change_callback:
            change_callback(self.model.field_value, self.store)

        sysparam.set_value_generic(self.model.field_name,
                                   self.model.field_value)

        return True

    #
    # Callbacks
    #

    def _on_image_slave__image_changed(self, slave, image):
        self.model.field_value = image and unicode(image.id)

    def _on_entry__validate(self, widget, value):
        if not value:
            return ValidationError(_("Field can not be empty."))

        validate_func = self.detail.get_parameter_validator()
        if validate_func and callable(validate_func):
            return validate_func(value)

    def _on_entry__validation_changed(self, widget, value):
        # FIXME: 1- The BaseModel (or one of it's parent classes) should be
        #           doing the next logic automatically.
        #        2- Why does refresh_ok only accepts int values?
        #           If a bool value is passed, it'll raise TypeError.
        self.refresh_ok(int(value))

    def _on_yes_radio__toggled(self, widget):
        self.model.field_value = unicode(int(widget.get_active()))

    def _on_spin__value_changed(self, widget):
        data_type = self.detail.get_parameter_type()
        if data_type is int:
            # float and Decimal are subclasses of int
            value = widget.get_value_as_int()
        else:
            value = widget.read()

        self.model.field_value = unicode(value)

    def _on_filechooser_button__selection_changed(self, widget):
        filename = widget.get_filename()
        self._entry.set_text(filename)
Exemplo n.º 4
0
class SystemParameterEditor(BaseEditor):
    gladefile = "SystemParameterEditor"
    proxy_widgets = ("parameter_name",
                     "parameter_desc",
                     "parameter_group")
    model_type = ParameterData
    help_section = 'param'

    def __init__(self, store, model):
        if not model:
            raise ValueError("This editor can't be called without a model")
        # By default, if the user sets a value to None (e.g. selecting nothing
        # on a comboentry) we block it's update. Change this to False if the
        # param itself can accept None.
        self._block_none_value = True
        self.sensitive = True
        if model.field_name in ['DEMO_MODE', 'LOCAL_BRANCH',
                                'SYNCHRONIZED_MODE']:
            self.sensitive = False

        self._parameter_details = sysparam.get_detail_by_name(model.field_name)
        BaseEditor.__init__(self, store, model)
        self._setup_widgets()

    #
    # Helper methods
    #

    def _setup_widgets(self):
        self.parameter_name.set_underline(True)
        self.parameter_desc.set_size("small")
        self.parameter_group.set_label(_(self.model.get_group()))

    def _setup_entry_slave(self, box=None):
        widget = ProxyEntry()
        widget.props.sensitive = self.sensitive
        widget.data_type = unicode
        widget.model_attribute = "field_value"
        self.proxy.add_widget("field_value", widget)
        if box is None:
            self.container.add(widget)
        else:
            box.pack_start(widget)

        widget.show()
        widget.connect('validate', self._on_entry__validate)
        widget.connect('validation-changed',
                       self._on_entry__validation_changed)

        self._entry = widget

    def _setup_spin_entry_slave(self, box=None):
        data_type = self.detail.get_parameter_type()
        widget = ProxySpinButton(data_type=data_type)
        widget.props.sensitive = self.sensitive
        widget.set_range(self.detail.range[0], self.detail.range[1])
        widget.set_value(data_type(self.model.field_value))
        widget.set_increments(1, 10)
        if issubclass(data_type, Decimal):
            widget.props.digits = 2

        widget.connect('value-changed', self._on_spin__value_changed)
        if box is None:
            self.container.add(widget)
        else:
            box.pack_start(widget)

        widget.show()
        widget.connect('validate', self._on_entry__validate)
        widget.connect('validation-changed',
                       self._on_entry__validation_changed)
        self._entry = widget

    def _setup_text_view_slave(self):
        sw = gtk.ScrolledWindow()
        sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
        sw.set_policy(gtk.POLICY_AUTOMATIC,
                      gtk.POLICY_AUTOMATIC)
        widget = ProxyTextView()
        widget.props.sensitive = self.sensitive
        widget.data_type = unicode
        widget.model_attribute = "field_value"
        if self.detail.wrap:
            widget.set_wrap_mode(gtk.WRAP_WORD)
        self.proxy.add_widget("field_value", widget)
        sw.add(widget)
        sw.show()
        self.container.add(sw)

        widget.show()
        self._entry = widget

    def _setup_entry_with_filechooser_button_slave(self, dir_only=False):
        hbox = gtk.HBox(spacing=6)
        hbox.props.sensitive = self.sensitive
        self._setup_entry_slave(hbox)
        title = _(u'Cat 52 directory selection')
        filechooser_button = gtk.FileChooserButton(title)
        filechooser_button.connect('selection-changed',
                                   self._on_filechooser_button__selection_changed)

        if dir_only:
            filechooser_button.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)

        hbox.pack_start(filechooser_button, expand=False)
        filechooser_button.show()

        self.container.add(hbox)
        hbox.show()

    def _setup_image_slave(self):
        event_box = gtk.EventBox()
        event_box.show()

        field_name = self.model.field_name
        model = sysparam.get_object(self.store, field_name)

        self.container.add(event_box)
        self._image_slave = ImageSlave(self.store, model)
        self._image_slave.connect('image-changed',
                                  self._on_image_slave__image_changed)
        self._image_slave.show()
        self.attach_slave('image_slave', self._image_slave, event_box)

        # Images can have field_value as None
        self._block_none_value = False

    def _setup_comboboxentry_slave(self, data=None):
        widget = ProxyComboEntry()
        widget.props.sensitive = self.sensitive
        widget.model_attribute = "field_value"
        widget.data_type = unicode

        detail = sysparam.get_detail_by_name(self.model.field_name)
        is_mandatory = not detail.allow_none
        self._block_none_value = is_mandatory
        widget.set_property('mandatory', is_mandatory)

        if not data:
            field_type = detail.get_parameter_type()
            # FIXME: DEFAULT_PAYMENT_METHOD needs to filter information from
            # domain because it cannot be any non-creatable method.
            # Find a way to implement this in a generic on ParameterDetails
            if self.model.field_name == "DEFAULT_PAYMENT_METHOD":
                result = PaymentMethod.get_creatable_methods(
                    self.store, Payment.TYPE_IN, False)
            else:
                result = self.store.find(field_type)
            data = [(res.get_description(), unicode(res.id)) for res in result]
        widget.prefill(data)
        self.proxy.add_widget("field_value", widget)
        self.container.add(widget)
        widget.show()
        widget.connect('validation-changed',
                       self._on_entry__validation_changed)

    def _setup_radio_slave(self):
        box = gtk.HBox()
        box.props.sensitive = self.sensitive
        yes_widget = gtk.RadioButton()
        yes_widget.set_label(_("Yes"))
        yes_widget.connect("toggled", self._on_yes_radio__toggled)
        group = yes_widget.get_group()[0]
        box.pack_start(yes_widget)
        yes_widget.show()
        no_widget = gtk.RadioButton()
        no_widget.set_label(_("No"))
        no_widget.set_group(group)
        box.pack_start(no_widget)
        no_widget.show()
        self.container.add(box)
        no_widget.set_active(self.model.field_value == "0")
        yes_widget.set_active(self.model.field_value == "1")
        box.show()

    def _setup_options_combo_slave(self):
        widget = ProxyComboBox()
        widget.props.sensitive = self.sensitive
        widget.model_attribute = "field_value"
        widget.data_type = unicode

        data = [(value, unicode(key))
                for key, value in self.detail.options.items()]
        widget.prefill(data)
        self.proxy.add_widget("field_value", widget)
        self.container.add(widget)
        widget.show()

    #
    # BaseEditor hooks
    #

    def get_title(self, model):
        return _("Edit '%s' Parameter") % self._parameter_details.short_desc

    def setup_proxies(self):
        self.add_proxy(self._parameter_details,
                       SystemParameterEditor.proxy_widgets)
        self.proxy = self.add_proxy(self.model)

    def setup_slaves(self):
        self._slave = None
        self.detail = sysparam.get_detail_by_name(self.model.field_name)
        field_type = self.detail.get_parameter_type()
        if issubclass(field_type, Image):
            self._setup_image_slave()
        elif issubclass(field_type, Domain):
            self._setup_comboboxentry_slave()
        elif self.detail.editor == 'file-chooser':
            self._setup_entry_with_filechooser_button_slave()
        elif self.detail.editor == 'directory-chooser':
            self._setup_entry_with_filechooser_button_slave(dir_only=True)
        elif issubclass(field_type, bool):
            self._setup_radio_slave()
        elif issubclass(field_type, (int, float, Decimal)):
            if self.detail.options:
                self._setup_options_combo_slave()
            elif self.detail.range:
                self._setup_spin_entry_slave()
            else:
                self._setup_entry_slave()
        elif issubclass(field_type, basestring):
            if self.detail.multiline:
                self._setup_text_view_slave()
            elif self.detail.combo_data:
                self._setup_comboboxentry_slave(data=self.detail.combo_data())
            else:
                self._setup_entry_slave()
        else:
            raise TypeError("ParameterData for `%s' has an invalid "
                            "type: %r" % (self.model.field_name,
                                          field_type))

    def validate_confirm(self):
        if self._block_none_value and self.model.field_value is None:
            return False

        change_callback = self.detail.get_change_callback()
        if change_callback:
            change_callback(self.model.field_value, self.store)

        sysparam.set_value_generic(self.model.field_name,
                                   self.model.field_value)

        return True

    #
    # Callbacks
    #

    def _on_image_slave__image_changed(self, slave, image):
        self.model.field_value = image and unicode(image.id)

    def _on_entry__validate(self, widget, value):
        if not value:
            return ValidationError(_("Field can not be empty."))

        validate_func = self.detail.get_parameter_validator()
        if validate_func and callable(validate_func):
            return validate_func(value)

    def _on_entry__validation_changed(self, widget, value):
        # FIXME: 1- The BaseModel (or one of it's parent classes) should be
        #           doing the next logic automatically.
        #        2- Why does refresh_ok only accepts int values?
        #           If a bool value is passed, it'll raise TypeError.
        self.refresh_ok(int(value))

    def _on_yes_radio__toggled(self, widget):
        self.model.field_value = unicode(int(widget.get_active()))

    def _on_spin__value_changed(self, widget):
        data_type = self.detail.get_parameter_type()
        if data_type is int:
            # float and Decimal are subclasses of int
            value = widget.get_value_as_int()
        else:
            value = widget.read()

        self.model.field_value = unicode(value)

    def _on_filechooser_button__selection_changed(self, widget):
        filename = widget.get_filename()
        self._entry.set_text(filename)
Exemplo n.º 5
0
 def _setup_image_slave(self, image_model):
     slave = ImageSlave(self.store, image_model, visual_mode=self.visual_mode)
     slave.connect('image-changed', self._on_image_slave__image_changed)
     self.attach_slave('sellable_image_holder', slave)
Exemplo n.º 6
0
 def _setup_image_slave(self, image_model):
     slave = ImageSlave(self.store,
                        image_model,
                        visual_mode=self.visual_mode)
     slave.connect('image-changed', self._on_image_slave__image_changed)
     self.attach_slave('sellable_image_holder', slave)
Exemplo n.º 7
0
class SystemParameterEditor(BaseEditor):
    gladefile = "SystemParameterEditor"
    proxy_widgets = ("parameter_name",
                     "parameter_desc")
    model_type = ParameterData
    help_section = 'param'

    def __init__(self, store, model):
        if not model:
            raise ValueError("This editor can't be called without a model")
        # By default, if the user sets a value to None (e.g. selecting nothing
        # on a comboentry) we block it's update. Change this to False if the
        # param itself can accept None.
        self._block_none_value = True
        self.sensitive = True
        if model.field_name in ['DEMO_MODE', 'LOCAL_BRANCH',
                                'SYNCHRONIZED_MODE']:
            self.sensitive = False

        self._parameter_details = get_parameter_details(model.field_name)
        BaseEditor.__init__(self, store, model)
        self._setup_widgets()

    #
    # Helper methods
    #

    def _setup_widgets(self):
        self.parameter_name.set_underline(True)
        self.parameter_desc.set_size("small")

    def _setup_entry_slave(self, box=None):
        widget = ProxyEntry()
        widget.props.sensitive = self.sensitive
        widget.data_type = unicode
        widget.model_attribute = "field_value"
        self.proxy.add_widget("field_value", widget)
        if box is None:
            self.container.add(widget)
        else:
            box.pack_start(widget)

        widget.show()
        widget.connect('validate', self._on_entry__validate)
        widget.connect('validation-changed',
                       self._on_entry__validation_changed)

        self._entry = widget

    def _setup_spin_entry_slave(self, box=None):
        data_type = self.constant.get_parameter_type()
        widget = ProxySpinButton(data_type=data_type)
        widget.props.sensitive = self.sensitive
        widget.set_range(self.constant.range[0], self.constant.range[1])
        widget.set_value(data_type(self.model.field_value))
        widget.set_increments(1, 10)
        if issubclass(data_type, Decimal):
            widget.props.digits = 2

        widget.connect('value-changed', self._on_spin__value_changed)
        if box is None:
            self.container.add(widget)
        else:
            box.pack_start(widget)

        widget.show()
        widget.connect('validate', self._on_entry__validate)
        widget.connect('validation-changed',
                       self._on_entry__validation_changed)
        self._entry = widget

    def _setup_text_view_slave(self):
        sw = gtk.ScrolledWindow()
        sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
        sw.set_policy(gtk.POLICY_AUTOMATIC,
                      gtk.POLICY_AUTOMATIC)
        widget = ProxyTextView()
        widget.props.sensitive = self.sensitive
        widget.data_type = unicode
        widget.model_attribute = "field_value"
        widget.set_wrap_mode(gtk.WRAP_WORD)
        self.proxy.add_widget("field_value", widget)
        sw.add(widget)
        sw.show()
        self.container.add(sw)

        widget.show()
        self._entry = widget

    def _setup_entry_with_filechooser_button_slave(self, dir_only=False):
        hbox = gtk.HBox(spacing=6)
        hbox.props.sensitive = self.sensitive
        self._setup_entry_slave(hbox)
        title = _(u'Cat 52 directory selection')
        filechooser_button = gtk.FileChooserButton(title)
        filechooser_button.connect('selection-changed',
            self._on_filechooser_button__selection_changed)

        if dir_only:
            filechooser_button.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)

        hbox.pack_start(filechooser_button, expand=False)
        filechooser_button.show()

        self.container.add(hbox)
        hbox.show()

    def _setup_image_slave(self):
        event_box = gtk.EventBox()
        event_box.show()

        field_name = self.model.field_name
        model = sysparam(self.store).get_parameter_by_field(field_name,
                                                           Image)

        self.container.add(event_box)
        self._image_slave = ImageSlave(self.store, model)
        self._image_slave.connect('image-changed',
                                  self._on_image_slave__image_changed)
        self._image_slave.show()
        self.attach_slave('image_slave', self._image_slave, event_box)

        # Images can have field_value as None
        self._block_none_value = False

    def _setup_comboboxentry_slave(self, data=None):
        widget = ProxyComboEntry()
        widget.props.sensitive = self.sensitive
        widget.model_attribute = "field_value"
        widget.data_type = unicode
        widget.mandatory = True
        if not data:
            field_type = sysparam(self.store).get_parameter_type(self.model.field_name)
            result = self.store.find(field_type)
            data = [(res.get_description(), unicode(res.id)) for res in result]
        widget.prefill(data)
        self.proxy.add_widget("field_value", widget)
        self.container.add(widget)
        widget.show()
        widget.connect('validation-changed',
                       self._on_entry__validation_changed)

    def _setup_radio_slave(self):
        box = gtk.HBox()
        box.props.sensitive = self.sensitive
        yes_widget = gtk.RadioButton()
        yes_widget.set_label(_("Yes"))
        yes_widget.connect("toggled", self._on_yes_radio__toggled)
        group = yes_widget.get_group()[0]
        box.pack_start(yes_widget)
        yes_widget.show()
        no_widget = gtk.RadioButton()
        no_widget.set_label(_("No"))
        no_widget.set_group(group)
        box.pack_start(no_widget)
        no_widget.show()
        self.container.add(box)
        no_widget.set_active(self.model.field_value == "0")
        yes_widget.set_active(self.model.field_value == "1")
        box.show()

    def _setup_options_combo_slave(self):
        widget = ProxyComboBox()
        widget.props.sensitive = self.sensitive
        widget.model_attribute = "field_value"
        widget.data_type = unicode

        data = [(value, unicode(key))
                for key, value in self.constant.options.items()]
        widget.prefill(data)
        self.proxy.add_widget("field_value", widget)
        self.container.add(widget)
        widget.show()

    #
    # BaseEditor hooks
    #

    def get_title(self, model):
        return _("Edit '%s' Parameter") % self._parameter_details.short_desc

    def setup_proxies(self):
        self.add_proxy(self._parameter_details,
                       SystemParameterEditor.proxy_widgets)
        self.proxy = self.add_proxy(self.model)

    def setup_slaves(self):
        self._slave = None
        sparam = sysparam(self.store)
        self.constant = sparam.get_parameter_constant(self.model.field_name)
        field_type = self.constant.get_parameter_type()
        if issubclass(field_type, Image):
            self._setup_image_slave()
        elif issubclass(field_type, Domain):
            self._setup_comboboxentry_slave()
        elif issubclass(field_type, FileParameter):
            self._setup_entry_with_filechooser_button_slave()
        elif issubclass(field_type, DirectoryParameter):
            self._setup_entry_with_filechooser_button_slave(dir_only=True)
        elif issubclass(field_type, bool):
            self._setup_radio_slave()
        elif issubclass(field_type, (int, float, Decimal)):
            if self.constant.options:
                self._setup_options_combo_slave()
            elif self.constant.range:
                self._setup_spin_entry_slave()
            else:
                self._setup_entry_slave()
        elif issubclass(field_type, basestring):
            if self.constant.multiline:
                self._setup_text_view_slave()
            elif self.constant.combo_data:
                self._setup_comboboxentry_slave(data=self.constant.combo_data())
            else:
                self._setup_entry_slave()
        else:
            raise TypeError("ParameterData for `%s' has an invalid "
                            "type: %r" % (self.model.field_name,
                                          field_type))

    def validate_confirm(self):
        if self._block_none_value and self.model.field_value is None:
            return False

        change_callback = self.constant.get_change_callback()
        if change_callback:
            change_callback(self.model.field_value, self.store)

        return True

    #
    # Callbacks
    #

    def _on_image_slave__image_changed(self, slave, image):
        self.model.field_value = image and unicode(image.id)

    def _on_entry__validate(self, widget, value):
        if not value:
            return ValidationError(_("Field can not be empty."))

        validate_func = self.constant.get_parameter_validator()
        if validate_func and callable(validate_func):
            return validate_func(value)

    def _on_entry__validation_changed(self, widget, value):
        # FIXME: 1- The BaseModel (or one of it's parent classes) should be
        #           doing the next logic automatically.
        #        2- Why does refresh_ok only accepts int values?
        #           If a bool value is passed, it'll raise TypeError.
        self.refresh_ok(int(value))

    def _on_yes_radio__toggled(self, widget):
        self.model.field_value = unicode(int(widget.get_active()))

    def _on_spin__value_changed(self, widget):
        data_type = self.constant.get_parameter_type()
        if data_type is int:
            # float and Decimal are subclasses of int
            value = widget.get_value_as_int()
        else:
            value = widget.read()

        self.model.field_value = unicode(value)

    def _on_filechooser_button__selection_changed(self, widget):
        filename = widget.get_filename()
        self._entry.set_text(filename)