Пример #1
0
    def _setup_widget(self, widget_name, widget):
        if not IProxyWidget.providedBy(widget):
            raise ProxyError("The widget %s (%r), in view %s is not "
                             "a kiwi widget and cannot be added to a proxy"
                             % (widget_name, widget,
                                self._view.__class__.__name__))

        data_type = _get_widget_data_type(widget)
        if data_type is None:
            raise ProxyError("The kiwi widget %s (%r) in view %s should "
                             "have a data type set" % (
                                 widget_name, widget, self._view.__class__.__name__))

        attribute = widget.get_property('model-attribute')
        if not attribute:
            attribute = widget_name
            widget.set_property('model-attribute', widget_name)

        # Do a isinstance here instead of in the callback,
        # as an optimization, it'll never change in runtime anyway
        connection_id = widget.connect(
            'content-changed',
            self._on_widget__content_changed,
            attribute,
            IValidatableProxyWidget.providedBy(widget))
        widget.set_data('content-changed-id', connection_id)

        if IValidatableProxyWidget.providedBy(widget):
            connection_id = widget.connect(
                'notify::visible',
                self._on_widget__notify)
            widget.set_data('notify-visible-id', connection_id)

            connection_id = widget.connect(
                'notify::sensitive',
                self._on_widget__notify)
            widget.set_data('notify-sensitive-id', connection_id)

            connection_id = widget.connect(
                'validation-changed',
                self._on_widget__validation_changed,
                attribute)
            widget.set_data('validation-changed-id', connection_id)

        model_attributes = self._model_attributes
        # save this widget in our map
        if (attribute in model_attributes and
            # RadioButtons are allowed several times
            not gobject.type_is_a(widget, 'GtkRadioButton')):
            old_widget = model_attributes[attribute]
            raise KeyError("The widget %s (%r) in view %s is already in "
                           "the proxy, defined by widget %s (%r)" % (
                               widget_name, widget, self._view.__class__.__name__,
                               old_widget.name, old_widget))

        model_attributes[attribute] = widget
        self._reset_widget(attribute, widget)
Пример #2
0
    def _setup_widget(self, widget_name, widget):
        if not IProxyWidget.providedBy(widget):
            raise ProxyError("The widget %s (%r), in view %s is not "
                             "a kiwi widget and cannot be added to a proxy"
                             % (widget_name, widget,
                                self._view.__class__.__name__))

        data_type = _get_widget_data_type(widget)
        if data_type is None:
            raise ProxyError("The kiwi widget %s (%r) in view %s should "
                             "have a data type set" % (
                                 widget_name, widget, self._view.__class__.__name__))

        attribute = widget.get_property('model-attribute')
        if not attribute:
            attribute = widget_name
            widget.set_property('model-attribute', widget_name)

        # Do a isinstance here instead of in the callback,
        # as an optimization, it'll never change in runtime anyway
        connection_id = widget.connect(
            'content-changed',
            self._on_widget__content_changed,
            attribute,
            IValidatableProxyWidget.providedBy(widget))
        widget.set_data('content-changed-id', connection_id)

        if IValidatableProxyWidget.providedBy(widget):
            connection_id = widget.connect(
                'notify::visible',
                self._on_widget__notify)
            widget.set_data('notify-visible-id', connection_id)

            connection_id = widget.connect(
                'notify::sensitive',
                self._on_widget__notify)
            widget.set_data('notify-sensitive-id', connection_id)

            connection_id = widget.connect(
                'validation-changed',
                self._on_widget__validation_changed,
                attribute)
            widget.set_data('validation-changed-id', connection_id)

        model_attributes = self._model_attributes
        # save this widget in our map
        if (attribute in model_attributes and
            # RadioButtons are allowed several times
            not gobject.type_is_a(widget, 'GtkRadioButton')):
            old_widget = model_attributes[attribute]
            raise KeyError("The widget %s (%r) in view %s is already in "
                           "the proxy, defined by widget %s (%r)" % (
                               widget_name, widget, self._view.__class__.__name__,
                               old_widget.name, old_widget))

        model_attributes[attribute] = widget
        self._reset_widget(attribute, widget)
