def __init__(self, app): DBusGMainLoop(set_as_default=True) name = dbus.service.BusName('org.mpris.MediaPlayer2.GnomeMusic', dbus.SessionBus()) dbus.service.Object.__init__(self, name, '/org/mpris/MediaPlayer2') self.app = app self.player = app.get_active_window().player self.player.connect('current-changed', self._on_current_changed) self.player.connect('thumbnail-updated', self._on_thumbnail_updated) self.player.connect('playback-status-changed', self._on_playback_status_changed) self.player.connect('repeat-mode-changed', self._on_repeat_mode_changed) self.player.connect('volume-changed', self._on_volume_changed) self.player.connect('prev-next-invalidated', self._on_prev_next_invalidated) self.player.connect('seeked', self._on_seeked) self.player.connect('playlist-changed', self._on_playlist_changed) playlists = Playlists.get_default() playlists.connect('playlist-created', self._on_playlists_count_changed) playlists.connect('playlist-deleted', self._on_playlists_count_changed) grilo.connect('ready', self._on_grilo_ready) self.playlists = [] self.playlist = None self.playlist_insert_handler = 0 self.playlist_delete_handler = 0 self.first_song_handler = 0
def __init__(self, parent): self.ui = Gtk.Builder() self.ui.add_from_resource('/org/gnome/Music/PlaylistDialog.ui') self.dialog_box = self.ui.get_object('dialog1') self.dialog_box.set_transient_for(parent) self.view = self.ui.get_object('treeview1') self.selection = self.ui.get_object('treeview-selection1') self._add_list_renderers() self.view.connect('row-activated', self._on_item_activated) self.model = self.ui.get_object('liststore1') self.populate() self.title_bar = self.ui.get_object('headerbar1') self.dialog_box.set_titlebar(self.title_bar) self._cancel_button = self.ui.get_object('cancel-button') self._select_button = self.ui.get_object('select-button') self._select_button.set_sensitive(False) self._cancel_button.connect('clicked', self._on_cancel_button_clicked) self._select_button.connect('clicked', self._on_selection) self.playlist = Playlists.get_default() self.playlist.connect('playlist-created', self._on_playlist_created)
def __init__(self, app): self.con = Gio.bus_get_sync(Gio.BusType.SESSION, None) Gio.bus_own_name_on_connection(self.con, 'org.mpris.MediaPlayer2.GnomeMusic', Gio.BusNameOwnerFlags.NONE, None, None) super().__init__(self.con, '/org/mpris/MediaPlayer2') self.app = app self.player = app.get_active_window().player self.player.connect('current-changed', self._on_current_changed) self.player.connect('thumbnail-updated', self._on_thumbnail_updated) self.player.connect('playback-status-changed', self._on_playback_status_changed) self.player.connect('repeat-mode-changed', self._on_repeat_mode_changed) self.player.connect('volume-changed', self._on_volume_changed) self.player.connect('prev-next-invalidated', self._on_prev_next_invalidated) self.player.connect('seeked', self._on_seeked) self.player.connect('playlist-changed', self._on_playlist_changed) playlists = Playlists.get_default() playlists.connect('playlist-created', self._on_playlists_count_changed) playlists.connect('playlist-deleted', self._on_playlists_count_changed) grilo.connect('ready', self._on_grilo_ready) self.playlists = [] self.playlist = None self.playlist_insert_handler = 0 self.playlist_delete_handler = 0 self.first_song_handler = 0
def __init__(self, parent): self.ui = Gtk.Builder() self.ui.add_from_resource('/org/gnome/Music/PlaylistDialog.ui') self.dialog_box = self.ui.get_object('dialog1') self.dialog_box.set_transient_for(parent) self.view = self.ui.get_object('treeview1') self.selection = self.ui.get_object('treeview-selection1') self.selection.connect('changed', self._on_selection_changed) self._add_list_renderers() self.view.connect('row-activated', self._on_item_activated) self.model = self.ui.get_object('liststore1') self.populate() self.title_bar = self.ui.get_object('headerbar1') self.dialog_box.set_titlebar(self.title_bar) self._cancel_button = self.ui.get_object('cancel-button') self._select_button = self.ui.get_object('select-button') self._select_button.set_sensitive(False) self._cancel_button.connect('clicked', self._on_cancel_button_clicked) self._select_button.connect('clicked', self._on_selection) self.playlist = Playlists.get_default() self.playlist.connect('playlist-created', self._on_playlist_created)
def __init__(self, app): self.con = Gio.bus_get_sync(Gio.BusType.SESSION, None) Gio.bus_own_name_on_connection(self.con, 'org.mpris.MediaPlayer2.GnomeMusic', Gio.BusNameOwnerFlags.NONE, None, None) super().__init__(self.con, '/org/mpris/MediaPlayer2') self.app = app self.player = app.props.player self.player.connect('song-changed', self._on_current_song_changed) self.player.connect('notify::state', self._on_player_state_changed) self.player.connect('notify::repeat-mode', self._on_repeat_mode_changed) self.player.connect('seek-finished', self._on_seek_finished) self.player.connect('playlist-changed', self._on_player_playlist_changed) self._playlists = Playlists.get_default() self._playlists.connect('playlist-created', self._on_playlists_count_changed) self._playlists.connect('playlist-deleted', self._on_playlists_count_changed) self._playlists.connect('playlist-renamed', self._on_playlist_renamed) grilo.connect('ready', self._on_grilo_ready) self._stored_playlists = [] self._player_previous_type = None self._path_list = [] self._metadata_list = [] self._previous_can_go_next = False self._previous_can_go_previous = False self._previous_can_play = False self._previous_is_shuffled = None self._previous_loop_status = "" self._previous_mpris_playlist = self._get_active_playlist() self._previous_playback_status = "Stopped"
def __init__(self, app): self.con = Gio.bus_get_sync(Gio.BusType.SESSION, None) Gio.bus_own_name_on_connection(self.con, 'org.mpris.MediaPlayer2.GnomeMusic', Gio.BusNameOwnerFlags.NONE, None, None) super().__init__(self.con, '/org/mpris/MediaPlayer2') self.app = app self.player = app.get_active_window()._player self.player.connect('song-changed', self._on_current_song_changed) self.player.connect('notify::state', self._on_player_state_changed) self.player.connect('notify::repeat-mode', self._on_repeat_mode_changed) self.player.connect('volume-changed', self._on_volume_changed) self.player.connect('prev-next-invalidated', self._on_prev_next_invalidated) self.player.connect('seek-finished', self._on_seek_finished) self.player.connect('playlist-changed', self._on_player_playlist_changed) self.player_toolbar = app.get_active_window()._player_toolbar self.player_toolbar.connect('thumbnail-updated', self._on_thumbnail_updated) playlists = Playlists.get_default() playlists.connect('playlist-created', self._on_playlists_count_changed) playlists.connect('playlist-deleted', self._on_playlists_count_changed) grilo.connect('ready', self._on_grilo_ready) self.playlists = [] self._player_previous_type = None self._path_list = [] self._metadata_list = []
def __init__(self, app): self.con = Gio.bus_get_sync(Gio.BusType.SESSION, None) Gio.bus_own_name_on_connection(self.con, 'org.mpris.MediaPlayer2.GnomeMusic', Gio.BusNameOwnerFlags.NONE, None, None) super().__init__(self.con, '/org/mpris/MediaPlayer2') self.app = app self.player = app.props.player self.player.connect( 'song-changed', self._on_current_song_changed) self.player.connect('notify::state', self._on_player_state_changed) self.player.connect('notify::repeat-mode', self._on_repeat_mode_changed) self.player.connect('seek-finished', self._on_seek_finished) self.player.connect( 'playlist-changed', self._on_player_playlist_changed) self.player_toolbar = app.get_active_window()._player_toolbar self.player_toolbar.connect( 'thumbnail-updated', self._on_thumbnail_updated) playlists = Playlists.get_default() playlists.connect('playlist-created', self._on_playlists_count_changed) playlists.connect('playlist-deleted', self._on_playlists_count_changed) grilo.connect('ready', self._on_grilo_ready) self.playlists = [] self._player_previous_type = None self._path_list = [] self._metadata_list = [] self._previous_playback_status = "Stopped"
def __init__(self, parent, playlists_todelete): super().__init__() self._add_playlist_button = None self._add_playlist_entry = None self.props.transient_for = parent self.set_titlebar(self._title_bar) self._populate() self._playlists_todelete_ids = playlists_todelete.keys() self._user_playlists_available = False self._playlist = Playlists.get_default() self._playlist.connect('playlist-created', self._on_playlist_created)
def __init__(self, parent, playlists_todelete): self._ui = Gtk.Builder() self._ui.add_from_resource('/org/gnome/Music/PlaylistDialog.ui') self._dialog_box = self._ui.get_object('dialog') self._dialog_box.set_transient_for(parent) self._add_playlist_stack = self._ui.get_object('add_playlist_stack') self._normal_state = self._ui.get_object('normal_state') self._empty_state = self._ui.get_object('empty_state') self._title_bar = self._ui.get_object('headerbar') self._dialog_box.set_titlebar(self._title_bar) self._setup_dialog() self._playlists_todelete_ids = playlists_todelete.keys() self._playlist = Playlists.get_default()
gi.require_version('Gst', '1.0') gi.require_version('GstAudio', '1.0') gi.require_version('GstPbutils', '1.0') from gi.repository import Gtk, Gdk, GLib, Gio, GObject, Gst, GstAudio, GstPbutils from gettext import gettext as _, ngettext from gnomemusic import log from gnomemusic.albumartcache import AlbumArtCache, DefaultIcon, ArtSize from gnomemusic.grilo import grilo from gnomemusic.playlists import Playlists from gnomemusic.scrobbler import LastFmScrobbler import gnomemusic.utils as utils logger = logging.getLogger(__name__) playlists = Playlists.get_default() class RepeatType: NONE = 0 SONG = 1 ALL = 2 SHUFFLE = 3 class PlaybackStatus: PLAYING = 0 PAUSED = 1 STOPPED = 2
from gnomemusic.views.artistsview import ArtistsView from gnomemusic.views.emptyview import EmptyView from gnomemusic.views.emptysearchview import EmptySearchView from gnomemusic.views.initialstateview import InitialStateView from gnomemusic.views.searchview import SearchView from gnomemusic.views.songsview import SongsView from gnomemusic.views.playlistview import PlaylistView from gnomemusic.widgets.playlistdialog import PlaylistDialog from gnomemusic.playlists import Playlists from gnomemusic.grilo import grilo import logging logger = logging.getLogger(__name__) tracker = TrackerWrapper().tracker playlist = Playlists.get_default() class Window(Gtk.ApplicationWindow): def __repr__(self): return '<Window>' @log 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'))
class SongWidget(Gtk.EventBox): """The single song widget used in DiscListBox Contains * play icon (depending on state) * selection check box (optional) * song number on disc (optional) * song title * song duration (optional) * favorite/star picker (optional) """ __gtype_name__ = 'SongWidget' __gsignals__ = { 'selection-changed': (GObject.SignalFlags.RUN_FIRST, None, ()), } selected = GObject.Property(type=bool, default=False) show_duration = GObject.Property(type=bool, default=True) show_favorite = GObject.Property(type=bool, default=True) show_song_number = GObject.Property(type=bool, default=True) _playlists = Playlists.get_default() _select_button = Gtk.Template.Child() _number_label = Gtk.Template.Child() _title_label = Gtk.Template.Child() _duration_label = Gtk.Template.Child() _star_eventbox = Gtk.Template.Child() _star_image = Gtk.Template.Child() _play_icon = Gtk.Template.Child() class State(IntEnum): """The state of the SongWidget """ PLAYED = 0 PLAYING = 1 UNPLAYED = 2 def __repr__(self): return '<SongWidget>' @log def __init__(self, media): super().__init__() self._media = media self._selection_mode = False self._state = SongWidget.State.UNPLAYED song_number = media.get_track_number() if song_number == 0: song_number = "" self._number_label.set_text(str(song_number)) title = utils.get_media_title(media) self._title_label.set_max_width_chars(50) self._title_label.set_text(title) time = utils.seconds_to_string(media.get_duration()) self._duration_label.set_text(time) self._star_image.props.favorite = media.get_favourite() self._select_button.set_visible(False) self._play_icon.set_from_icon_name('media-playback-start-symbolic', Gtk.IconSize.SMALL_TOOLBAR) self._play_icon.set_no_show_all(True) self.bind_property( 'selected', self._select_button, 'active', GObject.BindingFlags.BIDIRECTIONAL | GObject.BindingFlags.SYNC_CREATE) self.bind_property('show-duration', self._duration_label, 'visible', GObject.BindingFlags.SYNC_CREATE) self._duration_label.set_no_show_all(True) self.bind_property('show-favorite', self._star_eventbox, 'visible', GObject.BindingFlags.SYNC_CREATE) self._star_eventbox.set_no_show_all(True) self.bind_property('show-song-number', self._number_label, 'visible', GObject.BindingFlags.SYNC_CREATE) self._number_label.set_no_show_all(True) @Gtk.Template.Callback() @log def _on_selection_changed(self, klass): self.emit('selection-changed') @Gtk.Template.Callback() @log def _on_star_toggle(self, widget, event): if event.button != Gdk.BUTTON_PRIMARY: return False favorite = not self._star_image.favorite self._star_image.props.favorite = favorite # TODO: Rework and stop updating widgets from here directly. grilo.set_favorite(self._media, favorite) self._playlists.update_static_playlist(StaticPlaylists.Favorites) return True @Gtk.Template.Callback() @log def _on_star_hover(self, widget, event): self._star_image.props.hover = True @Gtk.Template.Callback() @log def _on_star_unhover(self, widget, event): self._star_image.props.hover = False @GObject.Property(type=bool, default=False) def selection_mode(self): """Selection mode :returns: Selection mode :rtype: bool """ return self._selection_mode @selection_mode.setter def selection_mode(self, value): """Set the selection mode :param bool value: Selection mode """ self._selection_mode = value self._select_button.set_visible(value) if not value: self.props.selected = False @GObject.Property def state(self): """State of the widget :returns: Widget state :rtype: SongWidget.State """ return self._state @state.setter def state(self, value): """Set state of the of widget This influences the look of the widgets label and if there is a song play indicator being shown. :param SongWidget.State value: Widget state """ self._state = value style_ctx = self._title_label.get_style_context() style_ctx.remove_class('dim-label') style_ctx.remove_class('playing-song-label') self._play_icon.set_visible(False) if value == SongWidget.State.PLAYED: style_ctx.add_class('dim-label') elif value == SongWidget.State.PLAYING: self._play_icon.set_visible(True) style_ctx.add_class('playing-song-label')
class DiscBox(Gtk.Box): """A widget which compromises one disc DiscBox contains a disc label for the disc number on top with a DiscSongsFlowBox beneath. """ __gtype_name__ = 'DiscBox' __gsignals__ = { 'selection-changed': (GObject.SignalFlags.RUN_FIRST, None, ()), 'selection-toggle': (GObject.SignalFlags.RUN_FIRST, None, ()), 'song-activated': (GObject.SignalFlags.RUN_FIRST, None, (Gtk.Widget, )) } _playlists = Playlists.get_default() def __repr__(self): return '<DiscBox>' @log def __init__(self, model=None): """Initialize :param model: The TreeStore to use """ super().__init__() self._model = model self._model.connect('row-changed', self._model_row_changed) builder = Gtk.Builder() builder.add_from_resource('/org/gnome/Music/ArtistAlbumWidget.ui') self._label = builder.get_object('disclabel') self._label.set_no_show_all(True) self._disc_songs_flowbox = builder.get_object('discsongsflowbox') self._selection_mode = False self._selection_mode_allowed = True self._selected_items = [] self._songs = [] self.pack_start(builder.get_object('disc'), True, True, 0) @log def set_columns(self, columns): """Set the number of columns used by the songs list :param int columns: Number of columns to display """ self._disc_songs_flowbox.set_columns(columns) @log def set_disc_number(self, disc_number): """Set the dics number to display :param int disc_number: Disc number to display """ self._label.set_markup(_("Disc {}").format(disc_number)) self._label.get_style_context().add_class('dim-label') self._label.set_visible(True) @log def show_disc_label(self, show_header): """Wheter to show the disc number label :param bool show_header: Display the disc number label """ self._label.set_visible(False) self._label.hide() @log def show_duration(self, show_duration): """Wheter to show the song durations :param bool show_duration: Display the song durations """ def child_show_duration(child): child.get_child().duration.set_visible(show_duration) self._disc_songs_flowbox.foreach(child_show_duration) @log def show_favorites(self, show_favorites): """Where to show the favorite switches :param bool show_favorites: Display the favorite switches """ def child_show_favorites(child): child.get_child().starevent.set_visible(show_favorites) self._disc_songs_flowbox.foreach(child_show_favorites) @log def show_song_numbers(self, show_song_number): """Whether to show the song numbers :param bool show_song_number: Display the song number """ def child_show_song_number(child): child.get_child().number.set_visible(show_song_number) self._disc_songs_flowbox.foreach(child_show_song_number) @log def set_songs(self, songs): """Songs to display :param list songs: A list of Grilo media items to add to the widget """ for song in songs: song_widget = self._create_song_widget(song) self._disc_songs_flowbox.insert(song_widget, -1) song.song_widget = song_widget @log def set_selection_mode(self, selection_mode): """Set selection mode :param bool selection_mode: Allow selection mode """ self._selection_mode = selection_mode self._disc_songs_flowbox.foreach(self._toggle_widget_selection) @log def get_selected_items(self): """Return all selected items :returns: The selected items: :rtype: A list if Grilo media items """ self._selected_items = [] self._disc_songs_flowbox.foreach(self._get_selected) return self._selected_items @log def _get_selected(self, child): song_widget = child.get_child() if song_widget.check_button.get_active(): itr = song_widget.itr self._selected_items.append(self._model[itr][5]) # FIXME: select all/none slow probably b/c of the row changes # invocations, maybe workaround? @log def select_all(self): """Select all songs""" def child_select_all(child): song_widget = child.get_child() self._model[song_widget.itr][6] = True self._disc_songs_flowbox.foreach(child_select_all) @log def select_none(self): """Deselect all songs""" def child_select_none(child): song_widget = child.get_child() self._model[song_widget.itr][6] = False self._disc_songs_flowbox.foreach(child_select_none) @log def _create_song_widget(self, song): """Helper function to create a song widget for a single song :param song: A Grilo media item :returns: A complete song widget :rtype: Gtk.EventBox """ builder = Gtk.Builder() builder.add_from_resource('/org/gnome/Music/TrackWidget.ui') song_widget = builder.get_object('eventbox1') self._songs.append(song_widget) title = utils.get_media_title(song) itr = self._model.append(None) self._model[itr][0, 1, 2, 5, 6] = [title, '', '', song, False] song_widget.itr = itr song_widget.model = self._model song_number = song.get_track_number() if song_number == 0: song_number = "" song_widget.number = builder.get_object('num') song_widget.number.set_markup( '<span color=\'grey\'>{}</span>'.format(song_number)) song_widget.number.set_no_show_all(True) song_widget.title = builder.get_object('title') song_widget.title.set_text(title) song_widget.title.set_max_width_chars(50) song_widget.duration = builder.get_object('duration') time = utils.seconds_to_string(song.get_duration()) song_widget.duration.set_text(time) song_widget.check_button = builder.get_object('select') song_widget.check_button.set_visible(False) song_widget.check_button.connect('toggled', self._check_button_toggled, song_widget) song_widget.now_playing_sign = builder.get_object('image1') song_widget.now_playing_sign.set_from_icon_name( 'media-playback-start-symbolic', Gtk.IconSize.SMALL_TOOLBAR) song_widget.now_playing_sign.set_no_show_all(True) song_widget.can_be_played = True song_widget.connect('button-release-event', self._song_activated) song_widget.star_image = builder.get_object('starimage') song_widget.star_image.set_favorite(song.get_favourite()) song_widget.star_image.set_visible(True) song_widget.starevent = builder.get_object('starevent') song_widget.starevent.connect('button-release-event', self._toggle_favorite, song_widget) song_widget.starevent.connect('enter-notify-event', song_widget.star_image.hover, None) song_widget.starevent.connect('leave-notify-event', song_widget.star_image.unhover, None) return song_widget @log def _toggle_favorite(self, widget, event, song_widget): if event.button == Gdk.BUTTON_PRIMARY: song_widget.star_image.toggle_favorite() # FIXME: ugleh. Should probably be triggered by a # signal. favorite = song_widget.star_image.get_favorite() grilo.set_favorite(self._model[song_widget.itr][5], favorite) self._playlists.update_static_playlist(StaticPlaylists.Favorites) return True @log def _check_button_toggled(self, widget, song_widget): self.emit('selection-changed') return True @log def _toggle_widget_selection(self, child): song_widget = child.get_child() song_widget.check_button.set_visible(self._selection_mode) if self._selection_mode is False: if song_widget.check_button.get_active(): song_widget.check_button.set_active(False) @log def _song_activated(self, widget, event): # FIXME: don't think keys work correctly, if they did ever # even. if (not event.button == Gdk.BUTTON_SECONDARY or (event.button == Gdk.BUTTON_PRIMARY and event.state & Gdk.ModifierType.CONTROL_MASK)): self.emit('song-activated', widget) if self._selection_mode: itr = widget.itr self._model[itr][6] = not self._model[itr][6] else: self.emit('selection-toggle') if self._selection_mode: itr = widget.itr self._model[itr][6] = True return True @log def _model_row_changed(self, model, path, itr): if (not self._selection_mode or not model[itr][5]): return song_widget = model[itr][5].song_widget selected = model[itr][6] if selected != song_widget.check_button.get_active(): song_widget.check_button.set_active(selected) return True