def __init__(self, parent, device_group, channel=None, starttime=None, duration=60): """ @param parent: Parent window @type parent: Gtk.Window @param device_group: DeviceGroup instance """ Gtk.Dialog.__init__(self, parent=parent) self.set_modal(True) self.set_destroy_with_parent(True) self.set_default_size(320, -1) self.device_group = device_group self.date_valid = False self.allowed_delta = datetime.timedelta(hours=1) self.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.REJECT) self.ok_button = self.add_button(Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT) self.set_border_width(5) table = Gtk.Grid(orientation=Gtk.Orientation.VERTICAL) table.set_column_spacing(18) table.set_row_spacing(6) table.set_border_width(5) self.get_content_area().pack_start(table, True, True, 0) label_channel = TextFieldLabel() table.add(label_channel) if channel == None: self.channel_selected = False self.set_title(_("Add Timer")) self.ok_button.set_sensitive(False) label_channel.set_markup_with_mnemonic(_("_Channel:")) self.channels = ChannelsStore(device_group) scrolledchannels = Gtk.ScrolledWindow(expand=True) scrolledchannels.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) scrolledchannels.set_shadow_type(Gtk.ShadowType.ETCHED_IN) table.attach_next_to(scrolledchannels, label_channel, Gtk.PositionType.BOTTOM, 2, 1) self.channelsview = ChannelsView(self.channels) self.channelsview.set_headers_visible(False) self.channelsview.get_selection().connect("changed", self._on_channel_changed) scrolledchannels.add(self.channelsview) label_channel.set_mnemonic_widget(self.channelsview) self.channelsview.grab_focus() else: self.channel_selected = True self.set_title(_("Edit Timer")) self.ok_button.set_sensitive(True) label_channel.set_text(_("Channel:")) self.channels = None self.channelsview = None channel_label = TextFieldLabel(channel) table.attach_next_to(channel_label, label_channel, Gtk.PositionType.RIGHT, 1, 1) label_start = TextFieldLabel() label_start.set_markup_with_mnemonic(_("_Start time:")) table.add(label_start) hbox = Gtk.Box(spacing=6, hexpand=True) table.attach_next_to(hbox, label_start, Gtk.PositionType.RIGHT, 1, 1) if starttime == None: starttime = datetime.datetime.now() self.datetime_box = DateTimeBox(starttime) self.datetime_box.connect("changed", self._on_datetime_changed) hbox.pack_start(self.datetime_box, True, True, 0) label_start.set_mnemonic_widget(self.datetime_box) label_duration = TextFieldLabel() label_duration.set_markup_with_mnemonic(_("_Duration:")) table.add(label_duration) duration_hbox = Gtk.Box(spacing=6, hexpand=True) table.attach_next_to(duration_hbox, label_duration, Gtk.PositionType.RIGHT, 1, 1) self.duration = Gtk.SpinButton() self.duration.set_range(1, 65535) self.duration.set_increments(1, 10) self.duration.set_width_chars(3) self.duration.set_value(60) duration_hbox.pack_start(self.duration, False, True, 0) label_duration.set_mnemonic_widget(self.duration) minutes_label = TextFieldLabel(_("minutes")) duration_hbox.pack_start(minutes_label, True, True, 0) self.set_start_time(starttime) self.set_duration(duration) table.show_all()
class ControlCenterWindow(Gtk.Window): def __init__(self, model): GObject.GObject.__init__(self) self.runningnextstore = None self.scrolledrunningnext = None self.runningnextview = None self.__single_group = None self.channellists = {} self.manager = model self.manager.connect('group-added', self._on_manager_group_added) self.manager.connect('group-removed', self._on_manager_group_removed) self.connect('delete-event', Gtk.main_quit) self.connect('destroy-event', Gtk.main_quit) self.set_title(_("DVB Control Center")) self.set_default_size(800, 500) self.vbox_outer = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.vbox_outer.show() self.add(self.vbox_outer) self.toolbar = None self.vbox_left = None self.__create_menu() self.__create_toolbar() self.hbox = Gtk.Box(spacing=6) self.vbox_outer.pack_start(self.hbox, True, True, 0) self.hpaned = Gtk.Paned() self.hpaned.set_border_width(3) self.hpaned.set_position(175) self.hbox.pack_start(self.hpaned, True, True, 0) self.vbox_left = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6) self.hpaned.pack1(self.vbox_left) self.devgroupslist = Gtk.ListStore(str, int, GObject.GObject) self.devgroupslist.connect("row-inserted", self._on_devgroupslist_inserted) self.devgroupscombo = Gtk.ComboBox.new_with_model_and_entry(self.devgroupslist) cell_adapter = Gtk.CellRendererText() self.devgroupscombo.pack_start(cell_adapter, True) self.devgroupscombo.set_entry_text_column(0) self.devgroupscombo.connect("changed", self._on_devgroupscombo_changed) self.vbox_left.pack_start(self.devgroupscombo, False, True, 0) self.channelsstore = None self.channelsview = ChannelsView() self.channelsview.set_headers_visible(False) self.channelsview.get_selection().connect("changed", self._on_channel_selected) scrolledchannels = Gtk.ScrolledWindow() scrolledchannels.add(self.channelsview) scrolledchannels.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) scrolledchannels.set_shadow_type(Gtk.ShadowType.IN) self.vbox_left.pack_start(scrolledchannels, True, True, 0) self.schedulestore = None self.help_eventbox = HelpBox() self.choose_group_text = _("Choose a device group and channel on the left to view the program guide") self.create_group_text = _("No devices are configured. Please go to preferences to configure them.") self.no_events_text = _("There is currently no schedule available for this channel") self.hpaned.pack2(self.help_eventbox) self.schedulepaned = SchedulePaned() self.schedulepaned.show() self.scheduleview = self.schedulepaned.get_treeview() self.scheduleview.connect("button-press-event", self._on_event_selected) self.get_device_groups() if len(self.devgroupslist) == 0: self.help_eventbox.set_markup(self.create_group_text) else: self._select_first_group() Gtk.Window.set_default_icon_name("gnome-dvb-daemon") def __create_menu(self): ui = ''' <menubar name="MenuBar"> <menu action="Timers"> <menuitem action="EditTimers"/> <menuitem action="Recordings"/> <separator/> <menuitem action="Quit"/> </menu> <menu action="Edit"> <menuitem action="EditChannelLists"/> <separator/> <menuitem action="Preferences"/> </menu> <menu action="View"> <menuitem action="WhatsOnNow"/> <menuitem action="Refresh"/> <menuitem action="PrevDay"/> <menuitem action="NextDay"/> <separator/> <menuitem action="Channels"/> <menuitem action="Toolbar"/> </menu> <menu action="Help"> <menuitem action="About"/> </menu> </menubar>''' uimanager = Gtk.UIManager() # Add the accelerator group to the toplevel window accelgroup = uimanager.get_accel_group() self.add_accel_group(accelgroup) # Create actions actiongroup = Gtk.ActionGroup(name='Root') actiongroup.add_actions([ ('Timers', None, _('_Recording schedule')), ('Edit', None, _('_Edit')), ('View', None, _('_View')), ('Help', None, _('Help')), ]) # Add the actiongroup to the uimanager uimanager.insert_action_group(actiongroup, 0) actiongroup = Gtk.ActionGroup(name='Timers') actiongroup.add_actions([ ('EditTimers', None, _('_Manage'), '<Control>T', _('Manage recording schedule'), self._on_button_display_timers_clicked), ('Recordings', None, _('_Recordings'), '<Control>W', _('Manage recordings'), self._on_button_recordings_clicked), ('Quit', Gtk.STOCK_QUIT, _('_Quit'), None, _('Quit the Program'), Gtk.main_quit)]) uimanager.insert_action_group(actiongroup, 1) actiongroup = Gtk.ActionGroup(name='Edit') actiongroup.add_actions([ ('EditChannelLists', None, _('_Channel Lists'), None, _('Edit channel lists'), self._on_edit_channellists_clicked), ('Preferences', Gtk.STOCK_PREFERENCES, _('_Preferences'), None, _('Display preferences'), self._on_button_prefs_clicked), ]) uimanager.insert_action_group(actiongroup, 2) actiongroup = Gtk.ActionGroup(name='View') actiongroup.add_actions([ ('WhatsOnNow', None, _("_What's on now"), None, _("See what's currently on and is coming next"), self._on_whats_on_now_clicked), ('Refresh', Gtk.STOCK_REFRESH, _('_Refresh'), '<Control>R', _('Refresh program guide'), self._on_refresh_clicked), ('PrevDay', None, _('_Previous Day'), '<Alt>Left', _('Go to previous day'), self._on_button_prev_day_clicked), ('NextDay', None, _('_Next Day'), '<Alt>Right', _('Go to next day'), self._on_button_next_day_clicked), ]) actiongroup.add_toggle_actions([ ('Channels', None, _('_Channels'), None, _('View/Hide channels'), self._on_view_channels_clicked), ('Toolbar', None, _('_Toolbar'), None, _('View/Hide toolbar'), self._on_view_toolbar_clicked), ]) action = actiongroup.get_action('Toolbar') action.set_active(True) action = actiongroup.get_action('Channels') action.set_active(True) uimanager.insert_action_group(actiongroup, 3) actiongroup = Gtk.ActionGroup(name='Help') actiongroup.add_actions([ ('About', Gtk.STOCK_ABOUT, _('_About'), None, _('Display informations about the program'), self._on_about_clicked), ]) uimanager.insert_action_group(actiongroup, 4) # Add a UI description uimanager.add_ui_from_string(ui) timers_image = Gtk.Image.new_from_icon_name("appointment-soon", Gtk.IconSize.MENU) timers_image.show() self.timersitem = uimanager.get_widget('/MenuBar/Timers/EditTimers') self.timersitem.set_image(timers_image) self.timersitem.set_sensitive(False) recordings_image = Gtk.Image.new_from_icon_name("video-x-generic", Gtk.IconSize.MENU) recordings_image.show() recordings = uimanager.get_widget('/MenuBar/Timers/Recordings') recordings.set_image(recordings_image) whatson_image = Gtk.Image.new_from_stock(Gtk.STOCK_INDEX, Gtk.IconSize.MENU) whatson_image.show() self.whatons_item = uimanager.get_widget('/MenuBar/View/WhatsOnNow') self.whatons_item.set_image(whatson_image) self.whatons_item.set_sensitive(False) self.refresh_menuitem = uimanager.get_widget('/MenuBar/View/Refresh') self.refresh_menuitem.set_sensitive(False) self.prev_day_menuitem = uimanager.get_widget('/MenuBar/View/PrevDay') prev_image = Gtk.Image.new_from_stock(Gtk.STOCK_GO_BACK, Gtk.IconSize.MENU) prev_image.show() self.prev_day_menuitem.set_image(prev_image) self.prev_day_menuitem.set_sensitive(False) self.next_day_menuitem = uimanager.get_widget('/MenuBar/View/NextDay') next_image = Gtk.Image.new_from_stock(Gtk.STOCK_GO_FORWARD, Gtk.IconSize.MENU) next_image.show() self.next_day_menuitem.set_image(next_image) self.next_day_menuitem.set_sensitive(False) # Create a MenuBar menubar = uimanager.get_widget('/MenuBar') menubar.show() self.vbox_outer.pack_start(menubar, False, True, 0) def __create_toolbar(self): self.toolbar = Gtk.Toolbar() self.toolbar.show() self.vbox_outer.pack_start(self.toolbar, False, True, 0) timers_image = Gtk.Image.new_from_icon_name("appointment-soon", Gtk.IconSize.MENU) timers_image.show() self.button_display_timers = Gtk.ToolButton(icon_widget=timers_image, label=_("Recording schedule")) self.button_display_timers.set_is_important(True) self.button_display_timers.set_sensitive(False) self.button_display_timers.connect("clicked", self._on_button_display_timers_clicked) self.button_display_timers.set_tooltip_markup(_("Manage recording schedule")) self.button_display_timers.show() self.toolbar.insert(self.button_display_timers, 0) recordings_image = Gtk.Image.new_from_icon_name("video-x-generic", Gtk.IconSize.MENU) recordings_image.show() button_recordings = Gtk.ToolButton(icon_widget=recordings_image, label=_("Recordings")) button_recordings.set_is_important(True) button_recordings.connect("clicked", self._on_button_recordings_clicked) button_recordings.show() self.toolbar.insert(button_recordings, 1) whatson_image = Gtk.Image.new_from_stock(Gtk.STOCK_INDEX, Gtk.IconSize.LARGE_TOOLBAR) whatson_image.show() self.button_whatson = Gtk.ToolButton(icon_widget=whatson_image, label=_("What's on now")) self.button_whatson.set_is_important(True) self.button_whatson.set_sensitive(False) self.button_whatson.connect("clicked", self._on_whats_on_now_clicked) self.button_whatson.show() self.toolbar.insert(self.button_whatson, 2) sep = Gtk.SeparatorToolItem() sep.show() self.toolbar.insert(sep, 3) self.refresh_button = Gtk.ToolButton.new_from_stock(Gtk.STOCK_REFRESH) self.refresh_button.connect("clicked", self._on_refresh_clicked) self.refresh_button.set_tooltip_markup(_("Refresh program guide")) self.refresh_button.show() self.toolbar.insert(self.refresh_button, 4) prev_image = Gtk.Image.new_from_stock(Gtk.STOCK_GO_BACK, Gtk.IconSize.LARGE_TOOLBAR) prev_image.show() self.button_prev_day = Gtk.ToolButton(icon_widget=prev_image, label=_("Previous Day")) self.button_prev_day.connect("clicked", self._on_button_prev_day_clicked) self.button_prev_day.set_tooltip_markup(_("Go to previous day")) self.button_prev_day.set_sensitive(False) self.button_prev_day.show() self.toolbar.insert(self.button_prev_day, 5) next_image = Gtk.Image.new_from_stock(Gtk.STOCK_GO_FORWARD, Gtk.IconSize.LARGE_TOOLBAR) next_image.show() self.button_next_day = Gtk.ToolButton(icon_widget=next_image, label=_("Next Day")) self.button_next_day.connect("clicked", self._on_button_next_day_clicked) self.button_next_day.set_tooltip_markup(_("Go to next day")) self.button_next_day.set_sensitive(False) self.button_next_day.show() self.toolbar.insert(self.button_next_day, 6) def get_device_groups(self): def append_groups(groups): for group in groups: self._append_group(group) self.check_single_group_mode() self.manager.get_registered_device_groups(result_handler=append_groups) def check_single_group_mode(self): val = len(self.devgroupslist) == 1 if val: aiter = self.devgroupslist.get_iter_first() self.__single_group = self.devgroupslist[aiter][2] self.devgroupscombo.hide() else: self.__single_group = None self.devgroupscombo.show() def _select_first_group(self): self.devgroupscombo.set_active(0) self.channelsview.grab_focus() def _append_group(self, group): self.devgroupslist.append([group["name"], group["id"], group]) self.channellists[group["id"]] = group.get_channel_list() def _remove_group(self, group_id): aiter = None for row in self.devgroupslist: if row[1] == group_id: aiter = row.iter if aiter != None: if self._get_selected_group()["id"] == group_id: # Select no group self.devgroupscombo.set_active(-1) self.devgroupslist.remove(aiter) del self.channellists[group_id] def _reset_ui(self): self.channelsstore = None self.channelsview.set_model(None) if len(self.devgroupslist) == 0: text = self.create_group_text else: text = self.choose_group_text self._display_help_message(text) self._set_timers_sensitive(False) def _reset_schedule_view(self): self.schedulestore = None self.scheduleview.set_model(None) self._display_running_next() def _on_manager_group_added(self, manager, group_id): group = self.manager.get_device_group(group_id) if group != None: self._append_group(group) self.check_single_group_mode() def _on_manager_group_removed(self, manager, group_id): self._remove_group(group_id) self.check_single_group_mode() self._select_first_group() def _get_selected_group(self): if self.__single_group != None: return self.__single_group aiter = self.devgroupscombo.get_active_iter() if aiter == None: return None else: return self.devgroupslist[aiter][2] def _get_selected_channel_sid(self): model, aiter = self.channelsview.get_selection().get_selected() if aiter != None: sid = model[aiter][model.COL_SID] return sid else: return None def _on_devgroupscombo_changed(self, combo): group = self._get_selected_group() if group != None: self._set_timers_sensitive(True) self._set_whatson_sensitive(True) self.channelsstore = ChannelsStore(group) self.channelsview.set_model(self.channelsstore) self._reset_schedule_view() else: self._reset_ui() def _on_devgroupslist_inserted(self, model, path, aiter): if len(model) == 1: # Delay the call otherwise we get DBus errors GLib.timeout_add(100, self._select_first_group) def _on_channel_selected(self, treeselection): model, aiter = treeselection.get_selected() child = self.hpaned.get_child2() if aiter != None: sid = model[aiter][model.COL_SID] group = self._get_selected_group() self.schedulestore = ScheduleStore(group, sid) self.schedulestore.connect("loading-finished", self._on_schedule_loading_finished) self.scheduleview.set_model(self.schedulestore) # Display schedule if it isn't already displayed if child != self.schedulepaned: self.hpaned.remove(child) self.hpaned.pack2(self.schedulepaned) self._set_previous_day_sensitive(True) self._set_next_day_sensitive(True) self._set_refresh_sensitive(True) else: # Display running/next if it isn't already displayed if child != self.scrolledrunningnext: self._display_running_next() def _on_schedule_loading_finished(self, schedulestore): if len(self.schedulestore) == 0: self._display_help_message(self.no_events_text) def _display_help_message(self, text): child = self.hpaned.get_child2() self.hpaned.remove(child) self.hpaned.pack2(self.help_eventbox) self._set_previous_day_sensitive(False) self._set_next_day_sensitive(False) self._set_refresh_sensitive(False) self.help_eventbox.set_markup(text) def _display_running_next(self): group = self._get_selected_group() self.runningnextstore = RunningNextStore(group) self.scrolledrunningnext = Gtk.ScrolledWindow() self.scrolledrunningnext.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) self.scrolledrunningnext.set_shadow_type(Gtk.ShadowType.IN) self.scrolledrunningnext.show() self.runningnextview = RunningNextView(self.runningnextstore) self.runningnextview.show() self.scrolledrunningnext.add(self.runningnextview) child = self.hpaned.get_child2() self.hpaned.remove(child) self.hpaned.pack2(self.scrolledrunningnext) self._set_previous_day_sensitive(False) self._set_next_day_sensitive(False) self._set_refresh_sensitive(False) def _set_next_day_sensitive(self, val): self.button_next_day.set_sensitive(val) self.next_day_menuitem.set_sensitive(val) def _set_previous_day_sensitive(self, val): self.button_prev_day.set_sensitive(val) self.prev_day_menuitem.set_sensitive(val) def _set_timers_sensitive(self, val): self.button_display_timers.set_sensitive(val) self.timersitem.set_sensitive(val) def _set_refresh_sensitive(self, val): self.refresh_button.set_sensitive(val) self.refresh_menuitem.set_sensitive(val) def _set_whatson_sensitive(self, val): self.whatons_item.set_sensitive(val) self.button_whatson.set_sensitive(val) def _on_event_selected(self, treeview, event): if event.type == getattr(Gdk.EventType, "2BUTTON_PRESS"): model, aiter = treeview.get_selection().get_selected() if aiter != None: dialog = Gtk.MessageDialog(parent=self, flags=Gtk.DialogFlags.MODAL|Gtk.DialogFlags.DESTROY_WITH_PARENT, type=Gtk.MessageType.QUESTION, buttons=Gtk.ButtonsType.YES_NO) dialog.set_markup ( "<big><span weight=\"bold\">%s</span></big>" % _("Schedule recording for the selected event?")) success = True if dialog.run() == Gtk.ResponseType.YES: event_id = model[aiter][model.COL_EVENT_ID] group = self._get_selected_group() channel_sid = self._get_selected_channel_sid() recorder = group.get_recorder() rec_id, success = recorder.add_timer_for_epg_event(event_id, channel_sid) dialog.destroy() if not success: dialog = TimerFailureDialog(self) dialog.run() dialog.destroy() def _on_button_display_timers_clicked(self, button, user_data=None): group = self._get_selected_group() if group != None: edit = EditTimersDialog(group, self) edit.run() edit.destroy() def _on_whats_on_now_clicked(self, button, user_data=None): self._reset_schedule_view() def _on_refresh_clicked(self, button, user_data=None): self.schedulestore.reload_all() def _on_button_prev_day_clicked(self, button, user_data=None): if self.schedulestore != None: model, aiter = self.scheduleview.get_selection().get_selected() if aiter == None: path, col, x, y = self.scheduleview.get_path_at_pos(1, 1) aiter = model.get_iter(path) day_iter = self.schedulestore.get_previous_day_iter(aiter) if day_iter == None: self._set_previous_day_sensitive(False) else: self._set_next_day_sensitive(True) day_path = model.get_path(day_iter) self.scheduleview.scroll_to_cell(day_path, use_align=True) self.scheduleview.set_cursor(day_path, None, False) def _on_button_next_day_clicked(self, button, user_data=None): if self.schedulestore != None: model, aiter = self.scheduleview.get_selection().get_selected() if aiter == None: path, col, x, y = self.scheduleview.get_path_at_pos(1, 1) aiter = model.get_iter(path) day_iter = self.schedulestore.get_next_day_iter(aiter) if day_iter == None: self._set_next_day_sensitive(False) else: self._set_previous_day_sensitive(True) day_path = model.get_path(day_iter) self.scheduleview.scroll_to_cell(day_path, use_align=True) self.scheduleview.set_cursor(day_path, None, False) def _on_button_prefs_clicked(self, button, user_data=None): prefs = Preferences(self.manager, self) prefs.show() def _on_button_recordings_clicked(self, button, user_data=None): dialog = RecordingsDialog(self) dialog.run() dialog.destroy() def _on_view_channels_clicked(self, action, user_data=None): if self.vbox_left: if action.get_active(): self.vbox_left.show() else: self.vbox_left.hide() def _on_view_toolbar_clicked(self, action, user_data=None): if self.toolbar: if action.get_active(): self.toolbar.show() else: self.toolbar.hide() def _on_about_clicked(self, action, user_data=None): about = Gtk.AboutDialog() about.set_transient_for(self) #translators: These appear in the About dialog, usual format applies. about.set_translator_credits( _("translator-credits") ) for prop, val in list(gnomedvb.INFOS.items()): about.set_property(prop, val) about.set_screen(self.get_screen()) about.run() about.destroy() def _on_edit_channellists_clicked(self, action, user_data=None): dialog = ChannelListEditorDialog(self.manager, parent=self) dialog.run() dialog.destroy()
def __init__(self, model): GObject.GObject.__init__(self) self.runningnextstore = None self.scrolledrunningnext = None self.runningnextview = None self.__single_group = None self.channellists = {} self.manager = model self.manager.connect('group-added', self._on_manager_group_added) self.manager.connect('group-removed', self._on_manager_group_removed) self.connect('delete-event', Gtk.main_quit) self.connect('destroy-event', Gtk.main_quit) self.set_title(_("DVB Control Center")) self.set_default_size(800, 500) self.vbox_outer = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.vbox_outer.show() self.add(self.vbox_outer) self.toolbar = None self.vbox_left = None self.__create_menu() self.__create_toolbar() self.hbox = Gtk.Box(spacing=6) self.vbox_outer.pack_start(self.hbox, True, True, 0) self.hpaned = Gtk.Paned() self.hpaned.set_border_width(3) self.hpaned.set_position(175) self.hbox.pack_start(self.hpaned, True, True, 0) self.vbox_left = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6) self.hpaned.pack1(self.vbox_left) self.devgroupslist = Gtk.ListStore(str, int, GObject.GObject) self.devgroupslist.connect("row-inserted", self._on_devgroupslist_inserted) self.devgroupscombo = Gtk.ComboBox.new_with_model_and_entry(self.devgroupslist) cell_adapter = Gtk.CellRendererText() self.devgroupscombo.pack_start(cell_adapter, True) self.devgroupscombo.set_entry_text_column(0) self.devgroupscombo.connect("changed", self._on_devgroupscombo_changed) self.vbox_left.pack_start(self.devgroupscombo, False, True, 0) self.channelsstore = None self.channelsview = ChannelsView() self.channelsview.set_headers_visible(False) self.channelsview.get_selection().connect("changed", self._on_channel_selected) scrolledchannels = Gtk.ScrolledWindow() scrolledchannels.add(self.channelsview) scrolledchannels.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) scrolledchannels.set_shadow_type(Gtk.ShadowType.IN) self.vbox_left.pack_start(scrolledchannels, True, True, 0) self.schedulestore = None self.help_eventbox = HelpBox() self.choose_group_text = _("Choose a device group and channel on the left to view the program guide") self.create_group_text = _("No devices are configured. Please go to preferences to configure them.") self.no_events_text = _("There is currently no schedule available for this channel") self.hpaned.pack2(self.help_eventbox) self.schedulepaned = SchedulePaned() self.schedulepaned.show() self.scheduleview = self.schedulepaned.get_treeview() self.scheduleview.connect("button-press-event", self._on_event_selected) self.get_device_groups() if len(self.devgroupslist) == 0: self.help_eventbox.set_markup(self.create_group_text) else: self._select_first_group() Gtk.Window.set_default_icon_name("gnome-dvb-daemon")
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)
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 __init__(self, model): GObject.GObject.__init__(self) self.runningnextstore = None self.scrolledrunningnext = None self.runningnextview = None self.__single_group = None self.channellists = {} self.manager = model self.manager.connect('group-added', self._on_manager_group_added) self.manager.connect('group-removed', self._on_manager_group_removed) self.connect('delete-event', Gtk.main_quit) self.connect('destroy-event', Gtk.main_quit) self.set_title(_("DVB Control Center")) self.set_default_size(800, 500) self.vbox_outer = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.vbox_outer.show() self.add(self.vbox_outer) self.toolbar = None self.vbox_left = None self.__create_menu() self.__create_toolbar() self.hbox = Gtk.Box(spacing=6) self.vbox_outer.pack_start(self.hbox, True, True, 0) self.hpaned = Gtk.Paned() self.hpaned.set_border_width(3) self.hpaned.set_position(175) self.hbox.pack_start(self.hpaned, True, True, 0) self.vbox_left = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6) self.hpaned.pack1(self.vbox_left) self.devgroupslist = Gtk.ListStore(str, int, GObject.GObject) self.devgroupslist.connect("row-inserted", self._on_devgroupslist_inserted) self.devgroupscombo = Gtk.ComboBox.new_with_model_and_entry( self.devgroupslist) cell_adapter = Gtk.CellRendererText() self.devgroupscombo.pack_start(cell_adapter, True) self.devgroupscombo.set_entry_text_column(0) self.devgroupscombo.connect("changed", self._on_devgroupscombo_changed) self.vbox_left.pack_start(self.devgroupscombo, False, True, 0) self.channelsstore = None self.channelsview = ChannelsView() self.channelsview.set_headers_visible(False) self.channelsview.get_selection().connect("changed", self._on_channel_selected) scrolledchannels = Gtk.ScrolledWindow() scrolledchannels.add(self.channelsview) scrolledchannels.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) scrolledchannels.set_shadow_type(Gtk.ShadowType.IN) self.vbox_left.pack_start(scrolledchannels, True, True, 0) self.schedulestore = None self.help_eventbox = HelpBox() self.choose_group_text = _( "Choose a device group and channel on the left to view the program guide" ) self.create_group_text = _( "No devices are configured. Please go to preferences to configure them." ) self.no_events_text = _( "There is currently no schedule available for this channel") self.hpaned.pack2(self.help_eventbox) self.schedulepaned = SchedulePaned() self.schedulepaned.show() self.scheduleview = self.schedulepaned.get_treeview() self.scheduleview.connect("button-press-event", self._on_event_selected) self.get_device_groups() if len(self.devgroupslist) == 0: self.help_eventbox.set_markup(self.create_group_text) else: self._select_first_group() Gtk.Window.set_default_icon_name("gnome-dvb-daemon")
class ControlCenterWindow(Gtk.Window): def __init__(self, model): GObject.GObject.__init__(self) self.runningnextstore = None self.scrolledrunningnext = None self.runningnextview = None self.__single_group = None self.channellists = {} self.manager = model self.manager.connect('group-added', self._on_manager_group_added) self.manager.connect('group-removed', self._on_manager_group_removed) self.connect('delete-event', Gtk.main_quit) self.connect('destroy-event', Gtk.main_quit) self.set_title(_("DVB Control Center")) self.set_default_size(800, 500) self.vbox_outer = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.vbox_outer.show() self.add(self.vbox_outer) self.toolbar = None self.vbox_left = None self.__create_menu() self.__create_toolbar() self.hbox = Gtk.Box(spacing=6) self.vbox_outer.pack_start(self.hbox, True, True, 0) self.hpaned = Gtk.Paned() self.hpaned.set_border_width(3) self.hpaned.set_position(175) self.hbox.pack_start(self.hpaned, True, True, 0) self.vbox_left = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6) self.hpaned.pack1(self.vbox_left) self.devgroupslist = Gtk.ListStore(str, int, GObject.GObject) self.devgroupslist.connect("row-inserted", self._on_devgroupslist_inserted) self.devgroupscombo = Gtk.ComboBox.new_with_model_and_entry( self.devgroupslist) cell_adapter = Gtk.CellRendererText() self.devgroupscombo.pack_start(cell_adapter, True) self.devgroupscombo.set_entry_text_column(0) self.devgroupscombo.connect("changed", self._on_devgroupscombo_changed) self.vbox_left.pack_start(self.devgroupscombo, False, True, 0) self.channelsstore = None self.channelsview = ChannelsView() self.channelsview.set_headers_visible(False) self.channelsview.get_selection().connect("changed", self._on_channel_selected) scrolledchannels = Gtk.ScrolledWindow() scrolledchannels.add(self.channelsview) scrolledchannels.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) scrolledchannels.set_shadow_type(Gtk.ShadowType.IN) self.vbox_left.pack_start(scrolledchannels, True, True, 0) self.schedulestore = None self.help_eventbox = HelpBox() self.choose_group_text = _( "Choose a device group and channel on the left to view the program guide" ) self.create_group_text = _( "No devices are configured. Please go to preferences to configure them." ) self.no_events_text = _( "There is currently no schedule available for this channel") self.hpaned.pack2(self.help_eventbox) self.schedulepaned = SchedulePaned() self.schedulepaned.show() self.scheduleview = self.schedulepaned.get_treeview() self.scheduleview.connect("button-press-event", self._on_event_selected) self.get_device_groups() if len(self.devgroupslist) == 0: self.help_eventbox.set_markup(self.create_group_text) else: self._select_first_group() Gtk.Window.set_default_icon_name("gnome-dvb-daemon") def __create_menu(self): ui = ''' <menubar name="MenuBar"> <menu action="Timers"> <menuitem action="EditTimers"/> <menuitem action="Recordings"/> <separator/> <menuitem action="Quit"/> </menu> <menu action="Edit"> <menuitem action="EditChannelLists"/> <separator/> <menuitem action="Preferences"/> </menu> <menu action="View"> <menuitem action="WhatsOnNow"/> <menuitem action="Refresh"/> <menuitem action="PrevDay"/> <menuitem action="NextDay"/> <separator/> <menuitem action="Channels"/> <menuitem action="Toolbar"/> </menu> <menu action="Help"> <menuitem action="About"/> </menu> </menubar>''' uimanager = Gtk.UIManager() # Add the accelerator group to the toplevel window accelgroup = uimanager.get_accel_group() self.add_accel_group(accelgroup) # Create actions actiongroup = Gtk.ActionGroup(name='Root') actiongroup.add_actions([ ('Timers', None, _('_Recording schedule')), ('Edit', None, _('_Edit')), ('View', None, _('_View')), ('Help', None, _('Help')), ]) # Add the actiongroup to the uimanager uimanager.insert_action_group(actiongroup, 0) actiongroup = Gtk.ActionGroup(name='Timers') actiongroup.add_actions([ ('EditTimers', None, _('_Manage'), '<Control>T', _('Manage recording schedule'), self._on_button_display_timers_clicked), ('Recordings', None, _('_Recordings'), '<Control>W', _('Manage recordings'), self._on_button_recordings_clicked), ('Quit', Gtk.STOCK_QUIT, _('_Quit'), None, _('Quit the Program'), Gtk.main_quit) ]) uimanager.insert_action_group(actiongroup, 1) actiongroup = Gtk.ActionGroup(name='Edit') actiongroup.add_actions([ ('EditChannelLists', None, _('_Channel Lists'), None, _('Edit channel lists'), self._on_edit_channellists_clicked), ('Preferences', Gtk.STOCK_PREFERENCES, _('_Preferences'), None, _('Display preferences'), self._on_button_prefs_clicked), ]) uimanager.insert_action_group(actiongroup, 2) actiongroup = Gtk.ActionGroup(name='View') actiongroup.add_actions([ ('WhatsOnNow', None, _("_What's on now"), None, _("See what's currently on and is coming next"), self._on_whats_on_now_clicked), ('Refresh', Gtk.STOCK_REFRESH, _('_Refresh'), '<Control>R', _('Refresh program guide'), self._on_refresh_clicked), ('PrevDay', None, _('_Previous Day'), '<Alt>Left', _('Go to previous day'), self._on_button_prev_day_clicked), ('NextDay', None, _('_Next Day'), '<Alt>Right', _('Go to next day'), self._on_button_next_day_clicked), ]) actiongroup.add_toggle_actions([ ('Channels', None, _('_Channels'), None, _('View/Hide channels'), self._on_view_channels_clicked), ('Toolbar', None, _('_Toolbar'), None, _('View/Hide toolbar'), self._on_view_toolbar_clicked), ]) action = actiongroup.get_action('Toolbar') action.set_active(True) action = actiongroup.get_action('Channels') action.set_active(True) uimanager.insert_action_group(actiongroup, 3) actiongroup = Gtk.ActionGroup(name='Help') actiongroup.add_actions([ ('About', Gtk.STOCK_ABOUT, _('_About'), None, _('Display informations about the program'), self._on_about_clicked), ]) uimanager.insert_action_group(actiongroup, 4) # Add a UI description uimanager.add_ui_from_string(ui) timers_image = Gtk.Image.new_from_icon_name("appointment-soon", Gtk.IconSize.MENU) timers_image.show() self.timersitem = uimanager.get_widget('/MenuBar/Timers/EditTimers') self.timersitem.set_image(timers_image) self.timersitem.set_sensitive(False) recordings_image = Gtk.Image.new_from_icon_name( "video-x-generic", Gtk.IconSize.MENU) recordings_image.show() recordings = uimanager.get_widget('/MenuBar/Timers/Recordings') recordings.set_image(recordings_image) whatson_image = Gtk.Image.new_from_stock(Gtk.STOCK_INDEX, Gtk.IconSize.MENU) whatson_image.show() self.whatons_item = uimanager.get_widget('/MenuBar/View/WhatsOnNow') self.whatons_item.set_image(whatson_image) self.whatons_item.set_sensitive(False) self.refresh_menuitem = uimanager.get_widget('/MenuBar/View/Refresh') self.refresh_menuitem.set_sensitive(False) self.prev_day_menuitem = uimanager.get_widget('/MenuBar/View/PrevDay') prev_image = Gtk.Image.new_from_stock(Gtk.STOCK_GO_BACK, Gtk.IconSize.MENU) prev_image.show() self.prev_day_menuitem.set_image(prev_image) self.prev_day_menuitem.set_sensitive(False) self.next_day_menuitem = uimanager.get_widget('/MenuBar/View/NextDay') next_image = Gtk.Image.new_from_stock(Gtk.STOCK_GO_FORWARD, Gtk.IconSize.MENU) next_image.show() self.next_day_menuitem.set_image(next_image) self.next_day_menuitem.set_sensitive(False) # Create a MenuBar menubar = uimanager.get_widget('/MenuBar') menubar.show() self.vbox_outer.pack_start(menubar, False, True, 0) def __create_toolbar(self): self.toolbar = Gtk.Toolbar() self.toolbar.show() self.vbox_outer.pack_start(self.toolbar, False, True, 0) timers_image = Gtk.Image.new_from_icon_name("appointment-soon", Gtk.IconSize.MENU) timers_image.show() self.button_display_timers = Gtk.ToolButton( icon_widget=timers_image, label=_("Recording schedule")) self.button_display_timers.set_is_important(True) self.button_display_timers.set_sensitive(False) self.button_display_timers.connect( "clicked", self._on_button_display_timers_clicked) self.button_display_timers.set_tooltip_markup( _("Manage recording schedule")) self.button_display_timers.show() self.toolbar.insert(self.button_display_timers, 0) recordings_image = Gtk.Image.new_from_icon_name( "video-x-generic", Gtk.IconSize.MENU) recordings_image.show() button_recordings = Gtk.ToolButton(icon_widget=recordings_image, label=_("Recordings")) button_recordings.set_is_important(True) button_recordings.connect("clicked", self._on_button_recordings_clicked) button_recordings.show() self.toolbar.insert(button_recordings, 1) whatson_image = Gtk.Image.new_from_stock(Gtk.STOCK_INDEX, Gtk.IconSize.LARGE_TOOLBAR) whatson_image.show() self.button_whatson = Gtk.ToolButton(icon_widget=whatson_image, label=_("What's on now")) self.button_whatson.set_is_important(True) self.button_whatson.set_sensitive(False) self.button_whatson.connect("clicked", self._on_whats_on_now_clicked) self.button_whatson.show() self.toolbar.insert(self.button_whatson, 2) sep = Gtk.SeparatorToolItem() sep.show() self.toolbar.insert(sep, 3) self.refresh_button = Gtk.ToolButton.new_from_stock(Gtk.STOCK_REFRESH) self.refresh_button.connect("clicked", self._on_refresh_clicked) self.refresh_button.set_tooltip_markup(_("Refresh program guide")) self.refresh_button.show() self.toolbar.insert(self.refresh_button, 4) prev_image = Gtk.Image.new_from_stock(Gtk.STOCK_GO_BACK, Gtk.IconSize.LARGE_TOOLBAR) prev_image.show() self.button_prev_day = Gtk.ToolButton(icon_widget=prev_image, label=_("Previous Day")) self.button_prev_day.connect("clicked", self._on_button_prev_day_clicked) self.button_prev_day.set_tooltip_markup(_("Go to previous day")) self.button_prev_day.set_sensitive(False) self.button_prev_day.show() self.toolbar.insert(self.button_prev_day, 5) next_image = Gtk.Image.new_from_stock(Gtk.STOCK_GO_FORWARD, Gtk.IconSize.LARGE_TOOLBAR) next_image.show() self.button_next_day = Gtk.ToolButton(icon_widget=next_image, label=_("Next Day")) self.button_next_day.connect("clicked", self._on_button_next_day_clicked) self.button_next_day.set_tooltip_markup(_("Go to next day")) self.button_next_day.set_sensitive(False) self.button_next_day.show() self.toolbar.insert(self.button_next_day, 6) def get_device_groups(self): def append_groups(groups): for group in groups: self._append_group(group) self.check_single_group_mode() self.manager.get_registered_device_groups(result_handler=append_groups) def check_single_group_mode(self): val = len(self.devgroupslist) == 1 if val: aiter = self.devgroupslist.get_iter_first() self.__single_group = self.devgroupslist[aiter][2] self.devgroupscombo.hide() else: self.__single_group = None self.devgroupscombo.show() def _select_first_group(self): self.devgroupscombo.set_active(0) self.channelsview.grab_focus() def _append_group(self, group): self.devgroupslist.append([group["name"], group["id"], group]) self.channellists[group["id"]] = group.get_channel_list() def _remove_group(self, group_id): aiter = None for row in self.devgroupslist: if row[1] == group_id: aiter = row.iter if aiter != None: if self._get_selected_group()["id"] == group_id: # Select no group self.devgroupscombo.set_active(-1) self.devgroupslist.remove(aiter) del self.channellists[group_id] def _reset_ui(self): self.channelsstore = None self.channelsview.set_model(None) if len(self.devgroupslist) == 0: text = self.create_group_text else: text = self.choose_group_text self._display_help_message(text) self._set_timers_sensitive(False) def _reset_schedule_view(self): self.schedulestore = None self.scheduleview.set_model(None) self._display_running_next() def _on_manager_group_added(self, manager, group_id): group = self.manager.get_device_group(group_id) if group != None: self._append_group(group) self.check_single_group_mode() def _on_manager_group_removed(self, manager, group_id): self._remove_group(group_id) self.check_single_group_mode() self._select_first_group() def _get_selected_group(self): if self.__single_group != None: return self.__single_group aiter = self.devgroupscombo.get_active_iter() if aiter == None: return None else: return self.devgroupslist[aiter][2] def _get_selected_channel_sid(self): model, aiter = self.channelsview.get_selection().get_selected() if aiter != None: sid = model[aiter][model.COL_SID] return sid else: return None def _on_devgroupscombo_changed(self, combo): group = self._get_selected_group() if group != None: self._set_timers_sensitive(True) self._set_whatson_sensitive(True) self.channelsstore = ChannelsStore(group) self.channelsview.set_model(self.channelsstore) self._reset_schedule_view() else: self._reset_ui() def _on_devgroupslist_inserted(self, model, path, aiter): if len(model) == 1: # Delay the call otherwise we get DBus errors GLib.timeout_add(100, self._select_first_group) def _on_channel_selected(self, treeselection): model, aiter = treeselection.get_selected() child = self.hpaned.get_child2() if aiter != None: sid = model[aiter][model.COL_SID] group = self._get_selected_group() self.schedulestore = ScheduleStore(group, sid) self.schedulestore.connect("loading-finished", self._on_schedule_loading_finished) self.scheduleview.set_model(self.schedulestore) # Display schedule if it isn't already displayed if child != self.schedulepaned: self.hpaned.remove(child) self.hpaned.pack2(self.schedulepaned) self._set_previous_day_sensitive(True) self._set_next_day_sensitive(True) self._set_refresh_sensitive(True) else: # Display running/next if it isn't already displayed if child != self.scrolledrunningnext: self._display_running_next() def _on_schedule_loading_finished(self, schedulestore): if len(self.schedulestore) == 0: self._display_help_message(self.no_events_text) def _display_help_message(self, text): child = self.hpaned.get_child2() self.hpaned.remove(child) self.hpaned.pack2(self.help_eventbox) self._set_previous_day_sensitive(False) self._set_next_day_sensitive(False) self._set_refresh_sensitive(False) self.help_eventbox.set_markup(text) def _display_running_next(self): group = self._get_selected_group() self.runningnextstore = RunningNextStore(group) self.scrolledrunningnext = Gtk.ScrolledWindow() self.scrolledrunningnext.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) self.scrolledrunningnext.set_shadow_type(Gtk.ShadowType.IN) self.scrolledrunningnext.show() self.runningnextview = RunningNextView(self.runningnextstore) self.runningnextview.show() self.scrolledrunningnext.add(self.runningnextview) child = self.hpaned.get_child2() self.hpaned.remove(child) self.hpaned.pack2(self.scrolledrunningnext) self._set_previous_day_sensitive(False) self._set_next_day_sensitive(False) self._set_refresh_sensitive(False) def _set_next_day_sensitive(self, val): self.button_next_day.set_sensitive(val) self.next_day_menuitem.set_sensitive(val) def _set_previous_day_sensitive(self, val): self.button_prev_day.set_sensitive(val) self.prev_day_menuitem.set_sensitive(val) def _set_timers_sensitive(self, val): self.button_display_timers.set_sensitive(val) self.timersitem.set_sensitive(val) def _set_refresh_sensitive(self, val): self.refresh_button.set_sensitive(val) self.refresh_menuitem.set_sensitive(val) def _set_whatson_sensitive(self, val): self.whatons_item.set_sensitive(val) self.button_whatson.set_sensitive(val) def _on_event_selected(self, treeview, event): if event.type == getattr(Gdk.EventType, "2BUTTON_PRESS"): model, aiter = treeview.get_selection().get_selected() if aiter != None: dialog = Gtk.MessageDialog( parent=self, flags=Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, type=Gtk.MessageType.QUESTION, buttons=Gtk.ButtonsType.YES_NO) dialog.set_markup( "<big><span weight=\"bold\">%s</span></big>" % _("Schedule recording for the selected event?")) success = True if dialog.run() == Gtk.ResponseType.YES: event_id = model[aiter][model.COL_EVENT_ID] group = self._get_selected_group() channel_sid = self._get_selected_channel_sid() recorder = group.get_recorder() rec_id, success = recorder.add_timer_for_epg_event( event_id, channel_sid) dialog.destroy() if not success: dialog = TimerFailureDialog(self) dialog.run() dialog.destroy() def _on_button_display_timers_clicked(self, button, user_data=None): group = self._get_selected_group() if group != None: edit = EditTimersDialog(group, self) edit.run() edit.destroy() def _on_whats_on_now_clicked(self, button, user_data=None): self._reset_schedule_view() def _on_refresh_clicked(self, button, user_data=None): self.schedulestore.reload_all() def _on_button_prev_day_clicked(self, button, user_data=None): if self.schedulestore != None: model, aiter = self.scheduleview.get_selection().get_selected() if aiter == None: path, col, x, y = self.scheduleview.get_path_at_pos(1, 1) aiter = model.get_iter(path) day_iter = self.schedulestore.get_previous_day_iter(aiter) if day_iter == None: self._set_previous_day_sensitive(False) else: self._set_next_day_sensitive(True) day_path = model.get_path(day_iter) self.scheduleview.scroll_to_cell(day_path, use_align=True) self.scheduleview.set_cursor(day_path, None, False) def _on_button_next_day_clicked(self, button, user_data=None): if self.schedulestore != None: model, aiter = self.scheduleview.get_selection().get_selected() if aiter == None: path, col, x, y = self.scheduleview.get_path_at_pos(1, 1) aiter = model.get_iter(path) day_iter = self.schedulestore.get_next_day_iter(aiter) if day_iter == None: self._set_next_day_sensitive(False) else: self._set_previous_day_sensitive(True) day_path = model.get_path(day_iter) self.scheduleview.scroll_to_cell(day_path, use_align=True) self.scheduleview.set_cursor(day_path, None, False) def _on_button_prefs_clicked(self, button, user_data=None): prefs = Preferences(self.manager, self) prefs.show() def _on_button_recordings_clicked(self, button, user_data=None): dialog = RecordingsDialog(self) dialog.run() dialog.destroy() def _on_view_channels_clicked(self, action, user_data=None): if self.vbox_left: if action.get_active(): self.vbox_left.show() else: self.vbox_left.hide() def _on_view_toolbar_clicked(self, action, user_data=None): if self.toolbar: if action.get_active(): self.toolbar.show() else: self.toolbar.hide() def _on_about_clicked(self, action, user_data=None): about = Gtk.AboutDialog() about.set_transient_for(self) #translators: These appear in the About dialog, usual format applies. about.set_translator_credits(_("translator-credits")) for prop, val in list(gnomedvb.INFOS.items()): about.set_property(prop, val) about.set_screen(self.get_screen()) about.run() about.destroy() def _on_edit_channellists_clicked(self, action, user_data=None): dialog = ChannelListEditorDialog(self.manager, parent=self) dialog.run() dialog.destroy()
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()
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)