Пример #3
0
    def _reset_widget(self, attribute, widget):
        if self._model is None:
            # if we have no model, leave value unset so we pick up
            # the widget default below.
            value = ValueUnset
        else:
            # if we have a model, grab its value to update the widgets
            self._register_proxy_in_model(attribute)
            value = kgetattr(self._model, attribute, ValueUnset)

        self.update(attribute, value, block=True)

        from kiwi.ui.widgets.combo import ProxyComboBox
        # FIXME: If the initial value is None and it is not a valid option,
        # the ProxyComboBox may ignore it and keep the currently selected
        # value instead. See ProxyComboBox.update for more information.
        # Remove this when fixing the callsites or finding a better solution
        if (isinstance(widget, ProxyComboBox) and self._model is not None
                and value is None):
            self._update_attribute(widget, attribute, widget.read())

        # The initial value of the model is set, at this point
        # do a read, it'll trigger a validation for widgets who
        # supports it.
        if not IValidatableProxyWidget.providedBy(widget):
            return

        widget.validate(force=True)
Пример #4
0
    def _reset_widget(self, attribute, widget):
        if self._model is None:
            # if we have no model, leave value unset so we pick up
            # the widget default below.
            value = ValueUnset
        else:
            # if we have a model, grab its value to update the widgets
            self._register_proxy_in_model(attribute)
            value = kgetattr(self._model, attribute, ValueUnset)

        self.update(attribute, value, block=True)

        from kiwi.ui.widgets.combo import ProxyComboBox
        # FIXME: If the initial value is None and it is not a valid option,
        # the ProxyComboBox may ignore it and keep the currently selected
        # value instead. See ProxyComboBox.update for more information.
        # Remove this when fixing the callsites or finding a better solution
        if (isinstance(widget, ProxyComboBox) and
                self._model is not None and value is None):
            self._update_attribute(widget, attribute, widget.read())

        # The initial value of the model is set, at this point
        # do a read, it'll trigger a validation for widgets who
        # supports it.
        if not IValidatableProxyWidget.providedBy(widget):
            return

        widget.validate(force=True)
Пример #5
0
    def add_proxy(self, model=None, widgets=None):
        """
        Add a proxy to this view that automatically update a model when
        the view changes. Arguments:

          - model. the object we are proxing. It can be None if we don't have
            a model yet and we want to display the interface and set it up with
            future models.
          - widgets. the list of widgets that contains model attributes to be
            proxied. If it is None (or not specified) it will be the whole list
            of widgets this View has.

        This method return a Proxy object that you may want to use to force
        updates or setting new models. Keep a reference to it since there is
        no way to get that proxy later on. You have been warned (tm)
        """
        log.debug(
            '%s: adding proxy for %s' %
            (self.__class__.__name__, model and model.__class__.__name__))

        widgets = widgets or self.widgets
        proxy_widgets = []

        for widget_name in widgets:
            widget = getattr(self, widget_name, None)
            if widget is None:
                continue

            if not IValidatableProxyWidget.providedBy(widget):
                continue

            try:
                widget.connect('validation-changed',
                               self._on_child__validation_changed, widget_name)
            except TypeError:
                raise AssertionError("%r does not have a validation-changed "
                                     "signal." % widget)

            proxy_widgets.append((widget_name, widget))

        proxy = Proxy(self, model, widgets)
        self._proxies.append(proxy)

        for widget_name, widget in proxy_widgets:
            # Do not store validation value for invisible/insensitive widgets.
            # If they turn visible/sensitive, _on_child__validation_changed
            # will handle that
            if (not widget.get_property('visible')
                    or not widget.get_property('sensitive')):
                continue

            # Proxy.__init__ will call widget.validate(force=True), so we
            # can use rely on widget.is_valid() here
            self._validation[widget_name] = widget.is_valid()
            validation_log.info(
                "%s: %s=%r (initial)" %
                (self.__class__.__name__, widget_name, widget.is_valid()))

        return proxy
