class Window(Gtk.ApplicationWindow): def __init__(self, app): Gtk.ApplicationWindow.__init__(self, application=app, title=_("Music")) self.connect('focus-in-event', self._windows_focus_cb) settings = Gio.Settings('org.gnome.Music') self.add_action(settings.create_action('repeat')) self.set_size_request(887, 640) self._setup_view() self.proxy = Gio.DBusProxy.new_sync(Gio.bus_get_sync(Gio.BusType.SESSION, None), Gio.DBusProxyFlags.NONE, None, 'org.gnome.SettingsDaemon', '/org/gnome/SettingsDaemon/MediaKeys', 'org.gnome.SettingsDaemon.MediaKeys', None) self._grab_media_player_keys() self.proxy.connect('g-signal', self._handle_media_keys) def _grab_media_player_keys(self): self.proxy.call_sync('GrabMediaPlayerKeys', GLib.Variant('(su)', ('Music', 0)), Gio.DBusCallFlags.NONE, -1, None) def _windows_focus_cb(self, window, event): self._grab_media_player_keys() def _handle_media_keys(self, proxy, sender, signal, parameters): if signal != 'MediaPlayerKeyPressed': print('Received an unexpected signal \'%s\' from media player'.format(signal)) return response = parameters.get_child_value(1).get_string() if 'Play' in response: self.player.play_pause() elif 'Stop' in response: self.player.Stop() elif 'Next' in response: self.player.play_next() elif 'Previous' in response: self.player.play_previous() def _setup_view(self): self._box = Gtk.VBox() self.player = Player() self.selection_toolbar = SelectionToolbar() self.toolbar = Toolbar() self.views = [] self._stack = Stack( transition_type=StackTransitionType.CROSSFADE, transition_duration=100, visible=True) if Gtk.get_minor_version() > 8: self.set_titlebar(self.toolbar.header_bar) else: self._box.pack_start(self.toolbar.header_bar, False, False, 0) self.set_hide_titlebar_when_maximized(True) self._box.pack_start(self.toolbar.searchbar, False, False, 0) self._box.pack_start(self._stack, True, True, 0) self._box.pack_start(self.player.eventBox, False, False, 0) self._box.pack_start(self.selection_toolbar.eventbox, False, False, 0) self.add(self._box) count = 1 cursor = tracker.query(Query.SONGS_COUNT, None) if cursor is not None and cursor.next(None): count = cursor.get_integer(0) if count > 0: self.views.append(Views.Albums(self.toolbar, self.selection_toolbar, self.player)) self.views.append(Views.Artists(self.toolbar, self.selection_toolbar, self.player)) self.views.append(Views.Songs(self.toolbar, self.selection_toolbar, self.player)) #self.views.append(Views.Playlist(self.toolbar, self.selection_toolbar, self.player)) for i in self.views: self._stack.add_titled(i, i.title, i.title) self.toolbar.set_stack(self._stack) self.toolbar.searchbar.show() self._on_notify_model_id = self._stack.connect('notify::visible-child', self._on_notify_mode) self.connect('destroy', self._notify_mode_disconnect) self.connect('key_press_event', self._on_key_press) self.views[0].populate() #To revert to the No Music View when no songs are found else: self.views.append(Views.Empty(self.toolbar, self.player)) self._stack.add_titled(self.views[0], _("Empty"), _("Empty")) self.toolbar._search_button.connect('toggled', self._on_search_toggled) self.toolbar.set_state(ToolbarState.ALBUMS) self.toolbar.header_bar.show() self.player.eventBox.show_all() self._box.show() self.show() def _on_key_press(self, widget, event): modifiers = Gtk.accelerator_get_default_mod_mask() if (event.keyval == Gdk.KEY_f and (event.state & modifiers) == Gdk.ModifierType.CONTROL_MASK): self._show_searchbar(not self.toolbar.searchbar.get_child_revealed()) elif (event.keyval == Gdk.KEY_Escape and (event.state & modifiers) == 0): self._show_searchbar(False) def _notify_mode_disconnect(self, data=None): self._stack.disconnect(self._on_notify_model_id) def _on_notify_mode(self, stack, param): #Slide out artist list on switching to artists view if stack.get_visible_child() == self.views[1]: stack.get_visible_child().stack.set_visible_child_name('dummy') stack.get_visible_child().stack.set_visible_child_name('artists') self._show_searchbar(False) def _toggle_view(self, btn, i): self._stack.set_visible_child(self.views[i]) def _on_search_toggled(self, button, data=None): self._show_searchbar(button.get_active()) def _show_searchbar(self, show): self.toolbar.searchbar.set_reveal_child(show) self.toolbar._search_button.set_active(show) if show: self.toolbar.searchbar._search_entry.grab_focus() else: self.toolbar.searchbar._search_entry.set_text('')
class SnapperGUI(Gtk.ApplicationWindow): """docstring for SnapperGUI""" def __init__(self, app): Gtk.ApplicationWindow.__init__(self, application=app, title="SnapperGUI") self.app = app self.builder = Gtk.Builder() self.builder.add_from_file( pkg_resources.resource_filename("snappergui", "glade/mainWindow.glade")) self.snapshotsBox = self.builder.get_object("snapshotsBox") self.statusbar = self.builder.get_object("statusbar") self.snapshotsTreeView = self.builder.get_object("snapstreeview") self.configsGroup = self.builder.get_object("configsGroup") self.builder.connect_signals(self) self.set_default_size(700, 600) self.configView = {} self.init_configs_stack() self._stack.set_visible_child_name("root") # Switch configurations from the header bar with a StackSwitcher switcher = Gtk.StackSwitcher(margin_top=2, margin_bottom=2, visible=True) switcher.set_stack(self._stack) self.header_bar = Gtk.HeaderBar(title="SnapperGUI", visible=True) self.header_bar.pack_start(switcher) self.header_bar.set_show_close_button(True) if Gtk.get_minor_version() > 8: self.set_titlebar(self.header_bar) else: self._box.pack_start(self.header_bar, False, False, 0) self.set_hide_titlebar_when_maximized(True) self.builder.get_object("snapshotsviewport").add(self._stack) self.add(self.snapshotsBox) # TODO do not hardcode to root configuration self.statusbar.push(5, "%d snapshots" % self.configView["root"].count) self.init_dbus_signal_handlers() self.show() def init_configs_stack(self): self._stack = Stack(transition_type=StackTransitionType.CROSSFADE, transition_duration=300, visible=True) self._stack.set_transition_type( Gtk.StackTransitionType.SLIDE_LEFT_RIGHT) for config in snapper.ListConfigs(): name = str(config[0]) self.configView[name] = snapshotsView(name) self._stack.add_titled(self.configView[name].scrolledwindow, name, name) self.configView[name].selection.connect( "changed", self.on_snapshots_selection_changed) def snapshot_columns(self, snapshot): if (snapshot[3] == -1): date = "Now" else: date = strftime("%a %R %e/%m/%Y", localtime(snapshot[3])) return [ snapshot[0], snapshot[1], snapshot[2], date, getpwuid(snapshot[4])[0], snapshot[5], snapshot[6] ] def get_current_config(self): return self._stack.get_visible_child_name() def on_snapshots_selection_changed(self, selection): config = self.get_current_config() userdatatreeview = self.builder.get_object("userdatatreeview") (model, paths) = selection.get_selected_rows() if (len(paths) == 0): self.builder.get_object("snapshotActions").set_sensitive(False) userdatatreeview.set_model(None) else: self.builder.get_object("snapshotActions").set_sensitive(True) try: snapshot_data = snapper.GetSnapshot( config, model[model.get_iter(paths[0])][0]) userdata_liststore = Gtk.ListStore(str, str) for key, value in snapshot_data[7].items(): userdata_liststore.append([key, value]) userdatatreeview.set_model(userdata_liststore) except dbus.exceptions.DBusException: pass def on_create_snapshot(self, widget): dialog = createSnapshot(self) response = dialog.run() dialog.destroy() if response == Gtk.ResponseType.OK: newSnapshot = snapper.CreateSingleSnapshot(dialog.config, dialog.description, dialog.cleanup, dialog.userdata) elif response == Gtk.ResponseType.CANCEL: pass def on_create_config(self, widget): dialog = createConfig(self) response = dialog.run() dialog.destroy() if response == Gtk.ResponseType.OK: snapper.CreateConfig(dialog.name, dialog.subvolume, dialog.fstype, dialog.template) elif response == Gtk.ResponseType.CANCEL: pass def on_delete_snapshot(self, widget): config = self.get_current_config() selection = self.configView[config].selection (model, paths) = selection.get_selected_rows() snapshots = [] for path in paths: treeiter = model.get_iter(path) # avoid duplicates because post snapshots are always added if model[treeiter][0] not in snapshots: snapshots.append(model[treeiter][0]) # if snapshot has post add that to delete if model.iter_has_child(treeiter): child_treeiter = model.iter_children(treeiter) snapshots.append(model[child_treeiter][0]) dialog = deleteDialog(self, config, snapshots) response = dialog.run() if response == Gtk.ResponseType.YES and len(dialog.to_delete) > 0: snapper.DeleteSnapshots(config, dialog.to_delete) def on_open_snapshot_folder(self, widget): config = self.get_current_config() selection = self.configView[config].selection model, paths = selection.get_selected_rows() for path in paths: treeiter = model.get_iter(path) mountpoint = snapper.GetMountPoint(config, model[treeiter][0]) subprocess.Popen(['xdg-open', mountpoint]) self.statusbar.push( True, "The mount point for the snapshot %s from %s is %s" % (model[treeiter][0], config, mountpoint)) def on_viewchanges_clicked(self, widget): config = self.get_current_config() selection = self.configView[config].selection model, paths = selection.get_selected_rows() if len(paths) > 1: # open a changes window with the first and the last snapshot selected begin = model[paths[0]][0] end = model[paths[-1]][0] window = changesWindow(config, begin, end) elif len(paths) == 1 and model.iter_has_child(model.get_iter( paths[0])): # open a changes window with the selected pre snapshot and is's post child_iter = model.iter_children(model.get_iter(paths[0])) begin = model[paths[0]][0] end = model.get_value(child_iter, 0) window = changesWindow(config, begin, end) def on_configs_properties_clicked(self, notebook): dialog = propertiesDialog(self) dialog.dialog.run() dialog.dialog.hide() def on_about_clicked(self, widget): about = self.builder.get_object("aboutdialog1") about.run() about.hide() def delete_event(self, widget): self.app._window.destroy() def init_dbus_signal_handlers(self): signals = { "SnapshotCreated": self.on_dbus_snapshot_created, "SnapshotModified": self.on_dbus_snapshot_modified, "SnapshotsDeleted": self.on_dbus_snapshots_deleted, "ConfigCreated": self.on_dbus_config_created, "ConfigModified": self.on_dbus_config_modified, "ConfigDeleted": self.on_dbus_config_deleted } for signal, handler in signals.items(): snapper.connect_to_signal(signal, handler) def on_dbus_snapshot_created(self, config, snapshot): self.statusbar.push( True, "Snapshot %s created for %s" % (str(snapshot), config)) self.configView[config].add_snapshot_to_tree(str(snapshot)) def on_dbus_snapshot_modified(self, config, snapshot): print("Snapshot SnapshotModified") def on_dbus_snapshots_deleted(self, config, snapshots): snaps_str = "" for snapshot in snapshots: snaps_str += str(snapshot) + " " self.statusbar.push( True, "Snapshots deleted from %s: %s" % (config, snaps_str)) for deleted in snapshots: self.configView[config].remove_snapshot_from_tree(deleted) def on_dbus_config_created(self, config): self.configView[config] = snapshotsView(config) self.configView[config].update_view() self._stack.add_titled(self.configView[config]._TreeView, config, config) self.statusbar.push(5, "Created new configuration %s" % config) def on_dbus_config_modified(self, args): print("Config Modified") def on_dbus_config_deleted(self, args): print("Config Deleted")
class Window(Gtk.ApplicationWindow): def __init__(self, app): Gtk.ApplicationWindow.__init__(self, application=app, title="Earthquake") self.setup_view() """ self.button = Gtk.Button(label="Play") self.button.connect("clicked", self.on_button_clicked) """ def setup_view(self): self._box = Gtk.VBox() self.toolbar = Toolbar() self.toolbar2 = Toolbar() self.views = [] self._stack = Stack( transition_type=StackTransitionType.CROSSFADE, transition_duration=100, visible=True) self.set_titlebar(self.toolbar.header_bar) self._box.pack_start(self.toolbar.searchbar, False, False, 0) self._box.pack_start(self._stack, True, True, 0) self.add(self._box) count = 1 plugins = Plugins() #self.views.append(Views.ElementView(self.toolbar, _("All"), all_plugins)) """" for cat in cats: self.views.append(Views.ElementView(self.toolbar, _(cat), plugins.get_by_cat(cat))) """ input_plugins = {} suffixes = [("Bins", "bin"), ("Decoders", "dec"), ("Demuxers", "demux"), ("Parsers", "parse"), ("Sources", "src")] for suffix in suffixes: input_plugins[suffix[0]] = plugins.get_by_suffix(suffix[1]) self.views.append(Views.ElementStackView(self.toolbar, "Input", input_plugins)) output_plugins = {} suffixes2 = [("Encoders", "enc"), ("Muxers", "mux"), ("Sinks", "sink")] for suffix in suffixes2: output_plugins[suffix[0]] = plugins.get_by_suffix(suffix[1]) self.views.append(Views.ElementStackView(self.toolbar, "Output", output_plugins)) lib_plugins = {} submodules = ["frei0r", "libav", "opengl", "effectv", "gnonlin", "rtp", "libvisual", "audiofx", "videofilter", "gaudieffects", "coreelements", "rtpmanager", "geometrictransform"] for submodule in submodules: lib_plugins[submodule] = plugins.get_by_cat(submodule) self.views.append(Views.ElementStackView(self.toolbar, "Libs", lib_plugins)) self.views.append(Views.ElementView(self.toolbar, _("Misc"), plugins.get_rest())) for i in self.views: self._stack.add_titled(i, i.title, i.title) self.toolbar.set_stack(self._stack) self.toolbar.searchbar.show() self.toolbar._search_button.connect('toggled', self._on_search_toggled) self.toolbar.set_state(ToolbarState.ALBUMS) self.toolbar.header_bar.show() self._box.show() self.show() def init_gst(self): Gst.init(None) self.pipeline = Gst.Pipeline.new("pipeline") videotestsrc = Gst.ElementFactory.make("videotestsrc", "src") glimagesink = Gst.ElementFactory.make("autovideosink", "sink") self.pipeline.add(videotestsrc) self.pipeline.add(glimagesink) Gst.Element.link(videotestsrc, glimagesink) def on_button_clicked(self, widget): if self.playing: self.pipeline.set_state(Gst.State.PAUSED) self.playing = False self.button.set_label("Play") else: self.pipeline.set_state(Gst.State.PLAYING) self.playing = True self.button.set_label("Pause") def _toggle_view(self, btn, i): self._stack.set_visible_child(self.views[i]) def _on_search_toggled(self, button, data=None): self._show_searchbar(button.get_active()) def _show_searchbar(self, show): self.toolbar.searchbar.set_reveal_child(show) self.toolbar._search_button.set_active(show) if show: self.toolbar.searchbar._search_entry.grab_focus() else: self.toolbar.searchbar._search_entry.set_text('')
class Window(Gtk.ApplicationWindow): def __init__(self, app): Gtk.ApplicationWindow.__init__(self, application=app, title=_("Music")) self.connect('focus-in-event', self._windows_focus_cb) self.settings = Gio.Settings('org.gnome.Music') self.add_action(self.settings.create_action('repeat')) self.set_size_request(887, 640) size_setting = self.settings.get_value('window-size') if isinstance(size_setting[0], int) and isinstance(size_setting[1], int): self.resize(size_setting[0], size_setting[1]) position_setting = self.settings.get_value('window-position') if len(position_setting) == 2 \ and isinstance(position_setting[0], int) \ and isinstance(position_setting[1], int): self.move(position_setting[0], position_setting[1]) if self.settings.get_value('window-maximized'): self.maximize() self.connect("window-state-event", self.on_window_state_event) self.connect("configure-event", self.on_configure_event) self._setup_view() self.proxy = Gio.DBusProxy.new_sync(Gio.bus_get_sync(Gio.BusType.SESSION, None), Gio.DBusProxyFlags.NONE, None, 'org.gnome.SettingsDaemon', '/org/gnome/SettingsDaemon/MediaKeys', 'org.gnome.SettingsDaemon.MediaKeys', None) self._grab_media_player_keys() self.proxy.connect('g-signal', self._handle_media_keys) def on_configure_event(self, widget, event): size = widget.get_size() self.settings.set_value('window-size', GLib.Variant('ai', [size[0], size[1]])) position = widget.get_position() self.settings.set_value('window-position', GLib.Variant('ai', [position[0], position[1]])) def on_window_state_event(self, widget, event): self.settings.set_boolean('window-maximized', 'GDK_WINDOW_STATE_MAXIMIZED' in event.new_window_state.value_names) def _grab_media_player_keys(self): self.proxy.call_sync('GrabMediaPlayerKeys', GLib.Variant('(su)', ('Music', 0)), Gio.DBusCallFlags.NONE, -1, None) def _windows_focus_cb(self, window, event): self._grab_media_player_keys() def _handle_media_keys(self, proxy, sender, signal, parameters): if signal != 'MediaPlayerKeyPressed': print('Received an unexpected signal \'%s\' from media player'.format(signal)) return response = parameters.get_child_value(1).get_string() if 'Play' in response: self.player.play_pause() elif 'Stop' in response: self.player.Stop() elif 'Next' in response: self.player.play_next() elif 'Previous' in response: self.player.play_previous() def _setup_view(self): self._box = Gtk.VBox() self.player = Player() self.selection_toolbar = SelectionToolbar() self.toolbar = Toolbar() self.views = [] self._stack = Stack( transition_type=StackTransitionType.CROSSFADE, transition_duration=100, visible=True) if Gtk.get_minor_version() > 8: self.set_titlebar(self.toolbar.header_bar) else: self._box.pack_start(self.toolbar.header_bar, False, False, 0) self.set_hide_titlebar_when_maximized(True) self._box.pack_start(self.toolbar.searchbar, False, False, 0) self._box.pack_start(self._stack, True, True, 0) self._box.pack_start(self.player.eventBox, False, False, 0) self._box.pack_start(self.selection_toolbar.eventbox, False, False, 0) self.add(self._box) count = 1 cursor = tracker.query(Query.SONGS_COUNT, None) if cursor is not None and cursor.next(None): count = cursor.get_integer(0) if count > 0: self.views.append(Views.Albums(self.toolbar, self.selection_toolbar, self.player)) self.views.append(Views.Artists(self.toolbar, self.selection_toolbar, self.player)) self.views.append(Views.Songs(self.toolbar, self.selection_toolbar, self.player)) #self.views.append(Views.Playlist(self.toolbar, self.selection_toolbar, self.player)) for i in self.views: self._stack.add_titled(i, i.title, i.title) self.toolbar.set_stack(self._stack) self.toolbar.searchbar.show() self._on_notify_model_id = self._stack.connect('notify::visible-child', self._on_notify_mode) self.connect('destroy', self._notify_mode_disconnect) self.connect('key_press_event', self._on_key_press) self.views[0].populate() #To revert to the No Music View when no songs are found else: self.views.append(Views.Empty(self.toolbar, self.player)) self._stack.add_titled(self.views[0], _("Empty"), _("Empty")) self.toolbar._search_button.connect('toggled', self._on_search_toggled) self.toolbar.set_state(ToolbarState.ALBUMS) self.toolbar.header_bar.show() self.player.eventBox.show_all() self._box.show() self.show() def _on_key_press(self, widget, event): modifiers = Gtk.accelerator_get_default_mod_mask() if (event.keyval == Gdk.KEY_f and (event.state & modifiers) == Gdk.ModifierType.CONTROL_MASK): self._show_searchbar(not self.toolbar.searchbar.get_child_revealed()) elif (event.keyval == Gdk.KEY_Escape and (event.state & modifiers) == 0): self._show_searchbar(False) if self.toolbar._selectionMode: self.toolbar.set_selection_mode(False) def _notify_mode_disconnect(self, data=None): self._stack.disconnect(self._on_notify_model_id) def _on_notify_mode(self, stack, param): #Slide out artist list on switching to artists view if stack.get_visible_child() == self.views[1]: stack.get_visible_child().stack.set_visible_child_name('dummy') stack.get_visible_child().stack.set_visible_child_name('artists') self._show_searchbar(False) def _toggle_view(self, btn, i): self._stack.set_visible_child(self.views[i]) def _on_search_toggled(self, button, data=None): self._show_searchbar(button.get_active()) def _show_searchbar(self, show): self.toolbar.searchbar.set_reveal_child(show) self.toolbar._search_button.set_active(show) if show: self.toolbar.searchbar._search_entry.grab_focus() else: self.toolbar.searchbar._search_entry.set_text('')
class Window(Gtk.ApplicationWindow): def __init__(self, app): Gtk.ApplicationWindow.__init__(self, application=app, title=_("Music")) self.connect('focus-in-event', self._windows_focus_cb) self.settings = Gio.Settings.new('org.gnome.Music') self.add_action(self.settings.create_action('repeat')) selectAll = Gio.SimpleAction.new('selectAll', None) selectAll.connect('activate', self._on_select_all) self.add_action(selectAll) selectNone = Gio.SimpleAction.new('selectNone', None) selectNone.connect('activate', self._on_select_none) self.add_action(selectNone) self.set_size_request(200, 100) size_setting = self.settings.get_value('window-size') if isinstance(size_setting[0], int) and isinstance(size_setting[1], int): self.resize(size_setting[0], size_setting[1]) position_setting = self.settings.get_value('window-position') if len(position_setting) == 2 \ and isinstance(position_setting[0], int) \ and isinstance(position_setting[1], int): self.move(position_setting[0], position_setting[1]) if self.settings.get_value('window-maximized'): self.maximize() self.connect("window-state-event", self._on_window_state_event) self.connect("configure-event", self._on_configure_event) self._setup_view() self.proxy = Gio.DBusProxy.new_sync(Gio.bus_get_sync(Gio.BusType.SESSION, None), Gio.DBusProxyFlags.NONE, None, 'org.gnome.SettingsDaemon', '/org/gnome/SettingsDaemon/MediaKeys', 'org.gnome.SettingsDaemon.MediaKeys', None) self._grab_media_player_keys() try: self.proxy.connect('g-signal', self._handle_media_keys) except GLib.GError: # We cannot grab media keys if no settings daemon is running pass def _on_configure_event(self, widget, event): size = widget.get_size() self.settings.set_value('window-size', GLib.Variant('ai', [size[0], size[1]])) position = widget.get_position() self.settings.set_value('window-position', GLib.Variant('ai', [position[0], position[1]])) def _on_window_state_event(self, widget, event): self.settings.set_boolean('window-maximized', 'GDK_WINDOW_STATE_MAXIMIZED' in event.new_window_state.value_names) def _grab_media_player_keys(self): try: self.proxy.call_sync('GrabMediaPlayerKeys', GLib.Variant('(su)', ('Music', 0)), Gio.DBusCallFlags.NONE, -1, None) except GLib.GError: # We cannot grab media keys if no settings daemon is running pass def _windows_focus_cb(self, window, event): self._grab_media_player_keys() def _handle_media_keys(self, proxy, sender, signal, parameters): if signal != 'MediaPlayerKeyPressed': print('Received an unexpected signal \'%s\' from media player'.format(signal)) return response = parameters.get_child_value(1).get_string() if 'Play' in response: self.player.play_pause() elif 'Stop' in response: self.player.Stop() elif 'Next' in response: self.player.play_next() elif 'Previous' in response: self.player.play_previous() def _setup_view(self): self._box = Gtk.VBox() self.player = Player() self.selection_toolbar = SelectionToolbar() self.toolbar = Toolbar() self.views = [] self._stack = Stack( transition_type=StackTransitionType.CROSSFADE, transition_duration=100, visible=True) if Gtk.get_minor_version() > 8: self.set_titlebar(self.toolbar.header_bar) else: self._box.pack_start(self.toolbar.header_bar, False, False, 0) self.set_hide_titlebar_when_maximized(True) self._box.pack_start(self.toolbar.searchbar, False, False, 0) self._box.pack_start(self._stack, True, True, 0) self._box.pack_start(self.player.eventBox, False, False, 0) self._box.pack_start(self.selection_toolbar.eventbox, False, False, 0) self.add(self._box) count = 1 cursor = tracker.query(Query.SONGS_COUNT, None) if cursor is not None and cursor.next(None): count = cursor.get_integer(0) if count > 0: self.views.append(Views.Albums(self.toolbar, self.selection_toolbar, self.player)) self.views.append(Views.Artists(self.toolbar, self.selection_toolbar, self.player)) self.views.append(Views.Songs(self.toolbar, self.selection_toolbar, self.player)) self.views.append(Views.Playlist(self.toolbar, self.selection_toolbar, self.player)) for i in self.views: self._stack.add_titled(i, i.title, i.title) self.toolbar.set_stack(self._stack) self.toolbar.searchbar.show() self._on_notify_model_id = self._stack.connect('notify::visible-child', self._on_notify_mode) self.connect('destroy', self._notify_mode_disconnect) self.connect('key_press_event', self._on_key_press) self.views[0].populate() #To revert to the No Music View when no songs are found else: self.views.append(Views.Empty(self.toolbar, self.player)) self._stack.add_titled(self.views[0], _("Empty"), _("Empty")) self.toolbar._search_button.set_sensitive(False) self.toolbar._select_button.set_sensitive(False) self.toolbar._search_button.connect('toggled', self._on_search_toggled) self.toolbar.connect('selection-mode-changed', self._on_selection_mode_changed) self.selection_toolbar._add_to_playlist_button.connect( 'clicked', self._on_add_to_playlist_button_clicked) self.selection_toolbar._remove_from_playlist_button.connect( 'clicked', self._on_remove_from_playlist_button_clicked) self.toolbar.set_state(ToolbarState.ALBUMS) self.toolbar.header_bar.show() self.player.eventBox.show_all() self._box.show() self.show() def _on_select_all(self, action, param): if self.toolbar._state != ToolbarState.SINGLE: model = self._stack.get_visible_child()._model else: model = self._stack.get_visible_child()._albumWidget.model _iter = model.get_iter_first() count = 0 while _iter is not None: model.set(_iter, [6], [True]) _iter = model.iter_next(_iter) count = count + 1 if count > 0: self.toolbar._selection_menu_label.set_text( ngettext(_("Selected %d item"), _("Selected %d items"), count) % count) self.selection_toolbar._add_to_playlist_button.set_sensitive(True) self.selection_toolbar._remove_from_playlist_button.set_sensitive(True) elif count == 0: self.toolbar._selection_menu_label.set_text(_("Click on items to select them")) def _on_select_none(self, action, param): if self.toolbar._state != ToolbarState.SINGLE: model = self._stack.get_visible_child()._model else: model = self._stack.get_visible_child()._albumWidget.model _iter = model.get_iter_first() self.selection_toolbar._add_to_playlist_button.set_sensitive(False) self.selection_toolbar._remove_from_playlist_button.set_sensitive(False) while _iter is not None: model.set(_iter, [6], [False]) _iter = model.iter_next(_iter) self.toolbar._selection_menu_label.set_text(_("Click on items to select them")) def _on_key_press(self, widget, event): modifiers = Gtk.accelerator_get_default_mod_mask() if (event.keyval == Gdk.KEY_f and (event.state & modifiers) == Gdk.ModifierType.CONTROL_MASK): self.toolbar.searchbar.toggle_bar() elif (event.keyval == Gdk.KEY_Escape and (event.state & modifiers) == 0): self.toolbar.searchbar.show_bar(False) if self.toolbar._selectionMode: self.toolbar.set_selection_mode(False) elif (event.state & modifiers) == 0 and \ event.keyval in range(33, 126) and \ not self.toolbar.searchbar.get_reveal_child(): self.toolbar.searchbar.show_bar(True) def _notify_mode_disconnect(self, data=None): self._stack.disconnect(self._on_notify_model_id) def _on_notify_mode(self, stack, param): #Slide out artist list on switching to artists view if stack.get_visible_child() == self.views[1] or \ stack.get_visible_child() == self.views[3]: stack.get_visible_child().stack.set_visible_child_name('dummy') stack.get_visible_child().stack.set_visible_child_name('sidebar') self.toolbar.searchbar.show_bar(False) def _toggle_view(self, btn, i): self._stack.set_visible_child(self.views[i]) def _on_search_toggled(self, button, data=None): self.toolbar.searchbar.show_bar(button.get_active()) def _on_selection_mode_changed(self, widget, data=None): if self.toolbar._selectionMode: in_playlist = self._stack.get_visible_child() == self.views[3] self.selection_toolbar._add_to_playlist_button.set_visible(not in_playlist) self.selection_toolbar._remove_from_playlist_button.set_visible(in_playlist) def _on_add_to_playlist_button_clicked(self, widget): if self._stack.get_visible_child() == self.views[3]: return def callback(selected_uris): if len(selected_uris) < 1: return add_to_playlist = Widgets.PlaylistDialog(self) if add_to_playlist.dialog_box.run() == Gtk.ResponseType.ACCEPT: playlist.add_to_playlist( add_to_playlist.get_selected(), selected_uris) self.toolbar.set_selection_mode(False) add_to_playlist.dialog_box.destroy() self._stack.get_visible_child().get_selected_track_uris(callback) def _on_remove_from_playlist_button_clicked(self, widget): if self._stack.get_visible_child() != self.views[3]: return def callback(selected_uris): if len(selected_uris) < 1: return playlist.remove_from_playlist( self.views[3].current_playlist, selected_uris) self.toolbar.set_selection_mode(False) self._stack.get_visible_child().get_selected_track_uris(callback)
def stackup_section(self, stack: Gtk.Stack) -> None: name = self.get_name() title = name.capitalize() stack.add_titled(self, name, title)
class SnapperGUI(Gtk.ApplicationWindow): """docstring for SnapperGUI""" def __init__(self, app): Gtk.ApplicationWindow.__init__(self, application=app, title="SnapperGUI") self.app = app self.builder = Gtk.Builder() self.builder.add_from_file(pkg_resources.resource_filename("snappergui", "glade/mainWindow.glade")) self.snapshotsBox = self.builder.get_object("snapshotsBox") self.statusbar = self.builder.get_object("statusbar") self.snapshotsTreeView = self.builder.get_object("snapstreeview") self.configsGroup = self.builder.get_object("configsGroup") self.builder.connect_signals(self) self.set_default_size(700,600) self.configView = {} self.init_configs_stack() self._stack.set_visible_child_name("root") # Switch configurations from the header bar with a StackSwitcher switcher = Gtk.StackSwitcher(margin_top=2, margin_bottom=2, visible=True) switcher.set_stack(self._stack) self.header_bar = Gtk.HeaderBar(title="SnapperGUI",visible=True) self.header_bar.pack_start(switcher) self.header_bar.set_show_close_button(True) if Gtk.get_minor_version() > 8: self.set_titlebar(self.header_bar) else: self._box.pack_start(self.header_bar, False, False, 0) self.set_hide_titlebar_when_maximized(True) self.builder.get_object("snapshotsviewport").add(self._stack) self.add(self.snapshotsBox) # TODO do not hardcode to root configuration self.statusbar.push(5,"%d snapshots"% self.configView["root"].count) self.init_dbus_signal_handlers() self.show() def init_configs_stack(self): self._stack = Stack( transition_type=StackTransitionType.CROSSFADE, transition_duration=300, visible=True) self._stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT_RIGHT) for config in snapper.ListConfigs(): name = str(config[0]) self.configView[name] = snapshotsView(name) self._stack.add_titled(self.configView[name].scrolledwindow, name, name) self.configView[name].selection.connect("changed", self.on_snapshots_selection_changed) def snapshot_columns(self,snapshot): if(snapshot[3] == -1): date = "Now" else: date = strftime("%a %R %e/%m/%Y", localtime(snapshot[3])) return [snapshot[0], snapshot[1], snapshot[2], date, getpwuid(snapshot[4])[0], snapshot[5], snapshot[6]] def get_current_config(self): return self._stack.get_visible_child_name() def on_snapshots_selection_changed(self,selection): config = self.get_current_config() userdatatreeview = self.builder.get_object("userdatatreeview") (model, paths) = selection.get_selected_rows() if(len(paths) == 0): self.builder.get_object("snapshotActions").set_sensitive(False) userdatatreeview.set_model(None) else: self.builder.get_object("snapshotActions").set_sensitive(True) try: snapshot_data = snapper.GetSnapshot(config,model[model.get_iter(paths[0])][0]) userdata_liststore = Gtk.ListStore(str, str) for key, value in snapshot_data[7].items(): userdata_liststore.append([key, value]) userdatatreeview.set_model(userdata_liststore) except dbus.exceptions.DBusException: pass def on_create_snapshot(self, widget): dialog = createSnapshot(self) response = dialog.run() dialog.destroy() if response == Gtk.ResponseType.OK: newSnapshot = snapper.CreateSingleSnapshot(dialog.config, dialog.description, dialog.cleanup, dialog.userdata) elif response == Gtk.ResponseType.CANCEL: pass def on_create_config(self, widget): dialog = createConfig(self) response = dialog.run() dialog.destroy() if response == Gtk.ResponseType.OK: snapper.CreateConfig(dialog.name, dialog.subvolume, dialog.fstype, dialog.template) elif response == Gtk.ResponseType.CANCEL: pass def on_delete_snapshot(self, widget): config = self.get_current_config() selection = self.configView[config].selection (model, paths) = selection.get_selected_rows() snapshots = [] for path in paths: treeiter = model.get_iter(path) # avoid duplicates because post snapshots are always added if model[treeiter][0] not in snapshots: snapshots.append(model[treeiter][0]) # if snapshot has post add that to delete if model.iter_has_child(treeiter): child_treeiter = model.iter_children(treeiter) snapshots.append(model[child_treeiter][0]) dialog = deleteDialog(self, config,snapshots) response = dialog.run() if response == Gtk.ResponseType.YES and len(dialog.to_delete) > 0: snapper.DeleteSnapshots(config, dialog.to_delete) def on_open_snapshot_folder(self, widget): config = self.get_current_config() selection = self.configView[config].selection model, paths = selection.get_selected_rows() for path in paths: treeiter = model.get_iter(path) mountpoint = snapper.GetMountPoint(config, model[treeiter][0]) subprocess.Popen(['xdg-open', mountpoint]) self.statusbar.push(True, "The mount point for the snapshot %s from %s is %s"% (model[treeiter][0], config, mountpoint)) def on_viewchanges_clicked(self, widget): config = self.get_current_config() selection = self.configView[config].selection model, paths = selection.get_selected_rows() if len(paths) > 1: # open a changes window with the first and the last snapshot selected begin = model[paths[0]][0] end = model[paths[-1]][0] window = changesWindow(config, begin, end) elif len(paths) == 1 and model.iter_has_child(model.get_iter(paths[0])): # open a changes window with the selected pre snapshot and is's post child_iter = model.iter_children(model.get_iter(paths[0])) begin = model[paths[0]][0] end = model.get_value(child_iter,0) window = changesWindow(config, begin, end) def on_configs_properties_clicked(self, notebook): dialog = propertiesDialog(self) dialog.dialog.run() dialog.dialog.hide() def on_about_clicked(self,widget): about = self.builder.get_object("aboutdialog1") about.run() about.hide() def delete_event(self,widget): self.app._window.destroy() def init_dbus_signal_handlers(self): signals = { "SnapshotCreated" : self.on_dbus_snapshot_created, "SnapshotModified" : self.on_dbus_snapshot_modified, "SnapshotsDeleted" : self.on_dbus_snapshots_deleted, "ConfigCreated" : self.on_dbus_config_created, "ConfigModified" : self.on_dbus_config_modified, "ConfigDeleted" : self.on_dbus_config_deleted } for signal, handler in signals.items(): snapper.connect_to_signal(signal,handler) def on_dbus_snapshot_created(self,config,snapshot): self.statusbar.push(True, "Snapshot %s created for %s"% (str(snapshot), config)) self.configView[config].add_snapshot_to_tree(str(snapshot)) def on_dbus_snapshot_modified(self,config,snapshot): print("Snapshot SnapshotModified") def on_dbus_snapshots_deleted(self,config,snapshots): snaps_str = "" for snapshot in snapshots: snaps_str += str(snapshot) + " " self.statusbar.push(True, "Snapshots deleted from %s: %s"% (config, snaps_str)) for deleted in snapshots: self.configView[config].remove_snapshot_from_tree(deleted) def on_dbus_config_created(self, config): self.configView[config] = snapshotsView(config) self.configView[config].update_view() self._stack.add_titled(self.configView[config]._TreeView, config, config) self.statusbar.push(5,"Created new configuration %s"% config) def on_dbus_config_modified(self,args): print("Config Modified") def on_dbus_config_deleted(self,args): print("Config Deleted")