def __menu(self, entry, menu): sep = SeparatorMenuItem() sep.show() menu.prepend(sep) cb = ConfigCheckMenuItem( _("Search after _typing"), 'settings', 'eager_search', populate=True) cb.set_tooltip_text( _("Show search results after the user stops typing.")) cb.show() menu.prepend(cb)
def __popup_menu(self, view, fs): # get all songs for the selection filenames = [ normalize_path(f, canonicalise=True) for f in fs.get_selected_paths() ] maybe_songs = [self.__library.get(f) for f in filenames] songs = [s for s in maybe_songs if s] if songs: menu = self.pm.Menu(self.__library, songs) if menu is None: menu = Gtk.Menu() else: menu.prepend(SeparatorMenuItem()) else: menu = Gtk.Menu() b = TrashMenuItem() b.connect('activate', self.__delete, filenames, fs) menu.prepend(b) def selection_done_cb(menu): menu.destroy() menu.connect('selection-done', selection_done_cb) menu.show_all() return view.popup_menu(menu, 0, Gtk.get_current_event_time())
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, 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 __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 __rebuild_menu(self): def toggled_cb(item, order): if item.get_active(): self.current = order menu = Gtk.Menu() group = None prev_priority = None def ui_sorted(items): return sorted(items, key=lambda k: (k.priority, k.display_name)) for order in ui_sorted(self.__orders): if prev_priority and order.priority > prev_priority: menu.append(SeparatorMenuItem()) prev_priority = order.priority group = RadioMenuItem( label=order.accelerated_name, use_underline=True, group=group) group.set_active(order == self.__current) group.connect("toggled", toggled_cb, order) menu.append(group) menu.show_all() self._menu_button.set_menu(menu)
def __popup_menu(self, view, parent): menu = Gtk.Menu() view.ensure_popup_selection() model, rows = view.get_selection().get_selected_rows() can_change = min([model[path][CANEDIT] for path in rows]) items = [ SplitDisc, SplitTitle, SplitPerformer, SplitArranger, SplitValues, SplitPerformerFromTitle, SplitOriginalArtistFromTitle ] items.extend(self.handler.plugins) items.sort(key=lambda item: (item._order, item.__name__)) if len(rows) == 1: row = model[rows[0]] value = row[VALUE].decode('utf-8') text = util.unescape(value) multi = (value.split("<")[0] != value) for Item in items: if Item.tags and row[TAG] not in Item.tags: continue try: b = Item(row[TAG], text) except: util.print_exc() else: b.connect('activate', self.__menu_activate, view) if (not min( map(self.__songinfo.can_change, b.needs) + [1]) or multi): b.set_sensitive(False) menu.append(b) if menu.get_children(): menu.append(SeparatorMenuItem()) b = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_REMOVE, None) b.connect('activate', self.__remove_tag, view) keyval, mod = Gtk.accelerator_parse("Delete") menu.__accels = Gtk.AccelGroup() b.add_accelerator('activate', menu.__accels, keyval, mod, Gtk.AccelFlags.VISIBLE) menu.append(b) menu.show_all() # Setting the menu itself to be insensitive causes it to not # be dismissed; see #473. for c in menu.get_children(): c.set_sensitive(can_change and c.get_property('sensitive')) menu.connect('selection-done', lambda m: m.destroy()) # XXX: Keep reference self.__menu = menu return view.popup_menu(menu, 3, Gtk.get_current_event_time())
def __popup_menu(self, view, parent): menu = Gtk.Menu() view.ensure_popup_selection() model, rows = view.get_selection().get_selected_rows() can_change = min([model[path][0].canedit for path in rows]) items = [ SplitDisc, SplitTitle, SplitPerformer, SplitArranger, SplitValues, SplitPerformerFromTitle, SplitOriginalArtistFromTitle ] items.extend(self.handler.plugins) items.sort(key=lambda item: (item._order, item.__name__)) if len(rows) == 1: row = model[rows[0]] entry = row[0] comment = entry.value text = comment.text for Item in items: if Item.tags and entry.tag not in Item.tags: continue try: b = Item(entry.tag, text) except: util.print_exc() else: b.connect('activate', self.__menu_activate, view) if (not min( map(self.__songinfo.can_change, b.needs) + [1]) or comment.is_special()): b.set_sensitive(False) menu.append(b) if menu.get_children(): menu.append(SeparatorMenuItem()) b = MenuItem(_("_Remove"), Icons.LIST_REMOVE) b.connect('activate', self.__remove_tag, view) qltk.add_fake_accel(b, "Delete") menu.append(b) menu.show_all() # Setting the menu itself to be insensitive causes it to not # be dismissed; see #473. for c in menu.get_children(): c.set_sensitive(can_change and c.get_property('sensitive')) b.set_sensitive(True) menu.connect('selection-done', lambda m: m.destroy()) # XXX: Keep reference self.__menu = menu return view.popup_menu(menu, 3, Gtk.get_current_event_time())
def Menu(self, library, songs): songs = ListWrapper(songs) attrs = [ 'plugin_song', 'plugin_songs', 'plugin_album', 'plugin_albums' ] if len(songs) == 1: attrs.append('plugin_single_song') last = (songs and songs[-1]) or None for song in songs: if song.album_key != last.album_key: break last = song else: attrs.append('plugin_single_album') items = [] kinds = self.__plugins kinds.sort(key=lambda plugin: plugin.PLUGIN_ID) for Kind in kinds: usable = any(callable(getattr(Kind, s)) for s in attrs) if usable: try: items.append(Kind(songs, library)) except: print_e( "Couldn't initialise song plugin %s. Stack trace:" % Kind) errorhook() items = [i for i in items if i.initialized] if items: menu = Gtk.Menu() for item in items: try: menu.append(item) args = (library, songs) if item.get_submenu(): for subitem in item.get_submenu().get_children(): subitem.connect('activate', self.__on_activate, item, *args) else: item.connect('activate', self.__on_activate, item, *args) except: errorhook() item.destroy() menu.append(SeparatorMenuItem()) prefs = Gtk.MenuItem(label=_("Configure Plugins…")) prefs.connect("activate", lambda _: PluginWindow().show()) menu.append(prefs) else: menu = None return menu
def _on_label_popup(self, label, menu, player, library): song_menu = self._get_menu(player, library) has_selection = label.get_selection_bounds()[0] if not has_selection: for child in menu.get_children(): child.destroy() for item in song_menu: song_menu.remove(item) menu.append(item) else: sub = Gtk.MenuItem.new_with_mnemonic(("Current _Song")) sub.set_submenu(song_menu) sub.set_sensitive(player.song is not None) sub.show_all() sep = SeparatorMenuItem() sep.show() menu.append(sep) menu.append(sub)
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(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 __popup(self, entry, menu): undo = MenuItem(_("_Undo"), Icons.EDIT_UNDO) add_fake_accel(undo, "<Primary>z") redo = MenuItem(_("_Redo"), Icons.EDIT_REDO) add_fake_accel(redo, "<Primary><shift>z") sep = SeparatorMenuItem() for widget in [sep, redo, undo]: widget.show() undo.connect('activate', lambda *x: self.undo()) redo.connect('activate', lambda *x: self.redo()) undo.set_sensitive(self.can_undo()) redo.set_sensitive(self.can_redo()) for item in [sep, redo, undo]: menu.prepend(item)
def __popup(self, entry, menu): undo = Gtk.ImageMenuItem(Gtk.STOCK_UNDO, use_stock=True) add_fake_accel(undo, "<ctrl>z") redo = Gtk.ImageMenuItem(Gtk.STOCK_REDO, use_stock=True) add_fake_accel(redo, "<ctrl><shift>z") sep = SeparatorMenuItem() for widget in [sep, redo, undo]: widget.show() undo.connect('activate', lambda *x: self.undo()) redo.connect('activate', lambda *x: self.redo()) undo.set_sensitive(self.can_undo()) redo.set_sensitive(self.can_redo()) for item in [sep, redo, undo]: menu.prepend(item)
def __init__(self, *args, **kwargs): super(WebsiteSearch, self).__init__(*args, **kwargs) self.chosen_site = None self._url_pats = [] submenu = Gtk.Menu() self._get_saved_searches() for name, url_pat in self._url_pats: item = Gtk.MenuItem(label=name) connect_obj(item, 'activate', self.__set_site, name) submenu.append(item) # Add link to editor configure = Gtk.MenuItem(label=_(u"Configure Searches…")) connect_obj(configure, 'activate', self.edit_patterns, configure) submenu.append(SeparatorMenuItem()) submenu.append(configure) if submenu.get_children(): self.set_submenu(submenu) else: self.set_sensitive(False)
def __init__(self, *args, **kwargs): super(CustomCommands, self).__init__(*args, **kwargs) self.com_index = None self.unique_only = False self.commands = {} submenu = Gtk.Menu() self.commands = self._get_saved_searches() for (name, c) in self.commands.items(): item = Gtk.MenuItem(name) item.connect_object('activate', self.__set_pat, name) submenu.append(item) # Add link to editor config = Gtk.MenuItem(_("Edit Custom Commands") + "...") config.connect_object('activate', self.edit_patterns, config) submenu.append(SeparatorMenuItem()) submenu.append(config) if submenu.get_children(): self.set_submenu(submenu) else: self.set_sensitive(False)
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 populate_menu(self, menu, library, browser, playlists): """Appends items onto `menu` for each enabled playlist plugin, separated as necessary. """ top_parent = qltk.get_top_parent(browser) attrs = ['plugin_playlist', 'plugin_playlists'] if len(playlists) == 1: attrs.append('plugin_single_playlist') items = [] kinds = self.__plugins kinds.sort(key=lambda plugin: plugin.PLUGIN_ID) print_d("Found %d Playlist plugin(s): %s" % (len(kinds), kinds)) for Kind in kinds: usable = any([callable(getattr(Kind, s)) for s in attrs]) if usable: try: items.append(Kind(playlists, library, top_parent)) except: print_e("Couldn't initialise playlist plugin %s: " % Kind) print_exc() items = filter(lambda i: i.initialized, items) if items: menu.append(SeparatorMenuItem()) for item in items: try: menu.append(item) args = (library, browser, playlists) if item.get_submenu(): for subitem in item.get_submenu().get_children(): subitem.connect_object('activate', self.__handle, item, *args) else: item.connect('activate', self.__handle, *args) except: print_exc() item.destroy()
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)
return util.tag(tag) current = zip(map(tag_title, current), current) def add_header_toggle(menu, (header, tag), active, column=column): item = Gtk.CheckMenuItem(label=header) item.tag = tag item.set_active(active) item.connect('activate', self.__toggle_header_item, column) item.show() item.set_tooltip_text(tag) menu.append(item) for header in current: add_header_toggle(menu, header, True) sep = SeparatorMenuItem() sep.show() menu.append(sep) trackinfo = """title genre ~title~version ~#track ~#playcount ~#skipcount ~rating ~#length""".split() peopleinfo = """artist ~people performer arranger author composer conductor lyricist originalartist""".split() albuminfo = """album ~album~discsubtitle labelid ~#disc ~#discs ~#tracks albumartist""".split() dateinfo = """date originaldate recordingdate ~#laststarted ~#lastplayed ~#added ~#mtime""".split() fileinfo = """~format ~#bitrate ~#filesize ~filename ~basename ~dirname ~uri""".split() copyinfo = """copyright organization location isrc contact website""".split()
def __popup_menu(self, view, parent): menu = Gtk.Menu() view.ensure_popup_selection() model, rows = view.get_selection().get_selected_rows() can_change = min([model[path][0].canedit for path in rows]) items = [ SplitDisc, SplitTitle, SplitPerformer, SplitArranger, SplitValues, SplitPerformerFromTitle, SplitOriginalArtistFromTitle ] items.extend(self.handler.plugins) items.sort(key=lambda item: (item._order, item.__name__)) if len(rows) == 1: row = model[rows[0]] entry = row[0] comment = entry.value text = comment.text split_menu = Gtk.Menu() for Item in items: if Item.tags and entry.tag not in Item.tags: continue try: b = Item(entry.tag, text) except: util.print_exc() else: b.connect('activate', self.__menu_activate, view) if (not min( list(map(self.__songinfo.can_change, b.needs)) + [1]) or comment.is_special()): b.set_sensitive(False) vals = b.activated(entry.tag, text) if len(vals) > 1 and vals[1][1]: split_menu.append(b) if split_menu.get_children(): split_menu.append(SeparatorMenuItem()) pref_item = MenuItem(_("_Configure"), Icons.PREFERENCES_SYSTEM) split_menu.append(pref_item) def show_prefs(parent): from quodlibet.qltk.exfalsowindow import ExFalsoWindow if isinstance(app.window, ExFalsoWindow): from quodlibet.qltk.exfalsowindow import PreferencesWindow window = PreferencesWindow(parent) else: from quodlibet.qltk.prefs import PreferencesWindow window = PreferencesWindow(parent, open_page="tagging") window.show() connect_obj(pref_item, "activate", show_prefs, self) split_item = MenuItem(_("_Split Tag"), Icons.EDIT_FIND_REPLACE) if split_menu.get_children(): split_item.set_submenu(split_menu) else: split_item.set_sensitive(False) menu.append(split_item) copy_b = MenuItem(_("_Copy Value(s)"), Icons.EDIT_COPY) copy_b.connect('activate', self.__copy_tag_value, view) qltk.add_fake_accel(copy_b, "<Primary>c") menu.append(copy_b) remove_b = MenuItem(_("_Remove"), Icons.LIST_REMOVE) remove_b.connect('activate', self.__remove_tag, view) qltk.add_fake_accel(remove_b, "Delete") menu.append(remove_b) menu.show_all() # Setting the menu itself to be insensitive causes it to not # be dismissed; see #473. for c in menu.get_children(): c.set_sensitive(can_change and c.get_property('sensitive')) copy_b.set_sensitive(True) remove_b.set_sensitive(True) menu.connect('selection-done', lambda m: m.destroy()) # XXX: Keep reference self.__menu = menu return view.popup_menu(menu, 3, Gtk.get_current_event_time())
def __init__(self, library, songs, plugins=True, playlists=True, queue=True, remove=True, delete=False, edit=True, ratings=True, show_files=True, download=False, items=None, accels=True, removal_confirmer=None, folder_chooser=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: try: from quodlibet.browsers.playlists.menu import PlaylistMenu submenu = PlaylistMenu(songs, library.playlists) 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) if download: def is_downloadable(song: AudioFile): return bool(not song.is_file and song.get("~uri", False)) self.separate() relevant = [s for s in songs if is_downloadable(s)] total = len(relevant) text = ngettext("_Download file…", "_Download %(total)d files…", total) % { "total": total } b = qltk.MenuItem(text, Icons.EMBLEM_DOWNLOADS) b.set_sensitive(relevant and len(relevant) < MenuItemPlugin.MAX_INVOCATIONS) def _finished(p, successes, failures): msg = (f"<b>{successes}</b> " + _("successful") + f"\n<b>{failures}</b> " + _("failed")) print_d(msg.replace("\n", "; ")) warning = Message(Gtk.MessageType.INFO, app.window, _("Downloads complete"), msg, escape_desc=False) warning.run() def download_cb(menu_item): songs = relevant total = len(songs) msg = ngettext("Download {name!r} to", "Download {total} files to", total) msg = msg.format( name=next(iter(songs))("title")[:99] if total else "?", total=total) chooser = folder_chooser or choose_folders paths = chooser(None, msg, _("Download here"), allow_multiple=False) if not paths: print_d("Cancelling download") return path = paths[0] progress = DownloadProgress(songs) progress.connect('finished', _finished) copool.add(progress.download_songs, path) b.connect('activate', download_cb) self.append(b) def selection_done_cb(menu): menu.destroy() self.connect('selection-done', selection_done_cb)
def preseparate(self): if not self.get_children(): return elif not isinstance(self.get_children()[0], Gtk.SeparatorMenuItem): self.prepend(SeparatorMenuItem())
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 _menu(self, column: SongListColumn) -> Gtk.Menu: menu = Gtk.Menu() def selection_done_cb(menu): menu.destroy() menu.connect('selection-done', selection_done_cb) current_set = set(SongList.headers) def tag_title(tag: str): if "<" in tag: return util.pattern(tag) return util.tag(tag) current = [(tag_title(c), c) for c in SongList.headers] def add_header_toggle(menu: Gtk.Menu, pair: Tuple[str, str], active: bool, column: SongListColumn = column): header, tag = pair item = Gtk.CheckMenuItem(label=header) item.tag = tag item.set_active(active) item.connect('activate', self.__toggle_header_item, column) item.show() item.set_tooltip_text(tag) menu.append(item) for header in current: add_header_toggle(menu, header, True) sep = SeparatorMenuItem() sep.show() menu.append(sep) trackinfo = """title genre comment ~title~version ~#track ~#playcount ~#skipcount ~rating ~#length ~playlists bpm initialkey""".split() peopleinfo = """artist ~people performer arranger author composer conductor lyricist originalartist""".split() albuminfo = """album ~album~discsubtitle labelid ~#disc ~#discs ~#tracks albumartist""".split() dateinfo = """date originaldate recordingdate ~year ~originalyear ~#laststarted ~#lastplayed ~#added ~#mtime""".split() fileinfo = """~format ~#bitdepth ~#bitrate ~#filesize ~filename ~basename ~dirname ~uri ~codec ~encoding ~#channels ~#samplerate""".split() copyinfo = """copyright organization location isrc contact website""".split() all_headers: List[str] = sum( [trackinfo, peopleinfo, albuminfo, dateinfo, fileinfo, copyinfo], []) for name, group in [ (_("All _Headers"), all_headers), (_("_Track Headers"), trackinfo), (_("_Album Headers"), albuminfo), (_("_People Headers"), peopleinfo), (_("_Date Headers"), dateinfo), (_("_File Headers"), fileinfo), (_("_Production Headers"), copyinfo), ]: item = Gtk.MenuItem(label=name, use_underline=True) item.show() menu.append(item) submenu = Gtk.Menu() item.set_submenu(submenu) for header in sorted(zip(map(util.tag, group), group)): add_header_toggle(submenu, header, header[1] in current_set) sep = SeparatorMenuItem() sep.show() menu.append(sep) custom = Gtk.MenuItem( label=_(u"_Customize Headers…"), use_underline=True) custom.show() custom.connect('activate', self.__add_custom_column) menu.append(custom) item = Gtk.CheckMenuItem(label=_("_Expand Column"), use_underline=True) item.set_active(column.get_expand()) item.set_sensitive(column.get_resizable()) def set_expand_cb(item, column): do_expand = item.get_active() if not do_expand: # in case we unexpand, get the current width and set it # so the column doesn't give up all its space # to the left over expanded columns column.set_fixed_width(column.get_width()) else: # in case we expand this seems to trigger a re-distribution # between all expanded columns column.set_fixed_width(-1) column.set_expand(do_expand) self.columns_autosize() sep = SeparatorMenuItem() sep.show() menu.append(sep) item.connect('activate', set_expand_cb, column) item.show() menu.append(item) return 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, library, songs, plugins=True, playlists=True, queue=True, devices=True, remove=True, delete=False, edit=True, ratings=True, items=None, accels=True): 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 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 try: submenu = PlaylistMenu(songs) except AttributeError as e: print_w("Couldn't get Playlists menu: %s" % e) else: b = qltk.MenuItem(_("Play_lists"), Icons.LIST_ADD) 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 = filter(lambda s: s.can_add, songs) 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 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"), Icons.EDIT_COPY) b.set_sensitive(can_add and len(submenu) > 0 and bool(songs)) b.set_submenu(submenu) self.append(b) if remove or delete: self.separate() if remove: 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): library.remove(set(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.DOCUMENT_PROPERTIES) 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) def selection_done_cb(menu): menu.destroy() self.connect('selection-done', selection_done_cb)
def __init__(self, library, dir=None): super(ExFalsoWindow, self).__init__(dialog=False) self.set_title("Ex Falso") self.set_default_size(750, 475) self.enable_window_tracking("exfalso") self.__library = library hp = ConfigRHPaned("memory", "exfalso_paned_position", 1.0) hp.set_border_width(0) hp.set_position(250) hp.show() self.add(hp) vb = Gtk.VBox() bbox = Gtk.HBox(spacing=6) def prefs_cb(*args): window = PreferencesWindow(self) window.show() def plugin_window_cb(*args): window = PluginWindow(self) window.show() def about_cb(*args): about = AboutDialog(self, app) about.run() about.destroy() def update_cb(*args): d = UpdateDialog(self) d.run() d.destroy() menu = Gtk.Menu() about_item = MenuItem(_("_About"), Icons.HELP_ABOUT) about_item.connect("activate", about_cb) menu.append(about_item) check_item = MenuItem(_("_Check for Updates…"), Icons.NETWORK_SERVER) check_item.connect("activate", update_cb) menu.append(check_item) menu.append(SeparatorMenuItem()) plugin_item = MenuItem(_("_Plugins"), Icons.SYSTEM_RUN) plugin_item.connect("activate", plugin_window_cb) menu.append(plugin_item) pref_item = MenuItem(_("_Preferences"), Icons.PREFERENCES_SYSTEM) pref_item.connect("activate", prefs_cb) menu.append(pref_item) menu.show_all() menu_button = MenuButton(SymbolicIconImage(Icons.EMBLEM_SYSTEM, Gtk.IconSize.BUTTON), arrow=True, down=False) menu_button.set_menu(menu) bbox.pack_start(menu_button, False, True, 0) l = Gtk.Label() l.set_alignment(1.0, 0.5) l.set_ellipsize(Pango.EllipsizeMode.END) bbox.pack_start(l, True, True, 0) self._fs = fs = MainFileSelector() vb.pack_start(fs, True, True, 0) vb.pack_start(Align(bbox, border=6), False, True, 0) vb.show_all() hp.pack1(vb, resize=True, shrink=False) nb = qltk.Notebook() nb.props.scrollable = True nb.show() for Page in [EditTags, TagsFromPath, RenameFiles, TrackNumbers]: page = Page(self, self.__library) page.show() nb.append_page(page) hp.pack2(nb, resize=True, shrink=False) fs.connect('changed', self.__changed, l) if dir: fs.go_to(dir) connect_destroy(self.__library, 'changed', self.__library_changed, fs) self.__save = None connect_obj(self, 'changed', self.set_pending, None) for c in fs.get_children(): c.get_child().connect('button-press-event', self.__pre_selection_changed, fs, nb) c.get_child().connect('focus', self.__pre_selection_changed, fs, nb) fs.get_children()[1].get_child().connect('popup-menu', self.__popup_menu, fs) self.emit('changed', []) self.get_child().show() self.__ag = Gtk.AccelGroup() key, mod = Gtk.accelerator_parse("<Primary>Q") self.__ag.connect(key, mod, 0, lambda *x: self.destroy()) self.add_accel_group(self.__ag) # GtkosxApplication assumes the menu bar is mapped, so add # it but don't show it. self._dummy_osx_menu_bar = Gtk.MenuBar() vb.pack_start(self._dummy_osx_menu_bar, False, False, 0)
def _popup_menu(self, view: BaseView, _parent): menu = Gtk.Menu() view.ensure_popup_selection() model, rows = view.get_selection().get_selected_rows() can_change = all(model[path][0].canedit for path in rows) if len(rows) == 1: row = model[rows[0]] entry = row[0] comment = entry.value text = comment.text split_menu = Gtk.Menu() for Item in self._SPLITTERS: if Item.tags and entry.tag not in Item.tags: continue item = self.__item_for(view, Item, entry.tag, text) if not item: continue vals = item.activated(entry.tag, text) changeable = any(not self._group_info.can_change(k) for k in item.needs) fixed = changeable or comment.is_special() if fixed: item.set_sensitive(False) if len(vals) > 1 and vals[1][1]: split_menu.append(item) if split_menu.get_children(): split_menu.append(SeparatorMenuItem()) plugins = self.handler.plugins print_d(f"Adding {len(plugins)} plugin(s) to menu: " f"{', '.join(p.__name__ for p in plugins)}") for p_cls in plugins: item = self.__item_for(view, p_cls, entry.tag, text) if not item: continue results = item.activated(entry.tag, text) # Only enable for the user if the plugin would do something item.set_sensitive(results != [(entry.tag, text)]) menu.append(item) pref_item = MenuItem(_("_Configure"), Icons.PREFERENCES_SYSTEM) split_menu.append(pref_item) def show_prefs(parent): from quodlibet.qltk.exfalsowindow import ExFalsoWindow if isinstance(app.window, ExFalsoWindow): from quodlibet.qltk.exfalsowindow import PreferencesWindow window = PreferencesWindow(parent) else: from quodlibet.qltk.prefs import PreferencesWindow window = PreferencesWindow(parent, open_page="tagging") window.show() connect_obj(pref_item, "activate", show_prefs, self) split_item = MenuItem(_("_Split Tag"), Icons.EDIT_FIND_REPLACE) if split_menu.get_children(): split_item.set_submenu(split_menu) else: split_item.set_sensitive(False) menu.append(split_item) copy_b = MenuItem(_("_Copy Value(s)"), Icons.EDIT_COPY) copy_b.connect('activate', self.__copy_tag_value, view) qltk.add_fake_accel(copy_b, "<Primary>c") menu.append(copy_b) remove_b = MenuItem(_("_Remove"), Icons.LIST_REMOVE) remove_b.connect('activate', self.__remove_tag, view) qltk.add_fake_accel(remove_b, "Delete") menu.append(remove_b) menu.show_all() # Setting the menu itself to be insensitive causes it to not # be dismissed; see #473. for c in menu.get_children(): c.set_sensitive(can_change and c.get_property('sensitive')) copy_b.set_sensitive(True) remove_b.set_sensitive(True) menu.connect('selection-done', lambda m: m.destroy()) # XXX: Keep reference self.__menu = menu return view.popup_menu(menu, 3, Gtk.get_current_event_time())
def __getmenu(self, column): menu = Gtk.Menu() def selection_done_cb(menu): menu.destroy() menu.connect('selection-done', selection_done_cb) current = SongList.headers[:] current_set = set(current) def tag_title(tag): if "<" in tag: return util.pattern(tag) return util.tag(tag) current = zip(map(tag_title, current), current) def add_header_toggle(menu, pair, active, column=column): header, tag = pair item = Gtk.CheckMenuItem(label=header) item.tag = tag item.set_active(active) item.connect('activate', self.__toggle_header_item, column) item.show() item.set_tooltip_text(tag) menu.append(item) for header in current: add_header_toggle(menu, header, True) sep = SeparatorMenuItem() sep.show() menu.append(sep) trackinfo = """title genre ~title~version ~#track ~#playcount ~#skipcount ~rating ~#length ~playlists""".split() peopleinfo = """artist ~people performer arranger author composer conductor lyricist originalartist""".split() albuminfo = """album ~album~discsubtitle labelid ~#disc ~#discs ~#tracks albumartist""".split() dateinfo = """date originaldate recordingdate ~year ~originalyear ~#laststarted ~#lastplayed ~#added ~#mtime""".split() fileinfo = """~format ~#bitrate ~#filesize ~filename ~basename ~dirname ~uri ~codec ~encoding""".split() copyinfo = """copyright organization location isrc contact website""".split() all_headers = sum( [trackinfo, peopleinfo, albuminfo, dateinfo, fileinfo, copyinfo], []) for name, group in [ (_("All _Headers"), all_headers), (_("_Track Headers"), trackinfo), (_("_Album Headers"), albuminfo), (_("_People Headers"), peopleinfo), (_("_Date Headers"), dateinfo), (_("_File Headers"), fileinfo), (_("_Production Headers"), copyinfo), ]: item = Gtk.MenuItem(label=name, use_underline=True) item.show() menu.append(item) submenu = Gtk.Menu() item.set_submenu(submenu) for header in sorted(zip(map(util.tag, group), group)): add_header_toggle(submenu, header, header[1] in current_set) sep = SeparatorMenuItem() sep.show() menu.append(sep) custom = Gtk.MenuItem( label=_(u"_Customize Headers…"), use_underline=True) custom.show() custom.connect('activate', self.__add_custom_column) menu.append(custom) item = Gtk.CheckMenuItem(label=_("_Expand Column"), use_underline=True) item.set_active(column.get_expand()) item.set_sensitive(column.get_resizable()) def set_expand_cb(item, column): do_expand = item.get_active() if not do_expand: # in case we unexpand, get the current width and set it # so the column doesn't give up all its space # to the left over expanded columns column.set_fixed_width(column.get_width()) else: # in case we expand this seems to trigger a re-distribution # between all expanded columns column.set_fixed_width(-1) column.set_expand(do_expand) self.columns_autosize() sep = SeparatorMenuItem() sep.show() menu.append(sep) item.connect('activate', set_expand_cb, column) item.show() menu.append(item) return menu
def add_edit_item(cls, submenu): config = Gtk.MenuItem(label=_("Edit Custom Commands") + "…") connect_obj(config, 'activate', cls.edit_patterns, config) config.set_sensitive(not JSONBasedEditor.is_not_unique()) submenu.append(SeparatorMenuItem()) submenu.append(config)
current = zip(map(tag_title, current), current) def add_header_toggle(menu, (header, tag), active, column=column): item = Gtk.CheckMenuItem(label=header) item.tag = tag item.set_active(active) item.connect('activate', self.__toggle_header_item, column) item.show() item.set_tooltip_text(tag) menu.append(item) for header in current: add_header_toggle(menu, header, True) sep = SeparatorMenuItem() sep.show() menu.append(sep) trackinfo = """title genre ~title~version ~#track ~#playcount ~#skipcount ~rating ~#length""".split() peopleinfo = """artist ~people performer arranger author composer conductor lyricist originalartist""".split() albuminfo = """album ~album~discsubtitle labelid ~#disc ~#discs ~#tracks albumartist""".split() dateinfo = """date originaldate recordingdate ~#laststarted ~#lastplayed ~#added ~#mtime""".split() fileinfo = """~format ~#bitrate ~#filesize ~filename ~basename ~dirname ~uri""".split() copyinfo = """copyright organization location isrc contact website""".split()