def __popup_menu(self, view, library): model, itr = view.get_selection().get_selected() if itr is None: return songs = list(model[itr][0]) songs = [s for s in songs if isinstance(s, AudioFile)] menu = SongsMenu(library, songs, playlists=False, remove=False, ratings=False) menu.preseparate() def _remove(model, itr): playlist = model[itr][0] dialog = ConfirmRemovePlaylistDialog(self, playlist) if dialog.run() == Gtk.ResponseType.YES: playlist.delete() model.get_model().remove( model.convert_iter_to_child_iter(itr)) rem = MenuItem(_("_Delete"), Icons.EDIT_DELETE) connect_obj(rem, 'activate', _remove, model, itr) menu.prepend(rem) def _rename(path): self._start_rename(path) ren = qltk.MenuItem(_("_Rename"), Icons.EDIT) qltk.add_fake_accel(ren, "F2") connect_obj(ren, 'activate', _rename, model.get_path(itr)) menu.prepend(ren) playlist = model[itr][0] PLAYLIST_HANDLER.populate_menu(menu, library, self, [playlist]) menu.show_all() return view.popup_menu(menu, 0, Gtk.get_current_event_time())
def test_queue(self): self.menu = SongsMenu(self.library, self.songs, plugins=False, playlists=False, queue=True, remove=False, delete=False, edit=False, ratings=False) self.failUnlessEqual(1, len(self.menu)) self.failUnless(self.menu.get_children()[0].props.sensitive) self.songs[0].can_add = False self.menu = SongsMenu(self.library, self.songs, plugins=False, playlists=False, queue=True, remove=False, delete=False, edit=False, ratings=False) self.failUnlessEqual(1, len(self.menu)) self.failIf(self.menu.get_children()[0].props.sensitive)
def test_queue(self): self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=True, devices=False, remove=False, delete=False, edit=False, ) self.failUnlessEqual(1, len(self.menu)) self.failUnless(self.menu.get_children()[0].props.sensitive) self.songs[0].can_add = False self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=True, devices=False, remove=False, delete=False, edit=False, ) self.failUnlessEqual(1, len(self.menu)) self.failIf(self.menu.get_children()[0].props.sensitive)
def test_remove_sensitive(self): self.library.add(self.songs) self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=False, remove=True, delete=False, edit=False, ratings=False) self.failUnlessEqual(len(self.menu), 1) self.failUnless(self.menu.get_children()[0].props.sensitive)
def Menu(self, library): songs = self.get_selected_songs() if not songs: return menu = SongsMenu( library, songs, delete=True, plugins=False, playlists=False) menu.show_all() return menu
def test_devices(self): self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=False, devices=True, remove=False, delete=False, edit=False, ratings=False) from quodlibet import browsers if browsers.media.MediaDevices in browsers.browsers: self.failUnlessEqual(1, len(self.menu)) else: self.failUnlessEqual(0, len(self.menu))
def _get_menu(self, player, library): item = qltk.MenuItem(_(u"_Edit Display…"), Gtk.STOCK_EDIT) item.connect('activate', self._on_edit_display, player) songs = [player.song] if player.song else [] song_menu = SongsMenu(library, songs, remove=False, accels=False, items=[[item]]) song_menu.show_all() return song_menu
def test_remove(self): self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=False, remove=True, delete=False, edit=False, ratings=False, removal_confirmer=self._confirmer) self.failUnlessEqual(1, len(self.menu)) item = self.menu.get_children()[0] self.failIf(item.props.sensitive) item.activate() self.failUnless(self.confirmed, "Should have confirmed song removal")
def _get_menu(self, player, library): item = qltk.MenuItem(_(u"_Edit Display…"), Icons.EDIT) item.connect('activate', self._on_edit_display, player) songs = [player.song] if player.song else [] song_menu = SongsMenu(library, songs, remove=False, delete=True, accels=False, items=[[item]]) song_menu.show_all() return song_menu
def __popup_menu(self, view, library): model, itr = view.get_selection().get_selected() if itr is None: return songs = list(model[itr][0]) songs = filter(lambda s: isinstance(s, AudioFile), songs) menu = SongsMenu(library, songs, playlists=False, remove=False, ratings=False) menu.preseparate() def _remove(model, itr): playlist = model[itr][0] dialog = ConfirmRemovePlaylistDialog(self, playlist) if dialog.run() == Gtk.ResponseType.YES: playlist.delete() model.get_model().remove(model.convert_iter_to_child_iter(itr)) rem = MenuItem(_("_Delete"), Icons.EDIT_DELETE) connect_obj(rem, "activate", _remove, model, itr) menu.prepend(rem) def _rename(path): self.__render.set_property("editable", True) view.set_cursor(path, view.get_columns()[0], start_editing=True) ren = qltk.MenuItem(_("_Rename"), Icons.EDIT) qltk.add_fake_accel(ren, "F2") connect_obj(ren, "activate", _rename, model.get_path(itr)) menu.prepend(ren) playlist = model[itr][0] PLAYLIST_HANDLER.populate_menu(menu, library, self, [playlist]) menu.show_all() return view.popup_menu(menu, 0, Gtk.get_current_event_time())
def test_empty(self): self.menu = SongsMenu(self.library, self.songs, plugins=False, playlists=False, queue=False, remove=False, delete=False, edit=False, ratings=False) self.failUnlessEqual(0, len(self.menu))
def __popup(self, view, library): albums = self.__get_selected_albums() songs = self.__get_songs_from_albums(albums) items = [] if self.__cover_column.get_visible(): num = len(albums) button = MenuItem(ngettext("Reload album _cover", "Reload album _covers", num), Icons.VIEW_REFRESH) button.connect("activate", self.__refresh_album, view) items.append(button) menu = SongsMenu(library, songs, items=[items]) menu.show_all() return view.popup_menu(menu, 0, Gtk.get_current_event_time())
def Menu(self, songs, songlist, library): menu = SongsMenu(library, songs, remove=self.__remove_songs, delete=True, accels=songlist.accelerators, parent=self) i = qltk.MenuItem(_("_Add to Library"), gtk.STOCK_ADD) i.set_sensitive(False) i.connect('activate', self.__add_songs, songs) for song in songs: if song not in self.__glibrary: i.set_sensitive(True) break menu.preseparate() menu.prepend(i) return menu
def Menu(self, songs, songlist, library): menu = SongsMenu(self.__librarian, songs, playlists=False, remove=True, queue=False, devices=False, parent=self) menu.prepend(SeparatorMenuItem()) in_fav = False in_all = False for song in songs: if song in self.__fav_stations: in_fav = True elif song in self.__stations: in_all = True if in_fav and in_all: break button = MenuItem(_("Remove from Favorites"), Gtk.STOCK_REMOVE) button.set_sensitive(in_fav) gobject_weak(button.connect_object, 'activate', self.__remove_fav, songs) menu.prepend(button) button = MenuItem(_("Add to Favorites"), Gtk.STOCK_ADD) button.set_sensitive(in_all) gobject_weak(button.connect_object, 'activate', self.__add_fav, songs) menu.prepend(button) return menu
def Menu(self, songs, songlist, library): menu = SongsMenu( library, songs, accels=songlist.accelerators, parent=self) if len(songs) == 1: item = qltk.MenuItem(_("_Download..."), gtk.STOCK_CONNECT) item.connect('activate', self.__download, songs[0]("~uri")) item.set_sensitive(not songs[0].is_file) else: songs = filter(lambda s: not s.is_file, songs) uris = [song("~uri") for song in songs] item = qltk.MenuItem(_("_Download..."), gtk.STOCK_CONNECT) item.connect('activate', self.__download_many, uris) item.set_sensitive(bool(songs)) menu.preseparate() menu.prepend(item) return menu
def Menu(self, songs, library, items): in_fav = False in_all = False for song in songs: if song in self.__fav_stations: in_fav = True elif song in self.__stations: in_all = True if in_fav and in_all: break iradio_items = [] button = MenuItem(_("Add to Favorites"), Icons.LIST_ADD) button.set_sensitive(in_all) connect_obj(button, 'activate', self.__add_fav, songs) iradio_items.append(button) button = MenuItem(_("Remove from Favorites"), Icons.LIST_REMOVE) button.set_sensitive(in_fav) connect_obj(button, 'activate', self.__remove_fav, songs) iradio_items.append(button) items.append(iradio_items) menu = SongsMenu(self.__librarian, songs, playlists=False, remove=True, queue=False, items=items) return menu
def __popup(self, view, library): albums = self.__get_selected_albums() songs = self.__get_songs_from_albums(albums) items = [] if self.__cover_column.get_visible(): num = len(albums) button = MenuItem( ngettext("Reload album _cover", "Reload album _covers", num), Icons.VIEW_REFRESH) button.connect('activate', self.__refresh_album, view) items.append(button) menu = SongsMenu(library, songs, items=[items]) menu.show_all() return view.popup_menu(menu, 0, Gtk.get_current_event_time())
def test_remove_sensitive(self): self.library.add(self.songs) self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=False, remove=True, delete=False, edit=False, ratings=False) self.failUnlessEqual(1, len(self.menu)) self.failUnless(self.menu.get_children()[0].props.sensitive)
def empty_menu_with(self, plugins=False, playlists=False, queue=False, remove=False, delete=False, edit=False, ratings=False, show_files=False, removal_confirmer=None): return SongsMenu(self.library, self.songs, plugins=plugins, playlists=playlists, queue=queue, remove=remove, delete=delete, edit=edit, ratings=ratings, show_files=show_files, removal_confirmer=removal_confirmer)
def __popup(self, view, library): albums = self.__get_selected_albums() songs = self.__get_songs_from_albums(albums) items = [] num = len(albums) button = MenuItem( ngettext("Reload album _cover", "Reload album _covers", num), Icons.VIEW_REFRESH) button.connect('activate', self.__refresh_album, view) items.append(button) menu = SongsMenu(library, songs, items=[items]) menu.show_all() popup_menu_at_widget(menu, view, Gdk.BUTTON_SECONDARY, Gtk.get_current_event_time())
def Menu(self, songs, songlist, library): menu = SongsMenu(self.__librarian, songs, playlists=False, remove=True, queue=False, accels=songlist.accelerators, devices=False, parent=self) menu.prepend(gtk.SeparatorMenuItem()) in_fav = False in_all = False for song in songs: if song in self.__fav_stations: in_fav = True elif song in self.__stations: in_all = True if in_fav and in_all: break button = MenuItem(_("Remove from Favorites"), gtk.STOCK_REMOVE) button.set_sensitive(in_fav) gobject_weak(button.connect_object, 'activate', self.__remove_fav, songs) menu.prepend(button) button = MenuItem(_("Add to Favorites"), gtk.STOCK_ADD) button.set_sensitive(in_all) gobject_weak(button.connect_object, 'activate', self.__add_fav, songs) menu.prepend(button) return menu
def Menu(self, songs, library, items): model, iter = self.__view.get_selection().get_selected() if iter: device = model[iter][0] delete = device.delete and self.__delete_songs else: delete = False menu = SongsMenu(library, songs, delete=delete, remove=False, items=items) return menu
def test_empty(self): self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=False, devices=False, remove=False, delete=False, edit=False, ) self.failUnlessEqual(0, len(self.menu))
def __popup(self, library): songs = self.get_selected_songs() if not songs: return menu = SongsMenu( library, songs, queue=False, remove=False, delete=False, ratings=False) menu.preseparate() remove = Gtk.ImageMenuItem(Gtk.STOCK_REMOVE, use_stock=True) qltk.add_fake_accel(remove, "Delete") remove.connect('activate', self.__remove) menu.prepend(remove) menu.show_all() return self.popup_menu(menu, 0, Gtk.get_current_event_time())
def __popup(self, widget, library): songs = self.get_selected_songs() if not songs: return menu = SongsMenu( library, songs, queue=False, remove=False, delete=False, ratings=False) menu.preseparate() remove = MenuItem(_("_Remove"), Icons.LIST_REMOVE) qltk.add_fake_accel(remove, "Delete") remove.connect('activate', self.__remove) menu.prepend(remove) menu.show_all() return self.popup_menu(menu, 0, Gtk.get_current_event_time())
def __popup_menu(self, view, library): model, itr = view.get_selection().get_selected() if itr is None: return songs = list(model[itr][0]) songs = [s for s in songs if isinstance(s, AudioFile)] menu = SongsMenu(library, songs, playlists=False, remove=False, ratings=False) menu.preseparate() def _remove(model, itr): playlist = model[itr][0] response = confirm_remove_playlist_dialog_invoke( self, playlist, self.Confirmer) if response: playlist.delete() else: print_d("Playlist removal cancelled through prompt") rem = MenuItem(_("_Delete"), Icons.EDIT_DELETE) connect_obj(rem, 'activate', _remove, model, itr) menu.prepend(rem) def _rename(path): self._start_rename(path) ren = qltk.MenuItem(_("_Rename"), Icons.EDIT) qltk.add_fake_accel(ren, "F2") connect_obj(ren, 'activate', _rename, model.get_path(itr)) menu.prepend(ren) playlist = model[itr][0] PLAYLIST_HANDLER.populate_menu(menu, library, self, [playlist]) menu.show_all() return view.popup_menu(menu, 0, Gtk.get_current_event_time())
def Menu(self, songs, library, items): i = qltk.MenuItem(_("_Add to Library"), Gtk.STOCK_ADD) i.set_sensitive(False) i.connect('activate', self.__add_songs, songs) for song in songs: if song not in self.__glibrary: i.set_sensitive(True) break items.append([i]) menu = SongsMenu(library, songs, remove=self.__remove_songs, delete=True, items=items) return menu
def __popup(self, view, event, library): x = int(event.x) y = int(event.y) current_path = view.get_path_at_pos(x, y) if event.button == Gdk.BUTTON_SECONDARY and current_path: if not view.path_is_selected(current_path): view.unselect_all() view.select_path(current_path) albums = self.__get_selected_albums() songs = self.__get_songs_from_albums(albums) items = [] num = len(albums) button = MenuItem( ngettext("Reload album _cover", "Reload album _covers", num), Icons.VIEW_REFRESH) button.connect('activate', self.__refresh_album, view) items.append(button) menu = SongsMenu(library, songs, items=[items]) menu.show_all() menu.popup(None, None, None, event.button, event.time, Gtk.get_current_event_time())
def Menu(self, songs, library, items): if len(songs) == 1: item = qltk.MenuItem(_(u"_Download…"), Icons.NETWORK_WORKGROUP) item.connect('activate', self.__download, songs[0]("~uri")) item.set_sensitive(not songs[0].is_file) else: uris = [song("~uri") for song in songs if not song.is_file] item = qltk.MenuItem(_(u"_Download…"), Icons.NETWORK_WORKGROUP) item.connect('activate', self.__download_many, uris) item.set_sensitive(bool(uris)) items.append([item]) menu = SongsMenu(library, songs, items=items) return menu
def __popup_menu(self, view, library): model, itr = view.get_selection().get_selected() if itr is None: return songs = list(model[itr][0]) songs = filter(lambda s: isinstance(s, AudioFile), songs) menu = SongsMenu(library, songs, playlists=False, remove=False, ratings=False) menu.preseparate() def _remove(model, itr): playlist = model[itr][0] dialog = ConfirmRemovePlaylistDialog(self, playlist) if dialog.run() == Gtk.ResponseType.YES: playlist.delete() model.get_model().remove(model.convert_iter_to_child_iter(itr)) rem = Gtk.ImageMenuItem(Gtk.STOCK_DELETE, use_stock=True) connect_obj(rem, 'activate', _remove, model, itr) menu.prepend(rem) def _rename(path): self.__render.set_property('editable', True) view.set_cursor(path, view.get_columns()[0], start_editing=True) ren = qltk.MenuItem(_("_Rename"), Gtk.STOCK_EDIT) qltk.add_fake_accel(ren, "F2") connect_obj(ren, 'activate', _rename, model.get_path(itr)) menu.prepend(ren) playlist = model[itr][0] PLAYLIST_HANDLER.populate_menu(menu, library, self, [playlist]) menu.show_all() return view.popup_menu(menu, 0, Gtk.get_current_event_time())
def __popup(self, library): songs = self.get_selected_songs() if not songs: return menu = SongsMenu(library, songs, queue=False, remove=False, delete=False, ratings=False) menu.preseparate() remove = MenuItem(_("_Remove"), Icons.LIST_REMOVE) qltk.add_fake_accel(remove, "Delete") remove.connect("activate", self.__remove) menu.prepend(remove) menu.show_all() return self.popup_menu(menu, 0, Gtk.get_current_event_time())
def __popup(self, library): songs = self.get_selected_songs() if not songs: return menu = SongsMenu( library, songs, queue=False, remove=False, delete=False, parent=self) menu.preseparate() remove = gtk.ImageMenuItem(gtk.STOCK_REMOVE) remove.connect('activate', self.__remove) menu.prepend(remove) menu.show_all() return self.popup_menu(menu, 0, gtk.get_current_event_time())
def __popup(self, view, library): albums = self.__get_selected_albums() songs = self.__get_songs_from_albums(albums) menu = SongsMenu(library, songs, parent=self) if self.__cover_column.get_visible(): num = len(albums) button = MenuItem( ngettext("Reload album _cover", "Reload album _covers", num), Gtk.STOCK_REFRESH) gobject_weak(button.connect, 'activate', self.__refresh_album, view) menu.prepend(SeparatorMenuItem()) menu.prepend(button) menu.show_all() return view.popup_menu(menu, 0, Gtk.get_current_event_time())
def Menu(self, songs, library, items): if len(songs) == 1: item = qltk.MenuItem(_(u"_Download…"), Gtk.STOCK_CONNECT) item.connect('activate', self.__download, songs[0]("~uri")) item.set_sensitive(not songs[0].is_file) else: songs = filter(lambda s: not s.is_file, songs) uris = [song("~uri") for song in songs] item = qltk.MenuItem(_(u"_Download…"), Gtk.STOCK_CONNECT) item.connect('activate', self.__download_many, uris) item.set_sensitive(bool(songs)) items.append([item]) menu = SongsMenu(library, songs, items=items) return menu
def __popup(self, view, library): selection = view.get_selection() albums = self.__get_selected_albums(selection) songs = self.__get_songs_from_albums(albums) menu = SongsMenu(library, songs, parent=self) if self.__cover_column.get_visible(): num = len(albums) button = MenuItem( ngettext("Reload album _cover", "Reload album _covers", num), gtk.STOCK_REFRESH) gobject_weak(button.connect, 'activate', self.__refresh_album, view) menu.prepend(gtk.SeparatorMenuItem()) menu.prepend(button) menu.show_all() return view.popup_menu(menu, 0, gtk.get_current_event_time())
def Menu(self, songs, songlist, library): menu = SongsMenu(library, songs, parent=self) if len(songs) == 1: item = qltk.MenuItem(_("_Download..."), Gtk.STOCK_CONNECT) item.connect('activate', self.__download, songs[0]("~uri")) item.set_sensitive(not songs[0].is_file) else: songs = filter(lambda s: not s.is_file, songs) uris = [song("~uri") for song in songs] item = qltk.MenuItem(_("_Download..."), Gtk.STOCK_CONNECT) item.connect('activate', self.__download_many, uris) item.set_sensitive(bool(songs)) menu.preseparate() menu.prepend(item) return menu
def Menu(self, songs, songlist, library): menu = SongsMenu(library, songs, remove=self.__remove_songs, delete=True, parent=self) i = qltk.MenuItem(_("_Add to Library"), Gtk.STOCK_ADD) i.set_sensitive(False) i.connect('activate', self.__add_songs, songs) for song in songs: if song not in self.__glibrary: i.set_sensitive(True) break menu.preseparate() menu.prepend(i) return menu
class TSongsMenu(TestCase): def _confirmer(self, *args): self.confirmed = True return False def setUp(self): config.init() self.library = SongLibrary() backend = quodlibet.player.init_backend("nullbe") self.device = backend.init(self.library) self.songs = [AudioFile({"title": x}) for x in ["song1", "song2", "song3"]] for song in self.songs: song.sanitize(fsnative(text_type(song["title"]))) self.confirmed = False def test_empty(self): self.menu = self.empty_menu_with() self.failIf(len(self.menu)) def test_simple(self): self.menu = SongsMenu(self.library, self.songs, plugins=False) def test_playlists(self): self.menu = self.empty_menu_with(playlists=True) self.failUnlessEqual(len(self.menu), 1) self.failUnless(self.menu.get_children()[0].props.sensitive) self.songs[0].can_add = False self.menu = self.empty_menu_with(playlists=True) self.failUnlessEqual(len(self.menu), 1) self.failIf(self.menu.get_children()[0].props.sensitive) def test_queue(self): self.menu = self.empty_menu_with(queue=True) self.failUnlessEqual(len(self.menu), 1) self.failUnless(self.menu.get_children()[0].props.sensitive) self.songs[0].can_add = False self.menu = self.empty_menu_with(queue=True) self.failUnlessEqual(len(self.menu), 1) self.failIf(self.menu.get_children()[0].props.sensitive) def test_remove(self): self.menu = self.empty_menu_with(remove=True, removal_confirmer=self._confirmer) self.failUnlessEqual(len(self.menu), 1) item = self.menu.get_children()[0] self.failIf(item.props.sensitive) item.activate() self.failUnless(self.confirmed, "Should have confirmed song removal") def test_remove_sensitive(self): self.library.add(self.songs) self.menu = self.empty_menu_with(remove=True) self.failUnlessEqual(len(self.menu), 1) self.failUnless(self.menu.get_children()[0].props.sensitive) def test_delete(self): self.menu = self.empty_menu_with(delete=True) self.failUnlessEqual(len(self.menu), 1) self.failUnless(self.menu.get_children()[0].props.sensitive) self.songs[0].is_file = False self.menu = self.empty_menu_with(delete=True) self.failIf(self.menu.get_children()[0].props.sensitive) def test_show_files(self): self.menu = self.empty_menu_with(show_files=True) self.failUnlessEqual(len(self.menu), 1) self.failUnless(self.menu.get_children()[0].props.sensitive) item = self.menu.get_children()[0] self.failUnless(item.props.sensitive) def test_show_files_remote_songs(self): self.songs = self.library.songs = [RemoteFile("http://example.com/")] self.menu = self.empty_menu_with(show_files=True) self.failIf(len(self.menu)) def test_show_files_too_many_songs(self): self.songs = self.library.songs = [an_af(i) for i in range(50)] self.menu = self.empty_menu_with(show_files=True) item = self.menu.get_children()[0] self.failIf(item.props.sensitive, msg="Should have disabled show files for 50 files") def empty_menu_with(self, plugins=False, playlists=False, queue=False, remove=False, delete=False, edit=False, ratings=False, show_files=False, removal_confirmer=None): return SongsMenu(self.library, self.songs, plugins=plugins, playlists=playlists, queue=queue, remove=remove, delete=delete, edit=edit, ratings=ratings, show_files=show_files, removal_confirmer=removal_confirmer) def tearDown(self): self.device.destroy() self.library.destroy() try: self.menu.destroy() except AttributeError: pass else: del(self.menu) config.quit()
def __popup_menu(self, view, library): model, iter = view.get_selection().get_selected() device = model[iter][0] if device.is_connected() and not self.__busy: songs = self.__list_songs(device) else: songs = [] menu = SongsMenu(library, songs, playlists=False, devices=False, remove=False, parent=self) menu.preseparate() props = gtk.ImageMenuItem(gtk.STOCK_PROPERTIES) props.connect_object('activate', self.__properties, model[iter][0]) props.set_sensitive(not self.__busy) menu.prepend(props) ren = qltk.MenuItem(_("_Rename"), gtk.STOCK_EDIT) keyval, mod = gtk.accelerator_parse("F2") ren.add_accelerator( 'activate', self.accelerators, keyval, mod, gtk.ACCEL_VISIBLE) def rename(path): self.__render.set_property('editable', True) view.set_cursor(path, view.get_columns()[0], start_editing=True) ren.connect_object('activate', rename, model.get_path(iter)) menu.prepend(ren) menu.preseparate() eject = gtk.ImageMenuItem(_("_Eject")) eject.set_image( gtk.image_new_from_icon_name("media-eject", gtk.ICON_SIZE_MENU)) eject.set_sensitive( not self.__busy and device.eject and device.is_connected()) eject.connect_object('activate', self.__eject, None) menu.prepend(eject) refresh = gtk.ImageMenuItem(gtk.STOCK_REFRESH) refresh.set_sensitive(device.is_connected()) refresh.connect_object('activate', self.__refresh, True) menu.prepend(refresh) menu.show_all() menu.popup(None, None, None, 0, gtk.get_current_event_time()) return True
def main(argv=None): if argv is None: argv = sys_argv import quodlibet config_file = os.path.join(quodlibet.get_user_dir(), "config") quodlibet.init_cli(config_file=config_file) try: # we want basic commands not to import gtk (doubles process time) assert "gi.repository.Gtk" not in sys.modules sys.modules["gi.repository.Gtk"] = None startup_actions, cmds_todo = process_arguments(argv) finally: sys.modules.pop("gi.repository.Gtk", None) quodlibet.init() from quodlibet import app from quodlibet.qltk import add_signal_watch, Icons add_signal_watch(app.quit) import quodlibet.player import quodlibet.library from quodlibet import config from quodlibet import browsers from quodlibet import util app.name = "Quod Libet" app.description = _("Music player and music library manager") app.id = "quodlibet" quodlibet.set_application_info(Icons.QUODLIBET, app.id, app.name) library_path = os.path.join(quodlibet.get_user_dir(), "songs") print_d("Initializing main library (%s)" % ( quodlibet.util.path.unexpand(library_path))) library = quodlibet.library.init(library_path) app.library = library # this assumes that nullbe will always succeed from quodlibet.player import PlayerError wanted_backend = environ.get( "QUODLIBET_BACKEND", config.get("player", "backend")) try: player = quodlibet.player.init_player(wanted_backend, app.librarian) except PlayerError: print_exc() player = quodlibet.player.init_player("nullbe", app.librarian) app.player = player environ["PULSE_PROP_media.role"] = "music" environ["PULSE_PROP_application.icon_name"] = "quodlibet" browsers.init() from quodlibet.qltk.songlist import SongList, get_columns headers = get_columns() SongList.set_all_column_headers(headers) for opt in config.options("header_maps"): val = config.get("header_maps", opt) util.tags.add(opt, val) in_all = ("~filename ~uri ~#lastplayed ~#rating ~#playcount ~#skipcount " "~#added ~#bitrate ~current ~#laststarted ~basename " "~dirname").split() for Kind in browsers.browsers: if Kind.headers is not None: Kind.headers.extend(in_all) Kind.init(library) pm = quodlibet.init_plugins("no-plugins" in startup_actions) if hasattr(player, "init_plugins"): player.init_plugins() from quodlibet.qltk import unity unity.init("quodlibet.desktop", player) from quodlibet.qltk.songsmenu import SongsMenu SongsMenu.init_plugins() from quodlibet.util.cover import CoverManager app.cover_manager = CoverManager() app.cover_manager.init_plugins() from quodlibet.plugins.playlist import PLAYLIST_HANDLER PLAYLIST_HANDLER.init_plugins() from quodlibet.plugins.query import QUERY_HANDLER QUERY_HANDLER.init_plugins() from gi.repository import GLib def exec_commands(*args): for cmd in cmds_todo: try: resp = cmd_registry.run(app, *cmd) except CommandError: pass else: if resp is not None: print_(resp, end="", flush=True) from quodlibet.qltk.quodlibetwindow import QuodLibetWindow, PlayerOptions # Call exec_commands after the window is restored, but make sure # it's after the mainloop has started so everything is set up. app.window = window = QuodLibetWindow( library, player, restore_cb=lambda: GLib.idle_add(exec_commands, priority=GLib.PRIORITY_HIGH)) app.player_options = PlayerOptions(window) from quodlibet.qltk.window import Window from quodlibet.plugins.events import EventPluginHandler from quodlibet.plugins.gui import UserInterfacePluginHandler pm.register_handler(EventPluginHandler(library.librarian, player, app.window.songlist)) pm.register_handler(UserInterfacePluginHandler()) from quodlibet.mmkeys import MMKeysHandler from quodlibet.remote import Remote, RemoteError from quodlibet.commands import registry as cmd_registry, CommandError from quodlibet.qltk.tracker import SongTracker, FSInterface try: from quodlibet.qltk.dbus_ import DBusHandler except ImportError: DBusHandler = lambda player, library: None mmkeys_handler = MMKeysHandler(app) mmkeys_handler.start() current_path = os.path.join(quodlibet.get_user_dir(), "current") fsiface = FSInterface(current_path, player) remote = Remote(app, cmd_registry) try: remote.start() except RemoteError: exit_(1, True) DBusHandler(player, library) tracker = SongTracker(library.librarian, player, window.playlist) from quodlibet.qltk import session session.init("quodlibet") quodlibet.enable_periodic_save(save_library=True) if "start-playing" in startup_actions: player.paused = False if "start-hidden" in startup_actions: Window.prevent_inital_show(True) # restore browser windows from quodlibet.qltk.browser import LibraryBrowser GLib.idle_add(LibraryBrowser.restore, library, player, priority=GLib.PRIORITY_HIGH) def before_quit(): print_d("Saving active browser state") try: app.browser.save() except NotImplementedError: pass print_d("Shutting down player device %r." % player.version_info) player.destroy() quodlibet.run(window, before_quit=before_quit) app.player_options.destroy() quodlibet.finish_first_session(app.id) mmkeys_handler.quit() remote.stop() fsiface.destroy() tracker.destroy() quodlibet.library.save() config.save() print_d("Finished shutdown.")
def Menu(self, songs, library, items): """This method returns a Gtk.Menu, probably a SongsMenu. After this menu is returned the SongList may modify it further. """ return SongsMenu(library, songs, delete=True, items=items)
def __popup_menu(self, view, library): songs = self.__get_selected_songs(sort=True) menu = SongsMenu(library, songs, parent=self) menu.show_all() return view.popup_menu(menu, 0, gtk.get_current_event_time())
def main(argv=None): if argv is None: argv = sys_argv import quodlibet config_file = os.path.join(quodlibet.get_user_dir(), "config") quodlibet.init_cli(config_file=config_file) try: # we want basic commands not to import gtk (doubles process time) assert "gi.repository.Gtk" not in sys.modules sys.modules["gi.repository.Gtk"] = None startup_actions, cmds_todo = process_arguments(argv) finally: sys.modules.pop("gi.repository.Gtk", None) quodlibet.init() from quodlibet import app from quodlibet.qltk import add_signal_watch, Icons add_signal_watch(app.quit) import quodlibet.player import quodlibet.library from quodlibet import config from quodlibet import browsers from quodlibet import util app.name = "Quod Libet" app.id = "quodlibet" quodlibet.set_application_info(Icons.QUODLIBET, app.id, app.name) library_path = os.path.join(quodlibet.get_user_dir(), "songs") print_d("Initializing main library (%s)" % ( quodlibet.util.path.unexpand(library_path))) library = quodlibet.library.init(library_path) app.library = library # this assumes that nullbe will always succeed from quodlibet.player import PlayerError wanted_backend = environ.get( "QUODLIBET_BACKEND", config.get("player", "backend")) try: player = quodlibet.player.init_player(wanted_backend, app.librarian) except PlayerError: print_exc() player = quodlibet.player.init_player("nullbe", app.librarian) app.player = player environ["PULSE_PROP_media.role"] = "music" environ["PULSE_PROP_application.icon_name"] = "quodlibet" browsers.init() from quodlibet.qltk.songlist import SongList, get_columns headers = get_columns() SongList.set_all_column_headers(headers) for opt in config.options("header_maps"): val = config.get("header_maps", opt) util.tags.add(opt, val) in_all = ("~filename ~uri ~#lastplayed ~#rating ~#playcount ~#skipcount " "~#added ~#bitrate ~current ~#laststarted ~basename " "~dirname").split() for Kind in browsers.browsers: if Kind.headers is not None: Kind.headers.extend(in_all) Kind.init(library) pm = quodlibet.init_plugins("no-plugins" in startup_actions) if hasattr(player, "init_plugins"): player.init_plugins() from quodlibet.qltk import unity unity.init("quodlibet.desktop", player) from quodlibet.qltk.songsmenu import SongsMenu SongsMenu.init_plugins() from quodlibet.util.cover import CoverManager app.cover_manager = CoverManager() app.cover_manager.init_plugins() from quodlibet.plugins.playlist import PLAYLIST_HANDLER PLAYLIST_HANDLER.init_plugins() from quodlibet.plugins.query import QUERY_HANDLER QUERY_HANDLER.init_plugins() from gi.repository import GLib def exec_commands(*args): for cmd in cmds_todo: try: resp = cmd_registry.run(app, *cmd) except CommandError: pass else: if resp is not None: print_(resp, end="", flush=True) from quodlibet.qltk.quodlibetwindow import QuodLibetWindow, PlayerOptions # Call exec_commands after the window is restored, but make sure # it's after the mainloop has started so everything is set up. app.window = window = QuodLibetWindow( library, player, restore_cb=lambda: GLib.idle_add(exec_commands, priority=GLib.PRIORITY_HIGH)) app.player_options = PlayerOptions(window) from quodlibet.qltk.window import Window from quodlibet.plugins.events import EventPluginHandler from quodlibet.plugins.gui import UserInterfacePluginHandler pm.register_handler(EventPluginHandler(library.librarian, player, app.window.songlist)) pm.register_handler(UserInterfacePluginHandler()) from quodlibet.mmkeys import MMKeysHandler from quodlibet.remote import Remote, RemoteError from quodlibet.commands import registry as cmd_registry, CommandError from quodlibet.qltk.tracker import SongTracker, FSInterface try: from quodlibet.qltk.dbus_ import DBusHandler except ImportError: DBusHandler = lambda player, library: None mmkeys_handler = MMKeysHandler(app) mmkeys_handler.start() current_path = os.path.join(quodlibet.get_user_dir(), "current") fsiface = FSInterface(current_path, player) remote = Remote(app, cmd_registry) try: remote.start() except RemoteError: exit_(1, True) DBusHandler(player, library) tracker = SongTracker(library.librarian, player, window.playlist) from quodlibet.qltk import session session.init("quodlibet") quodlibet.enable_periodic_save(save_library=True) if "start-playing" in startup_actions: player.paused = False if "start-hidden" in startup_actions: Window.prevent_inital_show(True) # restore browser windows from quodlibet.qltk.browser import LibraryBrowser GLib.idle_add(LibraryBrowser.restore, library, player, priority=GLib.PRIORITY_HIGH) def before_quit(): print_d("Saving active browser state") try: app.browser.save() except NotImplementedError: pass print_d("Shutting down player device %r." % player.version_info) player.destroy() quodlibet.run(window, before_quit=before_quit) app.player_options.destroy() quodlibet.finish_first_session(app.id) mmkeys_handler.quit() remote.stop() fsiface.destroy() tracker.destroy() quodlibet.library.save() config.save() print_d("Finished shutdown.")
def __popup_menu(self, view, library): model, iter = view.get_selection().get_selected() device = model[iter][0] if device.is_connected() and not self.__busy: songs = self.__list_songs(device) else: songs = [] menu = SongsMenu(library, songs, playlists=False, devices=False, remove=False) menu.preseparate() props = Gtk.ImageMenuItem(Gtk.STOCK_PROPERTIES, use_stock=True) connect_obj(props, 'activate', self.__properties, model[iter][0]) props.set_sensitive(not self.__busy) menu.prepend(props) ren = qltk.MenuItem(_("_Rename"), Gtk.STOCK_EDIT) keyval, mod = Gtk.accelerator_parse("F2") ren.add_accelerator( 'activate', self.accelerators, keyval, mod, Gtk.AccelFlags.VISIBLE) def rename(path): self.__render.set_property('editable', True) view.set_cursor(path, view.get_columns()[0], start_editing=True) connect_obj(ren, 'activate', rename, model.get_path(iter)) menu.prepend(ren) menu.preseparate() eject = Gtk.ImageMenuItem(_("_Eject"), use_underline=True) eject.set_image( Gtk.Image.new_from_icon_name("media-eject", Gtk.IconSize.MENU)) eject.set_sensitive( not self.__busy and device.eject and device.is_connected()) connect_obj(eject, 'activate', self.__eject, None) menu.prepend(eject) refresh = Gtk.ImageMenuItem(Gtk.STOCK_REFRESH, use_stock=True) refresh.set_sensitive(device.is_connected()) connect_obj(refresh, 'activate', self.__refresh, True) menu.prepend(refresh) menu.show_all() return view.popup_menu(menu, 0, Gtk.get_current_event_time())
def main(argv): import quodlibet quodlibet.init_cli() try: # we want basic commands not to import gtk (doubles process time) assert "gi.repository.Gtk" not in sys.modules sys.modules["gi.repository.Gtk"] = None startup_actions, cmds_todo = process_arguments(argv) finally: sys.modules.pop("gi.repository.Gtk", None) quodlibet.init() from quodlibet import app from quodlibet.qltk import add_signal_watch, Icons add_signal_watch(app.quit) import quodlibet.player import quodlibet.library from quodlibet import config from quodlibet import browsers from quodlibet import util from quodlibet.util.string import decode app.name = "Quod Libet" app.id = "quodlibet" quodlibet.set_application_info(Icons.QUODLIBET, app.id, app.name) config.init(os.path.join(quodlibet.get_user_dir(), "config")) library_path = os.path.join(quodlibet.get_user_dir(), "songs") print_d("Initializing main library (%s)" % ( quodlibet.util.path.unexpand(library_path))) library = quodlibet.library.init(library_path) app.library = library # this assumes that nullbe will always succeed from quodlibet.player import PlayerError wanted_backend = os.environ.get( "QUODLIBET_BACKEND", config.get("player", "backend")) backend_traceback = None for backend in [wanted_backend, "nullbe"]: try: player = quodlibet.player.init_player(backend, app.librarian) except PlayerError: backend_traceback = decode(traceback.format_exc()) else: break app.player = player os.environ["PULSE_PROP_media.role"] = "music" os.environ["PULSE_PROP_application.icon_name"] = "quodlibet" browsers.init() from quodlibet.qltk.songlist import SongList, get_columns from quodlibet.util.collection import Album try: cover_size = config.getint("browsers", "cover_size") except config.Error: pass else: if cover_size > 0: Album.COVER_SIZE = cover_size headers = get_columns() SongList.set_all_column_headers(headers) for opt in config.options("header_maps"): val = config.get("header_maps", opt) util.tags.add(opt, val) in_all = ("~filename ~uri ~#lastplayed ~#rating ~#playcount ~#skipcount " "~#added ~#bitrate ~current ~#laststarted ~basename " "~dirname").split() for Kind in browsers.browsers: if Kind.headers is not None: Kind.headers.extend(in_all) Kind.init(library) pm = quodlibet.init_plugins("no-plugins" in startup_actions) if hasattr(player, "init_plugins"): player.init_plugins() from quodlibet.qltk import unity unity.init("quodlibet.desktop", player) from quodlibet.qltk.songsmenu import SongsMenu SongsMenu.init_plugins() from quodlibet.util.cover import CoverManager app.cover_manager = CoverManager() app.cover_manager.init_plugins() from quodlibet.plugins.playlist import PLAYLIST_HANDLER PLAYLIST_HANDLER.init_plugins() from gi.repository import GLib def exec_commands(*args): for cmd in cmds_todo: try: resp = cmd_registry.run(app, *cmd) except CommandError: pass else: if resp is not None: print_(resp, end="") from quodlibet.qltk.quodlibetwindow import QuodLibetWindow, PlayerOptions # Call exec_commands after the window is restored, but make sure # it's after the mainloop has started so everything is set up. app.window = window = QuodLibetWindow( library, player, restore_cb=lambda: GLib.idle_add(exec_commands, priority=GLib.PRIORITY_HIGH)) app.player_options = PlayerOptions(window) from quodlibet.qltk.debugwindow import MinExceptionDialog from quodlibet.qltk.window import on_first_map if backend_traceback is not None: def show_backend_error(window): d = MinExceptionDialog(window, _("Audio Backend Failed to Load"), _("Loading the audio backend '%(name)s' failed. " "Audio playback will be disabled.") % {"name": wanted_backend}, backend_traceback) d.run() # so we show the main window first on_first_map(app.window, show_backend_error, app.window) from quodlibet.plugins.events import EventPluginHandler pm.register_handler(EventPluginHandler(library.librarian, player)) from quodlibet.mmkeys import MMKeysHandler from quodlibet.remote import Remote, RemoteError from quodlibet.commands import registry as cmd_registry, CommandError from quodlibet.qltk.tracker import SongTracker, FSInterface try: from quodlibet.qltk.dbus_ import DBusHandler except ImportError: DBusHandler = lambda player, library: None mmkeys_handler = MMKeysHandler(app.name, window, player) if "QUODLIBET_NO_MMKEYS" not in os.environ: mmkeys_handler.start() current_path = os.path.join(quodlibet.get_user_dir(), "current") fsiface = FSInterface(current_path, player) remote = Remote(app, cmd_registry) try: remote.start() except RemoteError: exit_(1, True) DBusHandler(player, library) tracker = SongTracker(library.librarian, player, window.playlist) from quodlibet.qltk import session session.init("quodlibet") quodlibet.enable_periodic_save(save_library=True) if "start-playing" in startup_actions: player.paused = False # restore browser windows from quodlibet.qltk.browser import LibraryBrowser GLib.idle_add(LibraryBrowser.restore, library, player, priority=GLib.PRIORITY_HIGH) def before_quit(): print_d("Saving active browser state") try: app.browser.save() except NotImplementedError: pass print_d("Shutting down player device %r." % player.version_info) player.destroy() quodlibet.main(window, before_quit=before_quit) app.player_options.destroy() quodlibet.finish_first_session(app.id) mmkeys_handler.quit() remote.stop() fsiface.destroy() tracker.destroy() quodlibet.library.save() config.save() print_d("Finished shutdown.")
def __popup_menu(self, view, library): # TODO: Consider allowing plugins to expose themselves in playlist model, itr = view.get_selection().get_selected() if itr is None: return songs = list(model[itr][0]) songs = filter(lambda s: isinstance(s, AudioFile), songs) menu = SongsMenu( library, songs, playlists=False, remove=False, parent=self) menu.preseparate() def _de_duplicate(model, itr): playlist = model[itr][0] unique = set() dupes = list() for s in songs: if s in unique: dupes.append(s) else: unique.add(s) if len(dupes) < 1: print_d("No duplicates in this playlist") return dialog = ConfirmRemoveDuplicatesDialog(self, playlist, len(dupes)) if dialog.run() == gtk.RESPONSE_YES: playlist.remove_songs(dupes, library, True) Playlists.changed(playlist) self.activate() de_dupe = gtk.MenuItem(_("Remove Duplicates")) de_dupe.connect_object('activate', _de_duplicate, model, itr) de_dupe.set_sensitive(not model[itr][0].has_duplicates()) menu.prepend(de_dupe) def _shuffle(model, itr): playlist = model[itr][0] playlist.shuffle() self.activate() shuffle = gtk.MenuItem(_("_Shuffle")) shuffle .connect_object('activate', _shuffle, model, itr) shuffle.set_sensitive(bool(len(model[itr][0]))) menu.prepend(shuffle) menu.prepend(gtk.SeparatorMenuItem()) def _remove(model, itr): playlist = model[itr][0] dialog = ConfirmRemovePlaylistDialog(self, playlist) if dialog.run() == gtk.RESPONSE_YES: playlist.delete() model.get_model().remove( model.convert_iter_to_child_iter(None, itr)) rem = gtk.ImageMenuItem(gtk.STOCK_DELETE) rem.connect_object('activate', _remove, model, itr) menu.prepend(rem) def _rename(path): self.__render.set_property('editable', True) view.set_cursor(path, view.get_columns()[0], start_editing=True) ren = qltk.MenuItem(_("_Rename"), gtk.STOCK_EDIT) keyval, mod = gtk.accelerator_parse("F2") ren.add_accelerator( 'activate', self.accelerators, keyval, mod, gtk.ACCEL_VISIBLE) ren.connect_object('activate', _rename, model.get_path(itr)) menu.prepend(ren) menu.show_all() return view.popup_menu(menu, 0, gtk.get_current_event_time())
def Menu(self, songs, library, items): return SongsMenu(library, songs, download=True, items=items)
class TSongsMenu(TestCase): def _confirmer(self, *args): self.confirmed = True return False def setUp(self): config.init() self.library = SongFileLibrary() backend = quodlibet.player.init_backend("nullbe") self.device = backend.init(self.library) self.songs = [AudioFile({"title": x}) for x in ["song1", "song2", "song3"]] for song in self.songs: song.sanitize(fsnative(str(song["title"]))) self.confirmed = False def test_empty(self): self.menu = self.empty_menu_with() self.failIf(len(self.menu)) def test_simple(self): self.menu = SongsMenu(self.library, self.songs, plugins=False) def test_playlists(self): self.menu = self.empty_menu_with(playlists=True) self.failUnlessEqual(len(self.menu), 1) self.failUnless(self.menu.get_children()[0].props.sensitive) self.songs[0].can_add = False self.menu = self.empty_menu_with(playlists=True) self.failUnlessEqual(len(self.menu), 1) self.failIf(self.menu.get_children()[0].props.sensitive) def test_queue(self): self.menu = self.empty_menu_with(queue=True) self.failUnlessEqual(len(self.menu), 1) self.failUnless(self.menu.get_children()[0].props.sensitive) self.songs[0].can_add = False self.menu = self.empty_menu_with(queue=True) self.failUnlessEqual(len(self.menu), 1) self.failIf(self.menu.get_children()[0].props.sensitive) def test_remove(self): self.menu = self.empty_menu_with(remove=True, removal_confirmer=self._confirmer) self.failUnlessEqual(len(self.menu), 1) item = self.menu.get_children()[0] self.failIf(item.props.sensitive) item.activate() self.failUnless(self.confirmed, "Should have confirmed song removal") def test_remove_sensitive(self): self.library.add(self.songs) self.menu = self.empty_menu_with(remove=True) self.failUnlessEqual(len(self.menu), 1) self.failUnless(self.menu.get_children()[0].props.sensitive) def test_delete(self): self.menu = self.empty_menu_with(delete=True) self.failUnlessEqual(len(self.menu), 1) self.failUnless(self.menu.get_children()[0].props.sensitive) self.songs[0].is_file = False self.menu = self.empty_menu_with(delete=True) self.failIf(self.menu.get_children()[0].props.sensitive) def test_show_files(self): self.menu = self.empty_menu_with(show_files=True) self.failUnlessEqual(len(self.menu), 1) self.failUnless(self.menu.get_children()[0].props.sensitive) item = self.menu.get_children()[0] self.failUnless(item.props.sensitive) def test_show_files_remote_songs(self): self.songs = self.library.songs = [an_rf(1)] self.menu = self.empty_menu_with(show_files=True) self.failIf(len(self.menu)) def test_show_files_too_many_songs(self): self.songs = self.library.songs = [an_af(i) for i in range(50)] self.menu = self.empty_menu_with(show_files=True) item = self.menu.get_children()[0] self.failIf(item.props.sensitive, msg="Should have disabled show files for 50 files") def test_download(self): def choose(*args, **kwargs): return [mkdtemp()] self.songs = self.library.songs = [an_rf(i) for i in range(3)] self.menu = self.empty_menu_with(download=True, folder_chooser=choose) last = self.menu.get_children()[-1] assert last.props.sensitive, "should have enabled download for remotes" # TODO: some useful assertions, without needing a UI def empty_menu_with(self, plugins=False, playlists=False, queue=False, remove=False, delete=False, edit=False, ratings=False, show_files=False, download=False, removal_confirmer=None, folder_chooser=None): return SongsMenu(self.library, self.songs, plugins=plugins, playlists=playlists, queue=queue, remove=remove, delete=delete, edit=edit, ratings=ratings, show_files=show_files, removal_confirmer=removal_confirmer, download=download, folder_chooser=folder_chooser) def tearDown(self): self.device.destroy() self.library.destroy() try: self.menu.destroy() except AttributeError: pass else: del(self.menu) config.quit()
def test_simple(self): self.menu = SongsMenu(self.library, self.songs, plugins=False)
class TSongsMenu(TestCase): def setUp(self): config.init() self.library = SongLibrary() backend = quodlibet.player.init_backend("nullbe") self.device = backend.init(self.library) self.songs = [AudioFile({"title": x}) for x in ["song1", "song2", "song3"]] for song in self.songs: song.sanitize(fsnative(text_type(song["title"]))) def test_empty(self): self.menu = SongsMenu(self.library, self.songs, plugins=False, playlists=False, queue=False, remove=False, delete=False, edit=False, ratings=False) self.failUnlessEqual(0, len(self.menu)) def test_simple(self): self.menu = SongsMenu(self.library, self.songs, plugins=False) def test_playlists(self): self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=True, queue=False, remove=False, delete=False, edit=False, ratings=False) self.failUnlessEqual(1, len(self.menu)) self.failUnless(self.menu.get_children()[0].props.sensitive) self.songs[0].can_add = False self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=True, queue=False, remove=False, delete=False, edit=False, ratings=False) self.failUnlessEqual(1, len(self.menu)) self.failIf(self.menu.get_children()[0].props.sensitive) def test_queue(self): self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=True, remove=False, delete=False, edit=False, ratings=False) self.failUnlessEqual(1, len(self.menu)) self.failUnless(self.menu.get_children()[0].props.sensitive) self.songs[0].can_add = False self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=True, remove=False, delete=False, edit=False, ratings=False) self.failUnlessEqual(1, len(self.menu)) self.failIf(self.menu.get_children()[0].props.sensitive) def test_remove(self): self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=False, remove=True, delete=False, edit=False, ratings=False) self.failUnlessEqual(1, len(self.menu)) self.failIf(self.menu.get_children()[0].props.sensitive) def test_remove_sensitive(self): self.library.add(self.songs) self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=False, remove=True, delete=False, edit=False, ratings=False) self.failUnlessEqual(1, len(self.menu)) self.failUnless(self.menu.get_children()[0].props.sensitive) def test_delete(self): self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=False, remove=False, delete=True, edit=False, ratings=False) self.failUnlessEqual(1, len(self.menu)) self.failUnless(self.menu.get_children()[0].props.sensitive) self.songs[0].is_file = False self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=False, remove=False, delete=True, edit=False, ratings=False) self.failUnlessEqual(1, len(self.menu)) self.failIf(self.menu.get_children()[0].props.sensitive) def tearDown(self): self.device.destroy() self.library.destroy() try: self.menu.destroy() except AttributeError: pass else: del(self.menu) config.quit()
util.tags.add(opt, val) in_all =("~filename ~uri ~#lastplayed ~#rating ~#playcount ~#skipcount " "~#added ~#bitrate ~current ~#laststarted ~basename " "~dirname").split() for Kind in browsers.browsers: if Kind.headers is not None: Kind.headers.extend(in_all) Kind.init(library) pm = quodlibet.init_plugins(no_plugins) if hasattr(player, "init_plugins"): player.init_plugins() from quodlibet.qltk.songsmenu import SongsMenu SongsMenu.init_plugins() from quodlibet.qltk.quodlibetwindow import QuodLibetWindow app.window = window = QuodLibetWindow(library, player) from quodlibet.plugins.events import EventPluginHandler pm.register_handler(EventPluginHandler(library.librarian, player)) from quodlibet.qltk import mmkeys_ as mmkeys from quodlibet.qltk.remote import FSInterface, FIFOControl from quodlibet.qltk.tracker import SongTracker try: from quodlibet.qltk.dbus_ import DBusHandler except ImportError: DBusHandler = lambda player, library: None
def main(): try: # we want basic commands not to import gtk (doubles process time) assert "gi.repository.Gtk" not in sys.modules sys.modules["gi.repository.Gtk"] = None startup_actions = process_arguments() # this will exit if it succeeds control('focus', ignore_error=True) finally: sys.modules.pop("gi.repository.Gtk", None) import quodlibet from quodlibet import app from quodlibet.qltk import add_signal_watch, icons add_signal_watch(app.quit) import quodlibet.player import quodlibet.library from quodlibet import config from quodlibet import browsers from quodlibet import const from quodlibet import util config.init(const.CONFIG) app.name = "Quod Libet" app.id = "quodlibet" quodlibet.init(icon=icons.QUODLIBET, name=app.name, proc_title=app.id) print_d("Initializing main library (%s)" % ( quodlibet.util.path.unexpand(const.LIBRARY))) library = quodlibet.library.init(const.LIBRARY) app.library = library from quodlibet.player import PlayerError # this assumes that nullbe will always succeed for backend in [config.get("player", "backend"), "nullbe"]: try: player = quodlibet.init_backend(backend, app.librarian) except PlayerError as error: print_e("%s. %s" % (error.short_desc, error.long_desc)) else: break app.player = player os.environ["PULSE_PROP_media.role"] = "music" os.environ["PULSE_PROP_application.icon_name"] = "quodlibet" browsers.init() from quodlibet.qltk.songlist import SongList, get_columns from quodlibet.util.collection import Album try: cover_size = config.getint("browsers", "cover_size") except config.Error: pass else: if cover_size > 0: Album.COVER_SIZE = cover_size headers = get_columns() SongList.set_all_column_headers(headers) for opt in config.options("header_maps"): val = config.get("header_maps", opt) util.tags.add(opt, val) in_all = ("~filename ~uri ~#lastplayed ~#rating ~#playcount ~#skipcount " "~#added ~#bitrate ~current ~#laststarted ~basename " "~dirname").split() for Kind in browsers.browsers: if Kind.headers is not None: Kind.headers.extend(in_all) Kind.init(library) pm = quodlibet.init_plugins("no-plugins" in startup_actions) if hasattr(player, "init_plugins"): player.init_plugins() from quodlibet.qltk import unity unity.init("quodlibet.desktop", player) from quodlibet.qltk.songsmenu import SongsMenu SongsMenu.init_plugins() from quodlibet.util.cover import CoverManager app.cover_manager = CoverManager() app.cover_manager.init_plugins() from quodlibet.plugins.playlist import PLAYLIST_HANDLER PLAYLIST_HANDLER.init_plugins() from quodlibet.qltk.quodlibetwindow import QuodLibetWindow app.window = window = QuodLibetWindow(library, player) from quodlibet.plugins.events import EventPluginHandler pm.register_handler(EventPluginHandler(library.librarian, player)) from quodlibet.mmkeys import MMKeysHandler from quodlibet.remote import Remote from quodlibet.commands import registry as cmd_registry from quodlibet.qltk.tracker import SongTracker, FSInterface try: from quodlibet.qltk.dbus_ import DBusHandler except ImportError: DBusHandler = lambda player, library: None mmkeys_handler = MMKeysHandler(app.name, window, player) if "QUODLIBET_NO_MMKEYS" not in os.environ: mmkeys_handler.start() fsiface = FSInterface(player) remote = Remote(app, cmd_registry) remote.start() DBusHandler(player, library) tracker = SongTracker(library.librarian, player, window.playlist) from quodlibet.qltk import session session.init("quodlibet") quodlibet.enable_periodic_save(save_library=True) if "start-playing" in startup_actions: player.paused = False # restore browser windows from quodlibet.qltk.browser import LibraryBrowser from gi.repository import GLib GLib.idle_add(LibraryBrowser.restore, library, player, priority=GLib.PRIORITY_HIGH) def before_quit(): print_d("Saving active browser state") try: app.browser.save() except NotImplementedError: pass quodlibet.main(window, before_quit=before_quit) quodlibet.finish_first_session(app.id) mmkeys_handler.quit() remote.stop() fsiface.destroy() print_d("Shutting down player device %r." % player.version_info) player.destroy() tracker.destroy() quodlibet.library.save(force=True) config.save(const.CONFIG) print_d("Finished shutdown.")
def __popup(self, view, library): songs = self.__get_selected_songs(view.get_selection()) menu = SongsMenu(library, songs) menu.show_all() return view.popup_menu(menu, 0, Gtk.get_current_event_time())
class TSongsMenu(TestCase): def setUp(self): self.library = SongLibrary() quodlibet.player.init("nullbe") self.device = quodlibet.player.init_device(self.library) self.songs = [AudioFile({"title": x}) for x in ["song1", "song2", "song3"]] for song in self.songs: song.sanitize(song["title"]) def test_empty(self): self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=False, devices=False, remove=False, delete=False, edit=False, ) self.failUnlessEqual(0, len(self.menu)) def test_simple(self): self.menu = SongsMenu(self.library, self.songs, plugins=False) def test_playlists(self): self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=True, queue=False, devices=False, remove=False, delete=False, edit=False, ) self.failUnlessEqual(1, len(self.menu)) self.failUnless(self.menu.get_children()[0].props.sensitive) self.songs[0].can_add = False self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=True, queue=False, devices=False, remove=False, delete=False, edit=False, ) self.failUnlessEqual(1, len(self.menu)) self.failIf(self.menu.get_children()[0].props.sensitive) def test_queue(self): self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=True, devices=False, remove=False, delete=False, edit=False, ) self.failUnlessEqual(1, len(self.menu)) self.failUnless(self.menu.get_children()[0].props.sensitive) self.songs[0].can_add = False self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=True, devices=False, remove=False, delete=False, edit=False, ) self.failUnlessEqual(1, len(self.menu)) self.failIf(self.menu.get_children()[0].props.sensitive) def test_devices(self): self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=False, devices=True, remove=False, delete=False, edit=False, ) from quodlibet import browsers if browsers.media.MediaDevices in browsers.browsers: self.failUnlessEqual(1, len(self.menu)) else: self.failUnlessEqual(0, len(self.menu)) def test_remove(self): self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=False, devices=False, remove=True, delete=False, edit=False, ) self.failUnlessEqual(1, len(self.menu)) self.failIf(self.menu.get_children()[0].props.sensitive) def test_remove_sensitive(self): self.library.add(self.songs) self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=False, devices=False, remove=True, delete=False, edit=False, ) self.failUnlessEqual(1, len(self.menu)) self.failUnless(self.menu.get_children()[0].props.sensitive) def test_delete(self): self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=False, devices=False, remove=False, delete=True, edit=False, ) self.failUnlessEqual(1, len(self.menu)) self.failUnless(self.menu.get_children()[0].props.sensitive) self.songs[0].is_file = False self.menu = SongsMenu( self.library, self.songs, plugins=False, playlists=False, queue=False, devices=False, remove=False, delete=True, edit=False, ) self.failUnlessEqual(1, len(self.menu)) self.failIf(self.menu.get_children()[0].props.sensitive) def tearDown(self): quodlibet.player.quit(self.device) self.library.destroy() try: self.menu.destroy() except AttributeError: pass else: del (self.menu)