Exemple #1
0
class DictMultiSelectionEntry(DictEntry):
    expand = False

    def create_widget(self):
        widget = Gtk.ScrolledWindow()
        widget.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        widget.set_shadow_type(Gtk.ShadowType.ETCHED_IN)
        widget.set_size_request(100, 100)

        model = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING)
        self.tree = TreeViewControl()
        self.tree.set_model(model)
        self.tree.set_search_column(1)
        self.tree.connect('focus-out-event',
                          lambda w, e: self.parent_widget._focus_out())
        self.tree.set_headers_visible(False)
        selection = self.tree.get_selection()
        selection.set_mode(Gtk.SelectionMode.MULTIPLE)
        selection.connect('changed', self._changed)
        widget.add(self.tree)

        self.selection = self.definition['selection']
        if self.definition.get('sort', True):
            self.selection.sort(key=operator.itemgetter(1))
        for value, name in self.selection:
            name = str(name)
            model.append((value, name))

        name_column = Gtk.TreeViewColumn()
        name_cell = Gtk.CellRendererText()
        name_column.pack_start(name_cell, expand=True)
        name_column.add_attribute(name_cell, 'text', 1)
        self.tree.append_column(name_column)

        return widget

    def get_value(self):
        model, paths = self.tree.get_selection().get_selected_rows()
        return [model[path][0] for path in paths]

    def set_value(self, value):
        value2path = {v: idx for idx, (v, _) in enumerate(self.selection)}
        selection = self.tree.get_selection()
        selection.handler_block_by_func(self._changed)
        try:
            selection.unselect_all()
            for v in value:
                if v in value2path:
                    selection.select_path(value2path[v])
        finally:
            selection.handler_unblock_by_func(self._changed)

    def _changed(self, selection):
        GLib.idle_add(self.parent_widget._focus_out)

    def set_readonly(self, readonly):
        selection = self.tree.get_selection()
        selection.set_select_function(lambda *a: not readonly)
class MultiSelection(Widget, SelectionMixin):
    expand = True

    def __init__(self, view, attrs):
        super(MultiSelection, self).__init__(view, attrs)

        if int(attrs.get('yexpand', self.expand)):
            self.widget = gtk.ScrolledWindow()
            self.widget.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
            self.widget.set_shadow_type(gtk.SHADOW_ETCHED_IN)
        else:
            self.widget = gtk.VBox()
        self.widget.get_accessible().set_name(attrs.get('string', ''))

        self.model = gtk.ListStore(gobject.TYPE_INT, gobject.TYPE_STRING)
        self.tree = TreeViewControl()
        self.tree.set_model(self.model)
        self.tree.set_search_column(1)
        self.tree.connect('focus-out-event', lambda *a: self._focus_out())
        self.tree.set_headers_visible(False)
        selection = self.tree.get_selection()
        selection.set_mode(gtk.SELECTION_MULTIPLE)
        selection.connect('changed', self.changed)
        self.widget.add(self.tree)
        name_column = gtk.TreeViewColumn()
        name_cell = gtk.CellRendererText()
        name_column.pack_start(name_cell)
        name_column.add_attribute(name_cell, 'text', 1)
        self.tree.append_column(name_column)

        self.nullable_widget = False
        self.init_selection()
        self.id2path = {}

    def _color_widget(self):
        return self.tree

    def _readonly_set(self, readonly):
        super(MultiSelection, self)._readonly_set(readonly)
        set_widget_style(self.tree, not readonly)
        selection = self.tree.get_selection()
        selection.set_select_function(lambda *a: not readonly)

    @property
    def modified(self):
        if self.record and self.field:
            group = set(r.id for r in self.field.get_client(self.record))
            value = set(self.get_value())
            return value != group
        return False

    def changed(self, selection):
        def focus_out():
            if self.widget.props.window:
                self._focus_out()
        # Must be deferred because it triggers a display of the form
        gobject.idle_add(focus_out)

    def get_value(self):
        model, paths = self.tree.get_selection().get_selected_rows()
        return [model[path][0] for path in paths]

    def set_value(self, record, field):
        field.set_client(record, self.get_value())

    def display(self, record, field):
        selection = self.tree.get_selection()
        selection.handler_block_by_func(self.changed)
        try:
            # Remove select_function to allow update,
            # it will be set back in the super call
            selection.set_select_function(lambda *a: True)
            self.update_selection(record, field)
            self.model.clear()
            if field is None:
                return
            id2path = {}
            for idx, (value, name) in enumerate(self.selection):
                self.model.append((value, name))
                id2path[value] = idx
            selection.unselect_all()
            group = field.get_client(record)
            for element in group:
                if (element not in group.record_removed
                        and element not in group.record_deleted
                        and element.id in id2path):
                    selection.select_path(id2path[element.id])
            super(MultiSelection, self).display(record, field)
        finally:
            selection.handler_unblock_by_func(self.changed)
class MultiSelection(Widget, SelectionMixin):
    expand = True

    def __init__(self, view, attrs):
        super(MultiSelection, self).__init__(view, attrs)

        self.widget = gtk.ScrolledWindow()
        self.widget.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        self.widget.set_shadow_type(gtk.SHADOW_ETCHED_IN)
        self.widget.get_accessible().set_name(attrs.get('string', ''))

        self.model = gtk.ListStore(gobject.TYPE_INT, gobject.TYPE_STRING)
        self.tree = TreeViewControl()
        self.tree.set_model(self.model)
        self.tree.set_search_column(1)
        self.tree.connect('focus-out-event', lambda *a: self._focus_out())
        self.tree.set_headers_visible(False)
        selection = self.tree.get_selection()
        selection.set_mode(gtk.SELECTION_MULTIPLE)
        selection.connect('changed', self.changed)
        self.widget.add(self.tree)
        name_column = gtk.TreeViewColumn()
        name_cell = gtk.CellRendererText()
        name_column.pack_start(name_cell)
        name_column.add_attribute(name_cell, 'text', 1)
        self.tree.append_column(name_column)

        self.nullable_widget = False
        self.init_selection()
        self.id2path = {}

    @property
    def modified(self):
        if self.record and self.field:
            group = set(r.id for r in self.field.get_client(self.record))
            value = set(self.get_value())
            return value != group
        return False

    def changed(self, selection):
        def focus_out():
            if self.widget.props.window:
                self._focus_out()
        # Must be deferred because it triggers a display of the form
        gobject.idle_add(focus_out)

    def get_value(self):
        model, paths = self.tree.get_selection().get_selected_rows()
        return [model[path][0] for path in paths]

    def set_value(self, record, field):
        field.set_client(record, self.get_value())

    def display(self, record, field):
        selection = self.tree.get_selection()
        selection.handler_block_by_func(self.changed)
        try:
            self.update_selection(record, field)
            super(MultiSelection, self).display(record, field)
            self.model.clear()
            if field is None:
                return
            id2path = {}
            for idx, (value, name) in enumerate(self.selection):
                self.model.append((value, name))
                id2path[value] = idx
            selection.unselect_all()
            group = field.get_client(record)
            for element in group:
                if (element not in group.record_removed
                        and element not in group.record_deleted
                        and element.id in id2path):
                    selection.select_path(id2path[element.id])
        finally:
            selection.handler_unblock_by_func(self.changed)