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 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, 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 _create_menu(self): menu = Gtk.Menu() m = qltk.MenuItem(_(u"_New Folder…"), Icons.DOCUMENT_NEW) m.connect('activate', self.__mkdir) menu.append(m) m = qltk.MenuItem(_("_Delete"), Icons.EDIT_DELETE) m.connect('activate', self.__rmdir) menu.append(m) m = qltk.MenuItem(_("_Refresh"), Icons.VIEW_REFRESH) m.connect('activate', self.__refresh) menu.append(m) m = qltk.MenuItem(_("_Select all Sub-Folders"), Icons.FOLDER) m.connect('activate', self.__expand) menu.append(m) menu.show_all() return menu
def __map(self, menu, songs): for song in songs: marks = song.bookmarks if marks: fake_player = self.FakePlayer(song) song_item = Gtk.MenuItem(song.comma("title")) song_menu = Gtk.Menu() song_item.set_submenu(song_menu) menu.append(song_item) items = qltk.bookmarks.MenuItems(marks, fake_player, True) for item in items: song_menu.append(item) song_menu.append(SeparatorMenuItem()) i = qltk.MenuItem(_(u"_Edit Bookmarks…"), Icons.EDIT) def edit_bookmarks_cb(menu_item): window = EditBookmarks(self.plugin_window, app.library, fake_player) window.show() i.connect('activate', edit_bookmarks_cb) song_menu.append(i) if menu.get_active() is None: no_marks = Gtk.MenuItem(_("No Bookmarks")) no_marks.set_sensitive(False) menu.append(no_marks) menu.show_all()
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 Filter(t): # Translators: The substituted string is the name of the # selected column (a translated tag name). b = qltk.MenuItem( _("_Filter on %s") % util.tag(t, True), Icons.EDIT_FIND) b.connect('activate', self.__filter_on, t, songs, browser) return b
def __init__(self, app): super().__init__() player = app.player play_item = MenuItem(_("_Play"), Icons.MEDIA_PLAYBACK_START) play_item.connect("activate", self._on_play, player) pause_item = MenuItem(_("P_ause"), Icons.MEDIA_PLAYBACK_PAUSE) pause_item.connect("activate", self._on_pause, player) self.append(play_item) self.append(pause_item) previous = MenuItem(_("Pre_vious"), Icons.MEDIA_SKIP_BACKWARD) previous.connect('activate', lambda *args: player.previous()) self.append(previous) next_ = MenuItem(_("_Next"), Icons.MEDIA_SKIP_FORWARD) next_.connect('activate', lambda *args: player.next()) self.append(next_) browse = qltk.MenuItem(_("_Browse Library"), Icons.EDIT_FIND) browse_sub = Gtk.Menu() for Kind in browsers.browsers: i = Gtk.MenuItem(label=Kind.accelerated_name, use_underline=True) connect_obj(i, 'activate', LibraryBrowser.open, Kind, app.library, app.player) browse_sub.append(i) browse.set_submenu(browse_sub) self.append(SeparatorMenuItem()) self.append(browse) self.show_all() self.hide()
def Menu(self, songs, library, items): model, iters = self.__get_selected_songs() remove = qltk.MenuItem(_("_Remove from Playlist"), Icons.LIST_REMOVE) qltk.add_fake_accel(remove, "Delete") connect_obj(remove, 'activate', self.__remove_songs, iters, model) playlist_iter = self.__selected_playlists()[1] remove.set_sensitive(bool(playlist_iter)) items.append([remove]) menu = super().Menu(songs, library, items) return menu
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 test__on_new_playlist_activate(self): main = qltk.MenuItem('Menu') menu = StubbedPlaylistMenu(self.SONGS, PlaylistLibrary(SongFileLibrary())) main.set_submenu(menu) pl = menu._on_new_playlist_activate(main, self.SONGS) self.failUnless(pl, msg="No playlists added") self.failUnlessEqual(pl.songs, self.SONGS)
def Menu(self, songs, songlist, library): menu = super(PlaylistsBrowser, self).Menu(songs, songlist, library) model, rows = songlist.get_selection().get_selected_rows() iters = map(model.get_iter, rows) i = qltk.MenuItem(_("_Remove from Playlist"), Gtk.STOCK_REMOVE) i.connect_object('activate', self.__remove, iters, model) i.set_sensitive(bool(self.__view.get_selection().get_selected()[1])) menu.preseparate() menu.prepend(i) return menu
def test__on_new_playlist_activate(self): main = qltk.MenuItem('Menu') menu = StubbedPlaylistMenu(self.SONGS, PlaylistLibrary(SongFileLibrary())) main.set_submenu(menu) # Run it (with stubbed dialog) pl = menu._on_new_playlist_activate(main, self.SONGS) assert pl, "No playlists added" assert pl.name == FIXED_NAME, "Wrong name used" assert pl.songs == self.SONGS
def Menu(self, songs, library, items): songlist = qltk.get_top_parent(self).songlist model, iters = self.__get_selected_songs(songlist) item = qltk.MenuItem(_("_Remove from Playlist"), Gtk.STOCK_REMOVE) qltk.add_fake_accel(item, "Delete") connect_obj(item, 'activate', self.__remove, iters, model) item.set_sensitive(bool(self.__view.get_selection().get_selected()[1])) items.append([item]) menu = super(PlaylistsBrowser, self).Menu(songs, library, items) return menu
def test__on_new_playlist_activate(self): main = qltk.MenuItem('Menu') menu = StubbedPlaylistMenu(self.SONGS, [], self.lib) menu.connect('new', self._on_new) main.set_submenu(menu) menu._on_new_playlist_activate(main, self.SONGS) self.failUnless(self.added, msg="No playlists signalled") self.failUnlessEqual(self.added[0].songs, self.SONGS) self.added[0].delete()
def __init__(self, player, library): hbox = Gtk.HBox(spacing=3) l = TimeLabel() self._time_label = l hbox.pack_start(l, True, True, 0) arrow = Gtk.Arrow.new(Gtk.ArrowType.RIGHT, Gtk.ShadowType.NONE) hbox.pack_start(arrow, False, True, 0) super(SeekButton, self).__init__(hbox) self._slider_label = TimeLabel() self.set_slider_widget(self._slider_label) self._on_seekable_changed(player) connect_destroy(player, "notify::seekable", self._on_seekable_changed) self.scale.connect('button-press-event', self.__seek_lock) self.scale.connect('button-release-event', self.__seek_unlock, player) self.scale.connect('key-press-event', self.__seek_lock) self.scale.connect('key-release-event', self.__seek_unlock, player) self.connect('scroll-event', self.__scroll, player) self.scale.connect('value-changed', self.__update_time, l) m = Gtk.Menu() c = ConfigCheckMenuItem( _("Display remaining time"), "player", "time_remaining") c.set_active(config.getboolean("player", "time_remaining")) connect_obj(c, 'toggled', self.scale.emit, 'value-changed') self.__remaining = c m.append(c) m.append(SeparatorMenuItem()) i = qltk.MenuItem(_(u"_Edit Bookmarks…"), Icons.EDIT) def edit_bookmarks_cb(menu_item): window = bookmarks.EditBookmarks(self, library, player) window.show() i.connect('activate', edit_bookmarks_cb) m.append(i) m.show_all() connect_obj(self, 'button-press-event', self.__check_menu, m, player, c) connect_obj(self, 'popup-menu', self.__popup_menu, m, player) timer = TimeTracker(player) connect_obj(timer, 'tick', self.__check_time, player) connect_destroy( library, "changed", self.__songs_changed, player, m) connect_destroy(player, 'song-started', self.__song_started, m) connect_destroy(player, 'seek', self.__seeked)
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, use_stock=True) 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.AccelFlags.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"), 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()) eject.connect_object('activate', self.__eject, None) menu.prepend(eject) refresh = Gtk.ImageMenuItem(Gtk.STOCK_REFRESH, use_stock=True) refresh.set_sensitive(device.is_connected()) refresh.connect_object('activate', self.__refresh, True) menu.prepend(refresh) 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 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
def __init__(self, player, library): hbox = Gtk.HBox(spacing=3) l = TimeLabel() hbox.pack_start(l, True, True, 0) arrow = Gtk.Arrow(Gtk.ArrowType.RIGHT, Gtk.ShadowType.NONE) hbox.pack_start(arrow, False, True, 0) super(SeekBar, self).__init__(hbox) self.scale.connect('button-press-event', self.__seek_lock) self.scale.connect('button-release-event', self.__seek_unlock, player) self.scale.connect('key-press-event', self.__seek_lock) self.scale.connect('key-release-event', self.__seek_unlock, player) self.connect('scroll-event', self.__scroll, player) self.scale.connect('value-changed', self.__update_time, l) m = Gtk.Menu() c = ConfigCheckMenuItem(_("Display remaining time"), "player", "time_remaining") c.set_active(config.getboolean("player", "time_remaining")) c.connect_object('toggled', self.scale.emit, 'value-changed') self.__remaining = c m.append(c) m.append(SeparatorMenuItem()) i = qltk.MenuItem(_("_Edit Bookmarks..."), Gtk.STOCK_EDIT) def edit_bookmarks_cb(menu_item): window = bookmarks.EditBookmarks(self, library, player) window.show() i.connect('activate', edit_bookmarks_cb) m.append(i) m.show_all() self.connect_object('button-press-event', self.__check_menu, m, player, c) self.connect_object('popup-menu', self.__popup_menu, m, player) timer = TimeTracker(player) timer.connect_object('tick', self.__check_time, player) player.connect('song-started', self.__song_changed, l, m) player.connect('seek', self.__seeked)
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 __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 __init__(self, library, song, close=False): super(EditBookmarksPane, self).__init__(spacing=6) hb = Gtk.HBox(spacing=12) self.time = time = Gtk.Entry() time.set_width_chars(5) self.markname = name = Gtk.Entry() add = qltk.Button(_("_Add"), Icons.LIST_ADD, Gtk.IconSize.MENU) hb.pack_start(time, False, True, 0) hb.pack_start(name, True, True, 0) hb.pack_start(add, False, True, 0) self.pack_start(hb, False, True, 0) model = Gtk.ListStore(int, str) sw = Gtk.ScrolledWindow() sw.set_shadow_type(Gtk.ShadowType.IN) sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) sw.add(RCMHintedTreeView(model=model)) render = Gtk.CellRendererText() def cdf(column, cell, model, iter, data): if model[iter][0] < 0: cell.set_property('text', _("N/A")) else: cell.set_property('text', util.format_time(model[iter][0])) render.set_property('editable', True) render.connect('edited', self.__edit_time, model) col = Gtk.TreeViewColumn(_("Time"), render) col.set_cell_data_func(render, cdf, None) sw.get_child().append_column(col) render = Gtk.CellRendererText() render.set_property('ellipsize', Pango.EllipsizeMode.END) col = Gtk.TreeViewColumn(_("Bookmark Name"), render, text=1) render.set_property('editable', True) render.connect('edited', self.__edit_name, model) sw.get_child().append_column(col) self.pack_start(sw, True, True, 0) self.accels = Gtk.AccelGroup() hbox = Gtk.HButtonBox() remove = qltk.Button(_("_Remove"), Icons.LIST_REMOVE) remove.set_sensitive(False) hbox.pack_start(remove, True, True, 0) if close: self.close = qltk.Button(_("_Close"), Icons.WINDOW_CLOSE) hbox.pack_start(self.close, True, True, 0) else: hbox.set_layout(Gtk.ButtonBoxStyle.END) self.pack_start(hbox, False, True, 0) connect_obj(add, 'clicked', self.__add, model, time, name) model.set_sort_column_id(0, Gtk.SortType.ASCENDING) model.connect('row-changed', self._set_bookmarks, library, song) model.connect('row-inserted', self._set_bookmarks, library, song) selection = sw.get_child().get_selection() selection.set_mode(Gtk.SelectionMode.MULTIPLE) selection.connect('changed', self.__check_selection, remove) remove.connect('clicked', self.__remove, selection, library, song) connect_obj(time, 'changed', self.__check_entry, add, time, name) connect_obj(name, 'changed', self.__check_entry, add, time, name) connect_obj(name, 'activate', Gtk.Button.clicked, add) time.set_text(_("MM:SS")) connect_obj(time, 'activate', Gtk.Entry.grab_focus, name) name.set_text(_("Bookmark Name")) menu = Gtk.Menu() remove = qltk.MenuItem(_("_Remove"), Icons.LIST_REMOVE) remove.connect('activate', self.__remove, selection, library, song) keyval, mod = Gtk.accelerator_parse("Delete") remove.add_accelerator( 'activate', self.accels, keyval, mod, Gtk.AccelFlags.VISIBLE) menu.append(remove) menu.show_all() sw.get_child().connect('popup-menu', self.__popup, menu) sw.get_child().connect('key-press-event', self.__view_key_press, remove) connect_obj(self, 'destroy', Gtk.Menu.destroy, menu) self.__fill(model, song)
def __init__(self, library, songs, plugins=True, playlists=True, queue=True, remove=True, delete=False, edit=True, ratings=True, show_files=True, items=None, accels=True, removal_confirmer=None): super().__init__() # The library may actually be a librarian; if it is, use it, # otherwise find the real librarian. librarian = getattr(library, 'librarian', library) if ratings: ratings_item = RatingsMenuItem(songs, librarian) ratings_item.set_sensitive(bool(songs)) self.append(ratings_item) self.separate() # external item groups for subitems in reversed(items or []): self.separate() for item in subitems: self.append(item) self.separate() if plugins: submenu = self.plugins.Menu(librarian, songs) if submenu is not None: b = qltk.MenuItem(_("_Plugins"), Icons.SYSTEM_RUN) b.set_sensitive(bool(songs)) self.append(b) b.set_submenu(submenu) self.append(SeparatorMenuItem()) in_lib = True can_add = True is_file = True for song in songs: if song not in library: in_lib = False if not song.can_add: can_add = False if not song.is_file: is_file = False if playlists: # Needed here to avoid a circular import; most browsers use # a SongsMenu, but SongsMenu needs access to the playlist # browser for this item. # FIXME: Two things are now importing browsers, so we need # some kind of inversion of control here. from quodlibet.browsers.playlists.menu import PlaylistMenu from quodlibet.browsers.playlists import PlaylistsBrowser try: submenu = PlaylistMenu(songs, PlaylistsBrowser.playlists()) def on_new(widget, playlist): PlaylistsBrowser.changed(playlist) submenu.connect('new', on_new) except AttributeError as e: print_w("Couldn't get Playlists menu: %s" % e) else: b = qltk.MenuItem(_("Play_lists"), Icons.FOLDER_DRAG_ACCEPT) b.set_sensitive(can_add and bool(songs)) b.set_submenu(submenu) self.append(b) if queue: b = qltk.MenuItem(_("Add to _Queue"), Icons.LIST_ADD) def enqueue_cb(item, songs): songs = [s for s in songs if s.can_add] if songs: from quodlibet import app app.window.playlist.enqueue(songs) b.connect('activate', enqueue_cb, songs) if accels: qltk.add_fake_accel(b, "<Primary>Return") self.append(b) b.set_sensitive(can_add and bool(songs)) if remove or delete: self.separate() if remove: self._confirm_song_removal = (removal_confirmer or confirm_song_removal_invoke) b = qltk.MenuItem(_("_Remove from Library…"), Icons.LIST_REMOVE) if callable(remove): b.connect('activate', lambda item: remove(songs)) else: def remove_cb(item, songs, library): parent = get_menu_item_top_parent(item) if self._confirm_song_removal(parent, songs): library.remove(songs) b.connect('activate', remove_cb, songs, library) b.set_sensitive(in_lib and bool(songs)) self.append(b) if delete: if callable(delete): b = qltk.MenuItem(_("_Delete"), Icons.EDIT_DELETE) b.connect('activate', lambda item: delete(songs)) if accels: qltk.add_fake_accel(b, "<Primary>Delete") else: b = TrashMenuItem() if accels: qltk.add_fake_accel(b, "<Primary>Delete") def trash_cb(item): parent = get_menu_item_top_parent(item) trash_songs(parent, songs, librarian) b.connect('activate', trash_cb) b.set_sensitive(is_file and bool(songs)) self.append(b) if edit: self.separate() b = qltk.MenuItem(_("Edit _Tags"), Icons.EDIT) b.set_sensitive(bool(songs)) if accels: qltk.add_fake_accel(b, "<alt>Return") def song_properties_cb(menu_item): parent = get_menu_item_top_parent(menu_item) window = SongProperties(librarian, songs, parent) window.show() b.connect('activate', song_properties_cb) self.append(b) b = qltk.MenuItem(_("_Information"), Icons.DIALOG_INFORMATION) b.set_sensitive(bool(songs)) if accels: qltk.add_fake_accel(b, "<Primary>I") def information_cb(menu_item): parent = get_menu_item_top_parent(menu_item) window = Information(librarian, songs, parent) window.show() b.connect('activate', information_cb) self.append(b) if show_files and any(is_a_file(s) for s in songs): def show_files_cb(menu_item): print_d("Trying to show files...") if not show_songs(songs): parent = get_menu_item_top_parent(menu_item) msg = ErrorMessage( parent, _("Unable to show files"), _("Error showing files, " "or no program available to show them.")) msg.run() self.separate() total = len([s for s in songs if is_a_file(s)]) text = ngettext("_Show in File Manager", "_Show %(total)d Files in File Manager", total) % { "total": total } b = qltk.MenuItem(text, Icons.DOCUMENT_OPEN) b.set_sensitive( bool(songs) and len(songs) < MenuItemPlugin.MAX_INVOCATIONS) b.connect('activate', show_files_cb) self.append(b) def selection_done_cb(menu): menu.destroy() self.connect('selection-done', selection_done_cb)
def __init__(self, initial=None, folders=None): """ initial -- the path to select/scroll to folders -- a list of paths to show in the tree view, None will result in a separator. """ model = ObjectTreeStore() super(DirectoryTree, self).__init__(model=model) if initial is not None: initial = util.fsnative(initial) column = TreeViewColumn(_("Folders")) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) render = Gtk.CellRendererPixbuf() render.set_property('stock_id', Gtk.STOCK_DIRECTORY) column.pack_start(render, False) render = Gtk.CellRendererText() column.pack_start(render, True) def cell_data(column, cell, model, iter_, userdata): value = model.get_value(iter_) if value is not None: text = fsdecode(os.path.basename(value) or value) cell.set_property('text', text) column.set_cell_data_func(render, cell_data) self.append_column(column) self.set_search_equal_func(search_func, True) if folders is None: folders = [] for path in folders: niter = model.append(None, [path]) if path is not None: model.append(niter, ["dummy"]) self.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE) self.connect('test-expand-row', DirectoryTree.__expanded, model) self.set_row_separator_func( lambda model, iter_, data: model.get_value(iter_) is None, None) if initial: self.go_to(initial) menu = Gtk.Menu() m = qltk.MenuItem(_("_New Folder..."), Gtk.STOCK_NEW) m.connect('activate', self.__mkdir) menu.append(m) m = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_DELETE, None) m.connect('activate', self.__rmdir) menu.append(m) m = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_REFRESH, None) m.connect('activate', self.__refresh) menu.append(m) m = qltk.MenuItem(_("_Select All Subfolders"), Gtk.STOCK_DIRECTORY) m.connect('activate', self.__expand) menu.append(m) menu.show_all() self.connect_object('popup-menu', self.__popup_menu, menu)
def __init__(self, library, songs, plugins=True, playlists=True, queue=True, devices=True, remove=True, delete=False, edit=True, parent=None): super(SongsMenu, self).__init__() # The library may actually be a librarian; if it is, use it, # otherwise find the real librarian. librarian = getattr(library, 'librarian', library) if plugins: submenu = self.plugins.Menu(librarian, parent, songs) if submenu is not None: b = qltk.MenuItem(_("_Plugins"), Gtk.STOCK_EXECUTE) self.append(b) b.set_submenu(submenu) self.append(SeparatorMenuItem()) in_lib = True can_add = True is_file = True for song in songs: if song not in library: in_lib = False if not song.can_add: can_add = False if not song.is_file: is_file = False self.separate() if playlists: # Needed here to avoid a circular import; most browsers use # a SongsMenu, but SongsMenu needs access to the playlist # browser for this item. # FIXME: Two things are now importing browsers, so we need # some kind of inversion of control here. from quodlibet.browsers.playlists.menu import PlaylistMenu try: submenu = PlaylistMenu(songs, parent) except AttributeError as e: print_w("Couldn't get Playlists menu: %s" % e) else: b = qltk.MenuItem(_("Play_lists"), Gtk.STOCK_ADD) b.set_sensitive(can_add) b.set_submenu(submenu) self.append(b) if queue: b = qltk.MenuItem(_("Add to _Queue"), Gtk.STOCK_ADD) b.connect('activate', self.__enqueue, songs) qltk.add_fake_accel(b, "<ctrl>Return") self.append(b) b.set_sensitive(can_add) if devices: from quodlibet import browsers try: browsers.media except AttributeError: pass else: if browsers.media.MediaDevices in browsers.browsers: submenu = browsers.media.Menu(songs, library) b = qltk.MenuItem(_("_Copy to Device"), Gtk.STOCK_COPY) b.set_sensitive(can_add and len(submenu) > 0) b.set_submenu(submenu) self.append(b) if remove or delete: self.separate() if remove: b = qltk.MenuItem(_("_Remove from library"), Gtk.STOCK_REMOVE) if callable(remove): b.connect_object('activate', remove, songs) else: b.connect('activate', self.__remove, songs, library) b.set_sensitive(in_lib) self.append(b) if delete: if callable(delete): b = Gtk.ImageMenuItem(Gtk.STOCK_DELETE, use_stock=True) b.connect_object('activate', delete, songs) else: b = TrashMenuItem() b.connect_object('activate', trash_songs, parent, songs, librarian) b.set_sensitive(is_file) self.append(b) if edit: self.separate() b = qltk.MenuItem(_("Edit _Tags"), Gtk.STOCK_PROPERTIES) qltk.add_fake_accel(b, "<alt>Return") def song_properties_cb(menu_item): window = SongProperties(librarian, songs, parent) window.show() b.connect('activate', song_properties_cb) self.append(b) b = Gtk.ImageMenuItem(label=Gtk.STOCK_INFO, use_stock=True) qltk.add_fake_accel(b, "<ctrl>I") def information_cb(menu_item): window = Information(librarian, songs, parent) window.show() b.connect('activate', information_cb) self.append(b) self.connect_object('selection-done', Gtk.Menu.destroy, self)
def __init__(self, title, validator=None): super(_KeyValueEditor, self).__init__() self.set_border_width(12) self.set_title(title) self.set_default_size(self._WIDTH, self._HEIGHT) self.add(Gtk.VBox(spacing=6)) t = Gtk.Table(n_rows=2, n_columns=3) t.set_row_spacings(3) t.set_col_spacing(0, 3) t.set_col_spacing(1, 12) l = Gtk.Label(label=_("_Name:")) name = entry.UndoEntry() l.set_mnemonic_widget(name) l.set_use_underline(True) l.set_alignment(0.0, 0.5) t.attach(l, 0, 1, 0, 1, xoptions=Gtk.AttachOptions.FILL) t.attach(name, 1, 2, 0, 1) l = Gtk.Label(label=_("_Value:")) self.value = entry.ValidatingEntry(validator) l.set_mnemonic_widget(self.value) l.set_use_underline(True) l.set_alignment(0.0, 0.5) t.attach(l, 0, 1, 1, 2, xoptions=Gtk.AttachOptions.FILL) t.attach(self.value, 1, 2, 1, 2) add = qltk.Button(_("_Add"), Icons.LIST_ADD) add.set_sensitive(False) t.attach(add, 2, 3, 1, 2, xoptions=Gtk.AttachOptions.FILL) self.get_child().pack_start(t, False, True, 0) # Set up the model for this widget self.model = Gtk.ListStore(str, str) self.fill_values() view = RCMHintedTreeView(model=self.model) view.set_headers_visible(False) view.set_reorderable(True) view.set_rules_hint(True) render = Gtk.CellRendererText() render.props.ellipsize = Pango.EllipsizeMode.END column = Gtk.TreeViewColumn("", render) column.set_cell_data_func(render, self.__cdf, None) view.append_column(column) sw = Gtk.ScrolledWindow() sw.set_shadow_type(Gtk.ShadowType.IN) sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) sw.add(view) self.get_child().pack_start(sw, True, True, 0) menu = Gtk.Menu() remove = qltk.MenuItem(_("_Remove"), Icons.LIST_REMOVE) connect_obj(remove, 'activate', self.__remove, view) qltk.add_fake_accel(remove, "Delete") menu.append(remove) menu.show_all() bbox = Gtk.HButtonBox() rem_b = qltk.Button(_("_Remove"), Icons.LIST_REMOVE) rem_b.set_sensitive(False) bbox.pack_start(rem_b, True, True, 0) self.use_header_bar() close = qltk.Button(_("_Close"), Icons.WINDOW_CLOSE) if not self.has_close_button(): bbox.pack_start(close, True, True, 0) else: bbox.set_layout(Gtk.ButtonBoxStyle.START) self.get_child().pack_start(bbox, False, True, 0) selection = view.get_selection() connect_obj(name, 'activate', Gtk.Entry.grab_focus, self.value) connect_obj(self.value, 'activate', Gtk.Button.clicked, add) self.value.connect('changed', self.__changed, [add]) connect_obj(add, 'clicked', self.__add, selection, name, self.value, self.model) selection.connect('changed', self.__set_text, name, self.value, rem_b) view.connect('popup-menu', self.__popup, menu) connect_obj(rem_b, 'clicked', self.__remove, view) connect_obj(close, 'clicked', qltk.Window.destroy, self) view.connect('key-press-event', self.__view_key_press) connect_obj(self, 'destroy', Gtk.Menu.destroy, menu) name.grab_focus() self.get_child().show_all()
def __init__(self, library): super(MaskedBox, self).__init__(spacing=6) self.model = model = Gtk.ListStore(object) view = RCMHintedTreeView(model=model) view.set_fixed_height_mode(True) view.set_headers_visible(False) self.view = view menu = Gtk.Menu() unhide_item = qltk.MenuItem(_("Unhide"), Gtk.STOCK_ADD) unhide_item.connect_object('activate', self.__unhide, view, library) menu.append(unhide_item) remove_item = Gtk.ImageMenuItem(label=Gtk.STOCK_REMOVE, use_stock=True) remove_item.connect_object('activate', self.__remove, view, library) menu.append(remove_item) menu.show_all() view.connect('popup-menu', self.__popup, menu) sw = Gtk.ScrolledWindow() sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) sw.set_shadow_type(Gtk.ShadowType.IN) sw.add(view) sw.set_size_request(-1, max(sw.size_request().height, 80)) def cdf(column, cell, model, iter, data): row = model[iter] cell.set_property('text', fsdecode(row[0])) def cdf_count(column, cell, model, iter, data): mount = model[iter][0] song_count = len(library.get_masked(mount)) cell.set_property( 'text', _("%(song_count)d songs") % {"song_count": song_count}) column = Gtk.TreeViewColumn(None) column.set_sizing(Gtk.TreeViewColumnSizing.FIXED) render = Gtk.CellRendererText() render.set_property('ellipsize', Pango.EllipsizeMode.END) column.pack_start(render, True) column.set_cell_data_func(render, cdf) render = Gtk.CellRendererText() render.props.sensitive = False column.pack_start(render, False) column.set_cell_data_func(render, cdf_count) view.append_column(column) unhide = qltk.Button(_("Unhide"), Gtk.STOCK_ADD) unhide.connect_object("clicked", self.__unhide, view, library) remove = Gtk.Button(stock=Gtk.STOCK_REMOVE) selection = view.get_selection() selection.set_mode(Gtk.SelectionMode.MULTIPLE) selection.connect("changed", self.__select_changed, remove, unhide) selection.emit("changed") remove.connect_object("clicked", self.__remove, view, library) vbox = Gtk.VBox(spacing=6) vbox.pack_start(unhide, False, True, 0) vbox.pack_start(remove, False, True, 0) self.pack_start(sw, True, True, 0) self.pack_start(vbox, False, True, 0) for path in library.masked_mount_points: model.append(row=[path]) if not len(model): self.set_sensitive(False) for child in self.get_children(): child.show_all()
def __init__(self, initial=None, folders=None): """ initial -- the path to select/scroll to folders -- a list of paths to show in the tree view, None will result in a separator. """ model = ObjectTreeStore() super(DirectoryTree, self).__init__(model=model) if initial is not None: assert is_fsnative(initial) column = TreeViewColumn(title=_("Folders")) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) render = Gtk.CellRendererPixbuf() render.set_property('icon-name', Icons.FOLDER) render.props.xpad = 3 column.pack_start(render, False) render = Gtk.CellRendererText() if self.supports_hints(): render.set_property('ellipsize', Pango.EllipsizeMode.END) column.pack_start(render, True) def cell_data(column, cell, model, iter_, userdata): value = model.get_value(iter_) if value is not None: text = fsdecode(os.path.basename(value) or value) cell.set_property('text', text) column.set_cell_data_func(render, cell_data) self.append_column(column) self.set_search_equal_func(search_func, True) self.set_search_column(0) if folders is None: folders = [] for path in folders: niter = model.append(None, [path]) if path is not None: assert is_fsnative(path) model.append(niter, ["dummy"]) self.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE) self.connect('test-expand-row', DirectoryTree.__expanded, model) self.set_row_separator_func( lambda model, iter_, data: model.get_value(iter_) is None, None) if initial: self.go_to(initial) menu = Gtk.Menu() m = qltk.MenuItem(_(u"_New Folder…"), Icons.DOCUMENT_NEW) m.connect('activate', self.__mkdir) menu.append(m) m = qltk.MenuItem(_("_Delete"), Icons.EDIT_DELETE) m.connect('activate', self.__rmdir) menu.append(m) m = qltk.MenuItem(_("_Refresh"), Icons.VIEW_REFRESH) m.connect('activate', self.__refresh) menu.append(m) m = qltk.MenuItem(_("_Select all Sub-Folders"), Icons.FOLDER) m.connect('activate', self.__expand) menu.append(m) menu.show_all() connect_obj(self, 'popup-menu', self.__popup_menu, menu) # Allow to drag and drop files from outside targets = [("text/uri-list", 0, 42)] targets = [Gtk.TargetEntry.new(*t) for t in targets] self.drag_dest_set(Gtk.DestDefaults.ALL, targets, Gdk.DragAction.COPY) self.connect('drag-data-received', self.__drag_data_received)
def __init__(self, app, add_show_item=False): super().__init__() self._app = app player = app.player show_item_bottom = is_plasma() if add_show_item: show_item = Gtk.CheckMenuItem.new_with_mnemonic( _("_Show %(application-name)s") % {"application-name": app.name}) def on_toggled(menuitem): if menuitem.get_active(): app.present() else: app.hide() self._toggle_id = show_item.connect("toggled", on_toggled) def on_visible_changed(*args): with show_item.handler_block(self._toggle_id): show_item.set_active(app.window.get_visible()) connect_destroy(app.window, "notify::visible", on_visible_changed) else: show_item = None self._play_item = MenuItem(_("_Play"), Icons.MEDIA_PLAYBACK_START) self._play_item.connect("activate", self._on_play_pause, player) self._play_item.set_no_show_all(True) self._pause_item = MenuItem(_("P_ause"), Icons.MEDIA_PLAYBACK_PAUSE) self._pause_item.connect("activate", self._on_play_pause, player) self._pause_item.set_no_show_all(True) self._action_item = None previous = MenuItem(_("Pre_vious"), Icons.MEDIA_SKIP_BACKWARD) previous.connect('activate', lambda *args: player.previous(force=True)) next = MenuItem(_("_Next"), Icons.MEDIA_SKIP_FORWARD) next.connect('activate', lambda *args: player.next()) player_options = app.player_options shuffle = Gtk.CheckMenuItem(label=_("_Shuffle"), use_underline=True) player_options.bind_property("shuffle", shuffle, "active", GObject.BindingFlags.BIDIRECTIONAL) player_options.notify("shuffle") repeat = Gtk.CheckMenuItem(label=_("_Repeat"), use_underline=True) player_options.bind_property("repeat", repeat, "active", GObject.BindingFlags.BIDIRECTIONAL) player_options.notify("repeat") safter = Gtk.CheckMenuItem(label=_("Stop _After This Song"), use_underline=True) player_options.bind_property("stop-after", safter, "active", GObject.BindingFlags.BIDIRECTIONAL) player_options.notify("stop-after") browse = qltk.MenuItem(_("Open _Browser"), Icons.EDIT_FIND) browse_sub = Gtk.Menu() for Kind in browsers.browsers: i = Gtk.MenuItem(label=Kind.accelerated_name, use_underline=True) connect_obj(i, 'activate', LibraryBrowser.open, Kind, app.library, app.player) browse_sub.append(i) browse.set_submenu(browse_sub) self._props = qltk.MenuItem(_("Edit _Tags"), Icons.EDIT) def on_properties(*args): song = player.song window = SongProperties(app.librarian, [song]) window.show() self._props.connect('activate', on_properties) self._info = MenuItem(_("_Information"), Icons.DIALOG_INFORMATION) self._playlists_item = MenuItem(_("Play_lists"), Icons.FOLDER_DRAG_ACCEPT) self._new_playlist_submenu_for(player.song) def on_information(*args): song = player.song window = Information(app.librarian, [song]) window.show() self._info.connect('activate', on_information) def set_rating(value): song = player.song song["~#rating"] = value app.librarian.changed([song]) self._rating_item = rating = RatingsMenuItem([], app.library) quit = MenuItem(_("_Quit"), Icons.APPLICATION_EXIT) quit.connect('activate', lambda *x: app.quit()) if not show_item_bottom and show_item: self.append(show_item) self.append(SeparatorMenuItem()) self.append(self._play_item) self.append(self._pause_item) self.append(previous) self.append(next) self.append(SeparatorMenuItem()) self.append(shuffle) self.append(repeat) self.append(safter) self.append(SeparatorMenuItem()) self.append(rating) self.append(self._playlists_item) self.append(self._props) self.append(self._info) self.append(SeparatorMenuItem()) self.append(browse) self.append(SeparatorMenuItem()) self.append(quit) if show_item_bottom and show_item: self.append(SeparatorMenuItem()) self.append(show_item) self.show_all() self.set_paused(True) self.set_song(None)