Пример #6
0
    def add_proxy(self, model=None, widgets=None):
        """
        Add a proxy to this view that automatically update a model when
        the view changes. Arguments:

          - model. the object we are proxing. It can be None if we don't have
            a model yet and we want to display the interface and set it up with
            future models.
          - widgets. the list of widgets that contains model attributes to be
            proxied. If it is None (or not specified) it will be the whole list
            of widgets this View has.

        This method return a Proxy object that you may want to use to force
        updates or setting new models. Keep a reference to it since there is
        no way to get that proxy later on. You have been warned (tm)
        """
        log('%s: adding proxy for %s' % (
            self.__class__.__name__,
            model and model.__class__.__name__))

        widgets = widgets or self.widgets
        proxy_widgets = []

        for widget_name in widgets:
            widget = getattr(self, widget_name, None)
            if widget is None:
                continue

            if not IValidatableProxyWidget.providedBy(widget):
                continue

            try:
                widget.connect('validation-changed',
                               self._on_child__validation_changed,
                               widget_name)
            except TypeError:
                raise AssertionError("%r does not have a validation-changed "
                                     "signal." % widget)

            proxy_widgets.append((widget_name, widget))

        proxy = Proxy(self, model, widgets)
        self._proxies.append(proxy)

        for widget_name, widget in proxy_widgets:
            # Do not store validation value for invisible/insensitive widgets.
            # If they turn visible/sensitive, _on_child__validation_changed
            # will handle that
            if (not widget.get_property('visible') or
                not widget.get_property('sensitive')):
                continue

            # Proxy.__init__ will call widget.validate(force=True), so we
            # can use rely on widget.is_valid() here
            self._validation[widget_name] = widget.is_valid()
            validation_log.info("%s: %s=%r (initial)" % (
                self.__class__.__name__, widget_name, widget.is_valid()))

        return proxy
Пример #7
0
    def add_proxy(self, model=None, widgets=None):
        """
        Add a proxy to this view that automatically update a model when
        the view changes. Arguments:

          - model. the object we are proxing. It can be None if we don't have
            a model yet and we want to display the interface and set it up with
            future models.
          - widgets. the list of widgets that contains model attributes to be
            proxied. If it is None (or not specified) it will be the whole list
            of widgets this View has.

        This method return a Proxy object that you may want to use to force
        updates or setting new models. Keep a reference to it since there is
        no way to get that proxy later on. You have been warned (tm)
        """
        log('%s: adding proxy for %s' % (
            self.__class__.__name__,
            model and model.__class__.__name__))

        widgets = widgets or self.widgets

        for widget_name in widgets:
            widget = getattr(self, widget_name, None)
            if widget is None:
                continue

            if not IValidatableProxyWidget.providedBy(widget):
                continue

            try:
                widget.connect('validation-changed',
                               self._on_child__validation_changed,
                               widget_name)
            except TypeError:
                raise AssertionError("%r does not have a validation-changed "
                                     "signal." % widget)

            if (widget.props.mandatory and
                widget.props.sensitive and
                widget.props.visible):
                try:
                    value = widget.read()
                    empty = value is ValueUnset or value is None
                    validation_log.info("%s: %s=%r (initial)" % (
                        self.__class__.__name__, widget_name, value))
                    if empty:
                        self._validation[widget_name] = False
                # FIXME: This is probably wrong, but we get improperly placed
                #        thousand operators in other places that has to be fixed first
                except ValidationError:
                    pass
        proxy = Proxy(self, model, widgets)
        self._proxies.append(proxy)
        return proxy
Пример #8
0
    def _write_widget(self, widget, indent=0, props=None, extra=None):
        extra = extra or []

        line_props = []
        name = self._items.get(hash(widget), '')
        if name:
            line_props.append(name)

        line_props.extend(self._get_packing_properties(widget))

        spaces = (' ' * (indent * 2))
        if not props:
            props = []

        if not widget.get_visible():
            props.append('hidden')
        if not widget.get_sensitive():
            props.append('insensitive')

        if (widget.get_sensitive() and
            widget.get_visible() and
            not widget.get_can_focus() and
            self._is_interactive_widget(widget)):
            props.append('unfocusable')
            fmt = "%s %s is not focusable"
            self.failures.append(fmt % (gobject.type_name(widget),
                                        self._items.get(hash(widget),
                                                        '???')))

        if IValidatableProxyWidget.providedBy(widget):
            if (not widget.is_valid() and
                widget.get_sensitive() and
                widget.get_visible()):
                if widget.mandatory:
                    props.append('mandatory')
                else:
                    props.append('invalid')

        if props:
            prop_lines = ' ' + ', '.join(props)
        else:
            prop_lines = ''
        self.output += "%s%s(%s):%s\n" % (
            spaces,
            gobject.type_name(widget),
            ', '.join(line_props),
            prop_lines)
        spaces = (' ' * ((indent + 1) * 2))
        for line in extra:
            self.output += spaces + line + '\n'
