class ChannelListEditorDialog(Gtk.Dialog): def __init__(self, model, parent=None): Gtk.Dialog.__init__(self, title=_("Edit Channel Lists"), parent=parent) self.set_modal(True) self.set_destroy_with_parent(True) self.model = model self.devgroup = None self.channel_list = None self.set_default_size(600, 500) self.set_border_width(5) close_button = self.add_button(Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE) close_button.grab_default() self.vbox_main = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12) self.vbox_main.set_border_width(5) self.get_content_area().pack_start(self.vbox_main, True, True, 0) # channel groups groups_box = Gtk.Box(spacing=6) groups_frame = BaseFrame("<b>%s</b>" % _("Channel groups"), groups_box) self.vbox_main.pack_start(groups_frame, False, True, 0) self.channel_groups = ChannelGroupsStore() self.channel_groups_view = ChannelGroupsView(self.channel_groups) self.channel_groups_view.set_headers_visible(False) self.channel_groups_view.get_selection().connect("changed", self.on_group_changed) self.channel_groups_view.get_renderer().connect("edited", self.on_channel_group_edited) scrolledgroups = Gtk.ScrolledWindow() scrolledgroups.add(self.channel_groups_view) scrolledgroups.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) scrolledgroups.set_shadow_type(Gtk.ShadowType.ETCHED_IN) groups_box.pack_start(scrolledgroups, True, True, 0) groups_buttonbox = Gtk.ButtonBox(orientation=Gtk.Orientation.VERTICAL) groups_buttonbox.set_spacing(6) groups_buttonbox.set_layout(Gtk.ButtonBoxStyle.START) groups_box.pack_end(groups_buttonbox, False, False, 0) new_group_button = Gtk.Button(stock=Gtk.STOCK_ADD) new_group_button.connect("clicked", self.on_new_group_clicked) groups_buttonbox.pack_start(new_group_button, True, True, 0) self.del_group_button = Gtk.Button(stock=Gtk.STOCK_REMOVE) self.del_group_button.connect("clicked", self.on_delete_group_clicked) groups_buttonbox.pack_start(self.del_group_button, True, True, 0) # device groups self.devgroupslist = Gtk.ListStore(str, int, GObject.GObject) self.devgroupscombo = Gtk.ComboBox.new_with_model_and_entry(self.devgroupslist) self.devgroupscombo.connect("changed", self.on_devgroupscombo_changed) cell_adapter = Gtk.CellRendererText() self.devgroupscombo.pack_start(cell_adapter, True) self.devgroupscombo.set_entry_text_column(0) groups_label = Gtk.Label() groups_label.set_markup_with_mnemonic(_("_Group:")) groups_label.set_mnemonic_widget(self.devgroupscombo) groups_box = Gtk.Box(spacing=6) groups_box.pack_start(groups_label, False, True, 0) groups_box.pack_start(self.devgroupscombo, True, True, 0) self.devgroups_frame = BaseFrame("<b>%s</b>" % _("Device groups"), groups_box, False, False) self.vbox_main.pack_start(self.devgroups_frame, False, True, 0) # channels channels_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6) self.vbox_main.pack_start(channels_box, True, True, 0) cbox = Gtk.Box(spacing=6) channels_box.pack_start(cbox, True, True, 0) # all channels self.channels_store = None self.channels_view = ChannelsView(self.channels_store) self.channels_view.set_headers_visible(False) self.channels_view.connect("row-activated", self.on_channels_view_activated) treesel = self.channels_view.get_selection() treesel.set_mode(Gtk.SelectionMode.MULTIPLE) treesel.connect("changed", self.on_channel_store_selected) left_frame = Frame("<b>%s</b>" % _("All channels"), self.channels_view) cbox.pack_start(left_frame, True, True, 0) # selected channels self.selected_channels_store = Gtk.ListStore(str, int) # Name, sid self.selected_channels_view = Gtk.TreeView.new_with_model(self.selected_channels_store) self.selected_channels_view.set_reorderable(True) self.selected_channels_view.set_headers_visible(False) self.selected_channels_view.connect("row-activated", self.on_selected_channels_view_activated) treesel = self.selected_channels_view.get_selection() treesel.connect("changed", self.on_selected_channels_changed) treesel.set_mode(Gtk.SelectionMode.MULTIPLE) col_name = Gtk.TreeViewColumn(_("Channel")) cell_name = Gtk.CellRendererText() col_name.pack_start(cell_name, True) col_name.add_attribute(cell_name, "markup", 0) self.selected_channels_view.append_column(col_name) self.selected_channels_view.show() self.scrolled_selected_channels = Gtk.ScrolledWindow() self.scrolled_selected_channels.set_shadow_type(Gtk.ShadowType.ETCHED_IN) self.scrolled_selected_channels.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) self.scrolled_selected_channels.add(self.selected_channels_view) self.select_group_helpbox = HelpBox() self.select_group_helpbox.set_markup(_("Choose a channel group")) self.right_frame = BaseFrame("<b>%s</b>" % _("Channels of group"), self.select_group_helpbox) cbox.pack_start(self.right_frame, True, True, 0) buttonbox = Gtk.ButtonBox() buttonbox.set_spacing(6) buttonbox.set_layout(Gtk.ButtonBoxStyle.SPREAD) self.add_channel_button = Gtk.Button(stock=Gtk.STOCK_ADD) self.add_channel_button.connect("clicked", self.on_add_channel_clicked) buttonbox.pack_start(self.add_channel_button, True, True, 0) self.remove_channel_button = Gtk.Button(stock=Gtk.STOCK_REMOVE) self.remove_channel_button.connect("clicked", self.on_remove_channel_clicked) buttonbox.pack_start(self.remove_channel_button, True, True, 0) channels_box.pack_start(buttonbox, False, False, 0) self.del_group_button.set_sensitive(False) self.add_channel_button.set_sensitive(False) self.remove_channel_button.set_sensitive(False) self.fill_device_groups() self.fill_channel_groups() self.show_all() def fill_channel_groups(self): def add_groups(proxy, groups, user_data): for gid, name in groups: self.channel_groups.append([gid, name, False]) # not editable self.model.get_channel_groups(result_handler=add_groups, error_handler=gnomedvb.global_error_handler) def fill_device_groups(self): def append_groups(groups): for group in groups: self.devgroupslist.append([group["name"], group["id"], group]) if len(groups) == 1: self.devgroup = groups[0] self.devgroups_frame.hide() else: self.devgroups_frame.show() self.devgroupscombo.set_active(0) self.model.get_registered_device_groups(result_handler=append_groups, error_handler=gnomedvb.global_error_handler) def refill_channel_groups(self): self.channel_groups.clear() self.fill_channel_groups() def fill_group_members(self): def add_channels(proxy, data, user_data): channels, success = data if success: for channel_id in channels: name, success = self.channel_list.get_channel_name(channel_id) if success: self.selected_channels_store.append([name, channel_id]) self.selected_channels_store.clear() data = self.get_selected_channel_group() if data: group_id, group_name = data self.channel_list.get_channels_of_group(group_id, result_handler=add_channels, error_handler=gnomedvb.global_error_handler) def get_selected_channels_all(self): sel = self.channels_view.get_selection() model, paths = sel.get_selected_rows() return [model[path][ChannelsStore.COL_SID] for path in paths] def get_selected_channels_selected_group(self): sel = self.selected_channels_view.get_selection() model, paths = sel.get_selected_rows() return [model[path][1] for path in paths] def get_selected_channel_group(self): model, aiter = self.channel_groups_view.get_selection().get_selected() if aiter == None: return None else: return self.channel_groups[aiter][0], self.channel_groups[aiter][1] def on_new_group_clicked(self, button): aiter = self.channel_groups.append() self.channel_groups.set_value(aiter, self.channel_groups.COL_EDITABLE, True) self.channel_groups_view.grab_focus() path = self.channel_groups.get_path(aiter) self.channel_groups_view.set_cursor(path, self.channel_groups_view.get_column(0), True) self.channel_groups_view.scroll_to_cell(path) def on_add_channel_group_finished(self, proxy, data, user_data): group_id, success = data if success: self.refill_channel_groups() else: error_dialog = Gtk.MessageDialog(parent=self, flags=Gtk.DialogFlags.MODAL|Gtk.DialogFlags.DESTROY_WITH_PARENT, type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK) error_dialog.set_markup( "<big><span weight=\"bold\">%s</span></big>" % _("An error occured while adding the group")) error_dialog.run() error_dialog.destroy() def on_delete_group_clicked(self, button): dialog = Gtk.MessageDialog(parent=self, flags=Gtk.DialogFlags.MODAL|Gtk.DialogFlags.DESTROY_WITH_PARENT, type=Gtk.MessageType.QUESTION, buttons=Gtk.ButtonsType.YES_NO) group_id, group_name = self.get_selected_channel_group() msg = _("Are you sure you want to delete the group '%s'?") % group_name dialog.set_markup ( "<big><span weight=\"bold\">%s</span></big>\n\n%s" % (msg, _("All assignments to this group will be lost."))) if dialog.run() == Gtk.ResponseType.YES: self.model.remove_channel_group(group_id, result_handler=self.on_remove_channel_group_finished, error_handler=gnomedvb.global_error_handler) dialog.destroy() def on_remove_channel_group_finished(self, proxy, success, user_data): if success: self.refill_channel_groups() else: error_dialog = Gtk.MessageDialog(parent=self, flags=Gtk.DialogFlags.MODAL|Gtk.DialogFlags.DESTROY_WITH_PARENT, type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK) error_dialog.set_markup( "<big><span weight=\"bold\">%s</span></big>" % _("An error occured while removing the group")) error_dialog.run() error_dialog.destroy() def on_add_channel_clicked(self, button): channel_ids = self.get_selected_channels_all() group_data = self.get_selected_channel_group() if group_data: for channel_id in channel_ids: self.channel_list.add_channel_to_group(channel_id, group_data[0]) self.fill_group_members() def on_remove_channel_clicked(self, button): channel_ids = self.get_selected_channels_selected_group() group_data = self.get_selected_channel_group() if group_data: for channel_id in channel_ids: self.channel_list.remove_channel_from_group(channel_id, group_data[0]) self.fill_group_members() def on_channel_store_selected(self, treeselection): model, paths = treeselection.get_selected_rows() val = (len(paths) > 0 and self.get_selected_channel_group() != None) self.add_channel_button.set_sensitive(val) def on_selected_channels_changed(self, treeselection): model, paths = treeselection.get_selected_rows() val = (len(paths) > 0) self.remove_channel_button.set_sensitive(val) def on_group_changed(self, treeselection): model, aiter = treeselection.get_selected() val = aiter != None self.del_group_button.set_sensitive(val) if val: self.fill_group_members() self.right_frame.set_aligned_child(self.scrolled_selected_channels) else: self.right_frame.set_aligned_child(self.select_group_helpbox) self.selected_channels_store.clear() def on_channel_group_edited(self, renderer, path, new_text): aiter = self.channel_groups.get_iter(path) if len(new_text) == 0: self.channel_groups.remove(aiter) else: self.model.add_channel_group(new_text, result_handler=self.on_add_channel_group_finished, error_handler=gnomedvb.global_error_handler) def get_selected_group(self): if self.devgroup != None: return self.devgroup aiter = self.devgroupscombo.get_active_iter() if aiter == None: return None else: return self.devgroupslist[aiter][2] def on_devgroupscombo_changed(self, combo): group = self.get_selected_group() if group != None: self.channel_list = group.get_channel_list() self.channels_store = ChannelsStore(group) self.channels_view.set_model(self.channels_store) def on_channels_view_activated(self, treeview, aiter, path): self.on_add_channel_clicked(None) def on_selected_channels_view_activated(self, treeview, aiter, path): self.on_remove_channel_clicked(None)
class ChannelListEditorDialog(Gtk.Dialog): def __init__(self, model, parent=None): Gtk.Dialog.__init__(self, title=_("Edit Channel Lists"), parent=parent) self.set_modal(True) self.set_destroy_with_parent(True) self.model = model self.devgroup = None self.channel_list = None self.set_default_size(600, 500) self.set_border_width(5) close_button = self.add_button(Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE) close_button.grab_default() self.vbox_main = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12) self.vbox_main.set_border_width(5) self.get_content_area().pack_start(self.vbox_main, True, True, 0) # channel groups groups_box = Gtk.Box(spacing=6) groups_frame = BaseFrame("<b>%s</b>" % _("Channel groups"), groups_box) self.vbox_main.pack_start(groups_frame, False, True, 0) self.channel_groups = ChannelGroupsStore() self.channel_groups_view = ChannelGroupsView(self.channel_groups) self.channel_groups_view.set_headers_visible(False) self.channel_groups_view.get_selection().connect( "changed", self.on_group_changed) self.channel_groups_view.get_renderer().connect( "edited", self.on_channel_group_edited) scrolledgroups = Gtk.ScrolledWindow() scrolledgroups.add(self.channel_groups_view) scrolledgroups.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) scrolledgroups.set_shadow_type(Gtk.ShadowType.ETCHED_IN) groups_box.pack_start(scrolledgroups, True, True, 0) groups_buttonbox = Gtk.ButtonBox(orientation=Gtk.Orientation.VERTICAL) groups_buttonbox.set_spacing(6) groups_buttonbox.set_layout(Gtk.ButtonBoxStyle.START) groups_box.pack_end(groups_buttonbox, False, False, 0) new_group_button = Gtk.Button(stock=Gtk.STOCK_ADD) new_group_button.connect("clicked", self.on_new_group_clicked) groups_buttonbox.pack_start(new_group_button, True, True, 0) self.del_group_button = Gtk.Button(stock=Gtk.STOCK_REMOVE) self.del_group_button.connect("clicked", self.on_delete_group_clicked) groups_buttonbox.pack_start(self.del_group_button, True, True, 0) # device groups self.devgroupslist = Gtk.ListStore(str, int, GObject.GObject) self.devgroupscombo = Gtk.ComboBox.new_with_model_and_entry( self.devgroupslist) self.devgroupscombo.connect("changed", self.on_devgroupscombo_changed) cell_adapter = Gtk.CellRendererText() self.devgroupscombo.pack_start(cell_adapter, True) self.devgroupscombo.set_entry_text_column(0) groups_label = Gtk.Label() groups_label.set_markup_with_mnemonic(_("_Group:")) groups_label.set_mnemonic_widget(self.devgroupscombo) groups_box = Gtk.Box(spacing=6) groups_box.pack_start(groups_label, False, True, 0) groups_box.pack_start(self.devgroupscombo, True, True, 0) self.devgroups_frame = BaseFrame("<b>%s</b>" % _("Device groups"), groups_box, False, False) self.vbox_main.pack_start(self.devgroups_frame, False, True, 0) # channels channels_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6) self.vbox_main.pack_start(channels_box, True, True, 0) cbox = Gtk.Box(spacing=6) channels_box.pack_start(cbox, True, True, 0) # all channels self.channels_store = None self.channels_view = ChannelsView(self.channels_store) self.channels_view.set_headers_visible(False) self.channels_view.connect("row-activated", self.on_channels_view_activated) treesel = self.channels_view.get_selection() treesel.set_mode(Gtk.SelectionMode.MULTIPLE) treesel.connect("changed", self.on_channel_store_selected) left_frame = Frame("<b>%s</b>" % _("All channels"), self.channels_view) cbox.pack_start(left_frame, True, True, 0) # selected channels self.selected_channels_store = Gtk.ListStore(str, int) # Name, sid self.selected_channels_view = Gtk.TreeView.new_with_model( self.selected_channels_store) self.selected_channels_view.set_reorderable(True) self.selected_channels_view.set_headers_visible(False) self.selected_channels_view.connect( "row-activated", self.on_selected_channels_view_activated) treesel = self.selected_channels_view.get_selection() treesel.connect("changed", self.on_selected_channels_changed) treesel.set_mode(Gtk.SelectionMode.MULTIPLE) col_name = Gtk.TreeViewColumn(_("Channel")) cell_name = Gtk.CellRendererText() col_name.pack_start(cell_name, True) col_name.add_attribute(cell_name, "markup", 0) self.selected_channels_view.append_column(col_name) self.selected_channels_view.show() self.scrolled_selected_channels = Gtk.ScrolledWindow() self.scrolled_selected_channels.set_shadow_type( Gtk.ShadowType.ETCHED_IN) self.scrolled_selected_channels.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) self.scrolled_selected_channels.add(self.selected_channels_view) self.select_group_helpbox = HelpBox() self.select_group_helpbox.set_markup(_("Choose a channel group")) self.right_frame = BaseFrame("<b>%s</b>" % _("Channels of group"), self.select_group_helpbox) cbox.pack_start(self.right_frame, True, True, 0) buttonbox = Gtk.ButtonBox() buttonbox.set_spacing(6) buttonbox.set_layout(Gtk.ButtonBoxStyle.SPREAD) self.add_channel_button = Gtk.Button(stock=Gtk.STOCK_ADD) self.add_channel_button.connect("clicked", self.on_add_channel_clicked) buttonbox.pack_start(self.add_channel_button, True, True, 0) self.remove_channel_button = Gtk.Button(stock=Gtk.STOCK_REMOVE) self.remove_channel_button.connect("clicked", self.on_remove_channel_clicked) buttonbox.pack_start(self.remove_channel_button, True, True, 0) channels_box.pack_start(buttonbox, False, False, 0) self.del_group_button.set_sensitive(False) self.add_channel_button.set_sensitive(False) self.remove_channel_button.set_sensitive(False) self.fill_device_groups() self.fill_channel_groups() self.show_all() def fill_channel_groups(self): def add_groups(proxy, groups, user_data): for gid, name in groups: self.channel_groups.append([gid, name, False]) # not editable self.model.get_channel_groups( result_handler=add_groups, error_handler=gnomedvb.global_error_handler) def fill_device_groups(self): def append_groups(groups): for group in groups: self.devgroupslist.append([group["name"], group["id"], group]) if len(groups) == 1: self.devgroup = groups[0] self.devgroups_frame.hide() else: self.devgroups_frame.show() self.devgroupscombo.set_active(0) self.model.get_registered_device_groups( result_handler=append_groups, error_handler=gnomedvb.global_error_handler) def refill_channel_groups(self): self.channel_groups.clear() self.fill_channel_groups() def fill_group_members(self): def add_channels(proxy, data, user_data): channels, success = data if success: for channel_id in channels: name, success = self.channel_list.get_channel_name( channel_id) if success: self.selected_channels_store.append([name, channel_id]) self.selected_channels_store.clear() data = self.get_selected_channel_group() if data: group_id, group_name = data self.channel_list.get_channels_of_group( group_id, result_handler=add_channels, error_handler=gnomedvb.global_error_handler) def get_selected_channels_all(self): sel = self.channels_view.get_selection() model, paths = sel.get_selected_rows() return [model[path][ChannelsStore.COL_SID] for path in paths] def get_selected_channels_selected_group(self): sel = self.selected_channels_view.get_selection() model, paths = sel.get_selected_rows() return [model[path][1] for path in paths] def get_selected_channel_group(self): model, aiter = self.channel_groups_view.get_selection().get_selected() if aiter == None: return None else: return self.channel_groups[aiter][0], self.channel_groups[aiter][1] def on_new_group_clicked(self, button): aiter = self.channel_groups.append() self.channel_groups.set_value(aiter, self.channel_groups.COL_EDITABLE, True) self.channel_groups_view.grab_focus() path = self.channel_groups.get_path(aiter) self.channel_groups_view.set_cursor( path, self.channel_groups_view.get_column(0), True) self.channel_groups_view.scroll_to_cell(path) def on_add_channel_group_finished(self, proxy, data, user_data): group_id, success = data if success: self.refill_channel_groups() else: error_dialog = Gtk.MessageDialog( parent=self, flags=Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK) error_dialog.set_markup( "<big><span weight=\"bold\">%s</span></big>" % _("An error occurred while adding the group")) error_dialog.run() error_dialog.destroy() def on_delete_group_clicked(self, button): dialog = Gtk.MessageDialog(parent=self, flags=Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, type=Gtk.MessageType.QUESTION, buttons=Gtk.ButtonsType.YES_NO) group_id, group_name = self.get_selected_channel_group() msg = _("Are you sure you want to delete the group '%s'?") % group_name dialog.set_markup( "<big><span weight=\"bold\">%s</span></big>\n\n%s" % (msg, _("All assignments to this group will be lost."))) if dialog.run() == Gtk.ResponseType.YES: self.model.remove_channel_group( group_id, result_handler=self.on_remove_channel_group_finished, error_handler=gnomedvb.global_error_handler) dialog.destroy() def on_remove_channel_group_finished(self, proxy, success, user_data): if success: self.refill_channel_groups() else: error_dialog = Gtk.MessageDialog( parent=self, flags=Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK) error_dialog.set_markup( "<big><span weight=\"bold\">%s</span></big>" % _("An error occurred while removing the group")) error_dialog.run() error_dialog.destroy() def on_add_channel_clicked(self, button): channel_ids = self.get_selected_channels_all() group_data = self.get_selected_channel_group() if group_data: for channel_id in channel_ids: self.channel_list.add_channel_to_group(channel_id, group_data[0]) self.fill_group_members() def on_remove_channel_clicked(self, button): channel_ids = self.get_selected_channels_selected_group() group_data = self.get_selected_channel_group() if group_data: for channel_id in channel_ids: self.channel_list.remove_channel_from_group( channel_id, group_data[0]) self.fill_group_members() def on_channel_store_selected(self, treeselection): model, paths = treeselection.get_selected_rows() val = (len(paths) > 0 and self.get_selected_channel_group() != None) self.add_channel_button.set_sensitive(val) def on_selected_channels_changed(self, treeselection): model, paths = treeselection.get_selected_rows() val = (len(paths) > 0) self.remove_channel_button.set_sensitive(val) def on_group_changed(self, treeselection): model, aiter = treeselection.get_selected() val = aiter != None self.del_group_button.set_sensitive(val) if val: self.fill_group_members() self.right_frame.set_aligned_child(self.scrolled_selected_channels) else: self.right_frame.set_aligned_child(self.select_group_helpbox) self.selected_channels_store.clear() def on_channel_group_edited(self, renderer, path, new_text): aiter = self.channel_groups.get_iter(path) if len(new_text) == 0: self.channel_groups.remove(aiter) else: self.model.add_channel_group( new_text, result_handler=self.on_add_channel_group_finished, error_handler=gnomedvb.global_error_handler) def get_selected_group(self): if self.devgroup != None: return self.devgroup aiter = self.devgroupscombo.get_active_iter() if aiter == None: return None else: return self.devgroupslist[aiter][2] def on_devgroupscombo_changed(self, combo): group = self.get_selected_group() if group != None: self.channel_list = group.get_channel_list() self.channels_store = ChannelsStore(group) self.channels_view.set_model(self.channels_store) def on_channels_view_activated(self, treeview, aiter, path): self.on_add_channel_clicked(None) def on_selected_channels_view_activated(self, treeview, aiter, path): self.on_remove_channel_clicked(None)