Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
    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)
Exemplo n.º 3
0
    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())
Exemplo n.º 4
0
    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()
Exemplo n.º 5
0
    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
Exemplo n.º 6
0
    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()
Exemplo n.º 7
0
    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)
Exemplo n.º 8
0
    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())
Exemplo n.º 9
0
    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())
Exemplo n.º 10
0
    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
Exemplo n.º 11
0
    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)
Exemplo n.º 12
0
    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)
Exemplo n.º 13
0
    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)
Exemplo n.º 14
0
    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())
Exemplo n.º 15
0
    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)
Exemplo n.º 16
0
    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)
Exemplo n.º 17
0
 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)
Exemplo n.º 18
0
 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)
Exemplo n.º 19
0
    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)
Exemplo n.º 20
0
    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()
Exemplo n.º 21
0
    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)
Exemplo n.º 22
0
            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()
Exemplo n.º 23
0
    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())
Exemplo n.º 24
0
    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)
Exemplo n.º 25
0
 def preseparate(self):
     if not self.get_children():
         return
     elif not isinstance(self.get_children()[0], Gtk.SeparatorMenuItem):
         self.prepend(SeparatorMenuItem())
Exemplo n.º 26
0
    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)
Exemplo n.º 27
0
    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
Exemplo n.º 28
0
    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)
Exemplo n.º 29
0
    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)
Exemplo n.º 30
0
    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)
Exemplo n.º 31
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())
Exemplo n.º 32
0
    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
Exemplo n.º 33
0
 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)
Exemplo n.º 34
0
        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()