Пример #9
0
    def _write_widget(self, widget, indent=0, props=None, extra=None):
        extra = extra or []

        line_props = []
        name = self._items.get(widget, '')
        if name:
            line_props.append(name)

        line_props.extend(self._get_packing_properties(widget))

        spaces = (' ' * (indent * 2))
        if not props:
            props = []

        g_name = GObject.type_name(widget)
        if g_name in ['GtkHBox', 'GtkVBox']:
            g_name = 'GtkBox'
        elif g_name in ['GtkHButtonBox', 'GtkVButtonBox']:
            g_name = 'GtkButtonBox'

        if not widget.get_visible():
            props.append('hidden')
        if not widget.get_sensitive():
            props.append('insensitive')

        if (widget.get_sensitive() and widget.get_visible()
                and not widget.get_can_focus()
                and self._is_interactive_widget(widget)):
            props.append('unfocusable')
            fmt = "%s %s is not focusable"
            self.failures.append(fmt %
                                 (g_name, self._items.get(widget, '???')))

        if IValidatableProxyWidget.providedBy(widget):
            if (not widget.is_valid() and widget.get_sensitive()
                    and widget.get_visible()):
                if widget.mandatory:
                    props.append('mandatory')
                else:
                    props.append('invalid')

        if props:
            prop_lines = ' ' + ', '.join(props)
        else:
            prop_lines = ''
        self.output += "%s%s(%s):%s\n" % (spaces, g_name,
                                          ', '.join(line_props), prop_lines)
        spaces = (' ' * ((indent + 1) * 2))
        for line in extra:
            self.output += spaces + line + '\n'
Пример #10
0
    def remove_widget(self, name):
        """
        Removes a widget from the proxy

        :param name: the name of the widget to remove
        """
        if not name in self._model_attributes:
            raise TypeError("there is no widget called %s" % name)

        widget = self._model_attributes.pop(name)
        widget.disconnect(widget._content_changed_id)

        if IValidatableProxyWidget.providedBy(widget):
            for data_name in ['_notify_visible_id', '_notify_sensitive_id']:
                widget.disconnect(getattr(widget, data_name))
Пример #11
0
    def remove_widget(self, name):
        """
        Removes a widget from the proxy

        :param name: the name of the widget to remove
        """
        if not name in self._model_attributes:
            raise TypeError("there is no widget called %s" % name)

        widget = self._model_attributes.pop(name)
        widget.disconnect(widget.get_data('content-changed-id'))

        if IValidatableProxyWidget.providedBy(widget):
            for data_name in ('notify-visible-id', 'notify-sensitive-id'):
                widget.disconnect(widget.get_data(data_name))
Пример #12
0
    def remove_widget(self, name):
        """
        Removes a widget from the proxy

        :param name: the name of the widget to remove
        """
        if not name in self._model_attributes:
            raise TypeError("there is no widget called %s" % name)

        widget = self._model_attributes.pop(name)
        widget.disconnect(widget.get_data("content-changed-id"))

        if IValidatableProxyWidget.providedBy(widget):
            for data_name in ("notify-visible-id", "notify-sensitive-id"):
                widget.disconnect(widget.get_data(data_name))
Пример #13
0
    def remove_widget(self, name):
        """
        Removes a widget from the proxy

        :param name: the name of the widget to remove
        """
        if not name in self._model_attributes:
            raise TypeError("there is no widget called %s" % name)

        widget = self._model_attributes.pop(name)
        widget.disconnect(widget._content_changed_id)

        if IValidatableProxyWidget.providedBy(widget):
            for data_name in ['_notify_visible_id',
                              '_notify_sensitive_id']:
                widget.disconnect(getattr(widget, data_name))
Пример #14
0
    def _reset_widget(self, attribute, widget):
        if self._model is None:
            # if we have no model, leave value unset so we pick up
            # the widget default below.
            value = ValueUnset
        else:
            # if we have a model, grab its value to update the widgets
            self._register_proxy_in_model(attribute)
            value = kgetattr(self._model, attribute, ValueUnset)

        self.update(attribute, value, block=True)

        # The initial value of the model is set, at this point
        # do a read, it'll trigger a validation for widgets who
        # supports it.
        if not IValidatableProxyWidget.providedBy(widget):
            return

        widget.validate(force=True)
Пример #15
0
    def _reset_widget(self, attribute, widget):
        if self._model is None:
            # if we have no model, leave value unset so we pick up
            # the widget default below.
            value = ValueUnset
        else:
            # if we have a model, grab its value to update the widgets
            self._register_proxy_in_model(attribute)
            value = kgetattr(self._model, attribute, ValueUnset)

        self.update(attribute, value, block=True)

        # The initial value of the model is set, at this point
        # do a read, it'll trigger a validation for widgets who
        # supports it.
        if not IValidatableProxyWidget.providedBy(widget):
            return

        widget.validate(force=True)
Пример #16
0
    def add_proxy(self, model=None, widgets=None):
        """
        Add a proxy to this view that automatically update a model when
        the view changes. Arguments:

          - model. the object we are proxing. It can be None if we don't have
            a model yet and we want to display the interface and set it up with
            future models.
          - widgets. the list of widgets that contains model attributes to be
            proxied. If it is None (or not specified) it will be the whole list
            of widgets this View has.

        This method return a Proxy object that you may want to use to force
        updates or setting new models. Keep a reference to it since there is
        no way to get that proxy later on. You have been warned (tm)
        """
        log('%s: adding proxy for %s' % (
            self.__class__.__name__,
            model and model.__class__.__name__))

        widgets = widgets or self.widgets

        for widget_name in widgets:
            widget = getattr(self, widget_name, None)
            if widget is None:
                continue

            if not IValidatableProxyWidget.providedBy(widget):
                continue

            try:
                widget.connect('validation-changed',
                               self._on_child__validation_changed,
                               widget_name)
            except TypeError:
                raise AssertionError("%r does not have a validation-changed "
                                     "signal." % widget)

        proxy = Proxy(self, model, widgets)
        self._proxies.append(proxy)
        return proxy
Пример #17
0
    def add_proxy(self, model=None, widgets=None):
        """
        Add a proxy to this view that automatically update a model when
        the view changes. Arguments:

          - model. the object we are proxing. It can be None if we don't have
            a model yet and we want to display the interface and set it up with
            future models.
          - widgets. the list of widgets that contains model attributes to be
            proxied. If it is None (or not specified) it will be the whole list
            of widgets this View has.

        This method return a Proxy object that you may want to use to force
        updates or setting new models. Keep a reference to it since there is
        no way to get that proxy later on. You have been warned (tm)
        """
        log('%s: adding proxy for %s' % (
            self.__class__.__name__,
            model and model.__class__.__name__))

        widgets = widgets or self.widgets

        for widget_name in widgets:
            widget = getattr(self, widget_name, None)
            if widget is None:
                continue

            if not IValidatableProxyWidget.providedBy(widget):
                continue

            try:
                widget.connect('validation-changed',
                               self._on_child__validation_changed,
                               widget_name)
            except TypeError:
                raise AssertionError("%r does not have a validation-changed "
                                     "signal." % widget)

        proxy = Proxy(self, model, widgets)
        self._proxies.append(proxy)
        return proxy
Пример #18
0
    def _write_widget(self, widget, indent=0, props=None, extra=None):
        extra = extra or []

        line_props = []
        name = self._items.get(widget, '')

        # FIXME python3: There're 2 tests that use SaleWithToolbarSearch that
        # are getting the name as 'results' or 'sales'. Idk what exactly is
        # happening in _add_namespace...
        if isinstance(widget, SearchResultListView) and name == 'sales':
            name = 'results'

        if name:
            line_props.append(name)

        line_props.extend(self._get_packing_properties(widget))

        spaces = (' ' * (indent * 2))
        if not props:
            props = []

        g_name = GObject.type_name(widget)
        if g_name in ['GtkHBox', 'GtkVBox']:
            g_name = 'GtkBox'
        elif g_name in ['GtkHButtonBox', 'GtkVButtonBox']:
            g_name = 'GtkButtonBox'

        if not widget.get_visible():
            props.append('hidden')
        if not widget.get_sensitive():
            props.append('insensitive')

        if (widget.get_sensitive() and
                widget.get_visible() and
                not widget.get_can_focus() and
                self._is_interactive_widget(widget)):
            props.append('unfocusable')
            fmt = "%s %s is not focusable"
            self.failures.append(fmt % (g_name,
                                        self._items.get(widget,
                                                        '???')))

        if IValidatableProxyWidget.providedBy(widget):
            if (not widget.is_valid() and
                    widget.get_sensitive() and
                    widget.get_visible()):
                if widget.mandatory:
                    props.append('mandatory')
                else:
                    props.append('invalid')

        if props:
            prop_lines = ' ' + ', '.join(props)
        else:
            prop_lines = ''
        self.output += "%s%s(%s):%s\n" % (
            spaces,
            g_name,
            ', '.join(line_props),
            prop_lines)
        spaces = (' ' * ((indent + 1) * 2))
        for line in extra:
            self.output += spaces + line + '\n'