Example #1
0
    def Menu(self, songs, library, items):
        if len(songs) == 1:
            item = qltk.MenuItem(_(u"_Download…"), Icons.NETWORK_WORKGROUP)
            item.connect('activate', self.__download, songs[0]("~uri"))
            item.set_sensitive(not songs[0].is_file)
        else:
            uris = [song("~uri") for song in songs if not song.is_file]
            item = qltk.MenuItem(_(u"_Download…"), Icons.NETWORK_WORKGROUP)
            item.connect('activate', self.__download_many, uris)
            item.set_sensitive(bool(uris))

        items.append([item])
        menu = SongsMenu(library, songs, items=items)
        return menu
Example #2
0
 def Menu(self, songs, songlist, library):
     menu = SongsMenu(library, songs, parent=self)
     if len(songs) == 1:
         item = qltk.MenuItem(_("_Download..."), Gtk.STOCK_CONNECT)
         item.connect('activate', self.__download, songs[0]("~uri"))
         item.set_sensitive(not songs[0].is_file)
     else:
         songs = filter(lambda s: not s.is_file, songs)
         uris = [song("~uri") for song in songs]
         item = qltk.MenuItem(_("_Download..."), Gtk.STOCK_CONNECT)
         item.connect('activate', self.__download_many, uris)
         item.set_sensitive(bool(songs))
     menu.preseparate()
     menu.prepend(item)
     return menu
Example #3
0
    def Menu(self, songs, library, items):
        if len(songs) == 1:
            item = qltk.MenuItem(_(u"_Download…"), Gtk.STOCK_CONNECT)
            item.connect('activate', self.__download, songs[0]("~uri"))
            item.set_sensitive(not songs[0].is_file)
        else:
            songs = filter(lambda s: not s.is_file, songs)
            uris = [song("~uri") for song in songs]
            item = qltk.MenuItem(_(u"_Download…"), Gtk.STOCK_CONNECT)
            item.connect('activate', self.__download_many, uris)
            item.set_sensitive(bool(songs))

        items.append([item])
        menu = SongsMenu(library, songs, items=items)
        return menu
Example #4
0
 def _create_menu(self):
     menu = Gtk.Menu()
     m = qltk.MenuItem(_(u"_New Folder…"), Icons.DOCUMENT_NEW)
     m.connect('activate', self.__mkdir)
     menu.append(m)
     m = qltk.MenuItem(_("_Delete"), Icons.EDIT_DELETE)
     m.connect('activate', self.__rmdir)
     menu.append(m)
     m = qltk.MenuItem(_("_Refresh"), Icons.VIEW_REFRESH)
     m.connect('activate', self.__refresh)
     menu.append(m)
     m = qltk.MenuItem(_("_Select all Sub-Folders"), Icons.FOLDER)
     m.connect('activate', self.__expand)
     menu.append(m)
     menu.show_all()
     return menu
Example #5
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()
Example #6
0
    def __popup_menu(self, view, library):
        model, itr = view.get_selection().get_selected()
        if itr is None:
            return
        songs = list(model[itr][0])
        songs = [s for s in songs if isinstance(s, AudioFile)]
        menu = SongsMenu(library, songs,
                         playlists=False, remove=False,
                         ratings=False)
        menu.preseparate()

        def _remove(model, itr):
            playlist = model[itr][0]
            dialog = ConfirmRemovePlaylistDialog(self, playlist)
            if dialog.run() == Gtk.ResponseType.YES:
                playlist.delete()
                model.get_model().remove(
                    model.convert_iter_to_child_iter(itr))

        rem = MenuItem(_("_Delete"), Icons.EDIT_DELETE)
        connect_obj(rem, 'activate', _remove, model, itr)
        menu.prepend(rem)

        def _rename(path):
            self._start_rename(path)

        ren = qltk.MenuItem(_("_Rename"), Icons.EDIT)
        qltk.add_fake_accel(ren, "F2")
        connect_obj(ren, 'activate', _rename, model.get_path(itr))
        menu.prepend(ren)

        playlist = model[itr][0]
        PLAYLIST_HANDLER.populate_menu(menu, library, self, [playlist])
        menu.show_all()
        return view.popup_menu(menu, 0, Gtk.get_current_event_time())
Example #7
0
 def Filter(t):
     # Translators: The substituted string is the name of the
     # selected column (a translated tag name).
     b = qltk.MenuItem(
         _("_Filter on %s") % util.tag(t, True), Icons.EDIT_FIND)
     b.connect('activate', self.__filter_on, t, songs, browser)
     return b
Example #8
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()
Example #9
0
 def Menu(self, songs, library, items):
     model, iters = self.__get_selected_songs()
     remove = qltk.MenuItem(_("_Remove from Playlist"), Icons.LIST_REMOVE)
     qltk.add_fake_accel(remove, "Delete")
     connect_obj(remove, 'activate', self.__remove_songs, iters, model)
     playlist_iter = self.__selected_playlists()[1]
     remove.set_sensitive(bool(playlist_iter))
     items.append([remove])
     menu = super().Menu(songs, library, items)
     return menu
Example #10
0
    def _get_menu(self, player, library):
        item = qltk.MenuItem(_(u"_Edit Display…"), Icons.EDIT)
        item.connect('activate', self._on_edit_display, player)

        songs = [player.song] if player.song else []
        song_menu = SongsMenu(library, songs, remove=False, delete=True,
                              accels=False, items=[[item]])

        song_menu.show_all()
        return song_menu
Example #11
0
    def test__on_new_playlist_activate(self):
        main = qltk.MenuItem('Menu')
        menu = StubbedPlaylistMenu(self.SONGS,
                                   PlaylistLibrary(SongFileLibrary()))
        main.set_submenu(menu)

        pl = menu._on_new_playlist_activate(main, self.SONGS)

        self.failUnless(pl, msg="No playlists added")
        self.failUnlessEqual(pl.songs, self.SONGS)
Example #12
0
 def Menu(self, songs, songlist, library):
     menu = super(PlaylistsBrowser, self).Menu(songs, songlist, library)
     model, rows = songlist.get_selection().get_selected_rows()
     iters = map(model.get_iter, rows)
     i = qltk.MenuItem(_("_Remove from Playlist"), Gtk.STOCK_REMOVE)
     i.connect_object('activate', self.__remove, iters, model)
     i.set_sensitive(bool(self.__view.get_selection().get_selected()[1]))
     menu.preseparate()
     menu.prepend(i)
     return menu
Example #13
0
    def test__on_new_playlist_activate(self):
        main = qltk.MenuItem('Menu')
        menu = StubbedPlaylistMenu(self.SONGS, PlaylistLibrary(SongFileLibrary()))
        main.set_submenu(menu)

        # Run it (with stubbed dialog)
        pl = menu._on_new_playlist_activate(main, self.SONGS)

        assert pl, "No playlists added"
        assert pl.name == FIXED_NAME, "Wrong name used"
        assert pl.songs == self.SONGS
Example #14
0
    def Menu(self, songs, library, items):
        songlist = qltk.get_top_parent(self).songlist
        model, iters = self.__get_selected_songs(songlist)
        item = qltk.MenuItem(_("_Remove from Playlist"), Gtk.STOCK_REMOVE)
        qltk.add_fake_accel(item, "Delete")
        connect_obj(item, 'activate', self.__remove, iters, model)
        item.set_sensitive(bool(self.__view.get_selection().get_selected()[1]))

        items.append([item])
        menu = super(PlaylistsBrowser, self).Menu(songs, library, items)
        return menu
Example #15
0
    def test__on_new_playlist_activate(self):
        main = qltk.MenuItem('Menu')
        menu = StubbedPlaylistMenu(self.SONGS, [], self.lib)
        menu.connect('new', self._on_new)
        main.set_submenu(menu)

        menu._on_new_playlist_activate(main, self.SONGS)

        self.failUnless(self.added, msg="No playlists signalled")
        self.failUnlessEqual(self.added[0].songs, self.SONGS)
        self.added[0].delete()
Example #16
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)
    def __popup_menu(self, view, library):
        model, iter = view.get_selection().get_selected()
        device = model[iter][0]

        if device.is_connected() and not self.__busy:
            songs = self.__list_songs(device)
        else:
            songs = []
        menu = SongsMenu(library,
                         songs,
                         playlists=False,
                         devices=False,
                         remove=False,
                         parent=self)

        menu.preseparate()

        props = Gtk.ImageMenuItem(Gtk.STOCK_PROPERTIES, use_stock=True)
        props.connect_object('activate', self.__properties, model[iter][0])
        props.set_sensitive(not self.__busy)
        menu.prepend(props)

        ren = qltk.MenuItem(_("_Rename"), Gtk.STOCK_EDIT)
        keyval, mod = Gtk.accelerator_parse("F2")
        ren.add_accelerator('activate', self.accelerators, keyval, mod,
                            Gtk.AccelFlags.VISIBLE)

        def rename(path):
            self.__render.set_property('editable', True)
            view.set_cursor(path, view.get_columns()[0], start_editing=True)

        ren.connect_object('activate', rename, model.get_path(iter))
        menu.prepend(ren)

        menu.preseparate()

        eject = Gtk.ImageMenuItem(_("_Eject"), use_underline=True)
        eject.set_image(
            Gtk.Image.new_from_icon_name("media-eject", Gtk.IconSize.MENU))
        eject.set_sensitive(not self.__busy and device.eject
                            and device.is_connected())
        eject.connect_object('activate', self.__eject, None)
        menu.prepend(eject)

        refresh = Gtk.ImageMenuItem(Gtk.STOCK_REFRESH, use_stock=True)
        refresh.set_sensitive(device.is_connected())
        refresh.connect_object('activate', self.__refresh, True)
        menu.prepend(refresh)

        menu.show_all()
        return view.popup_menu(menu, 0, Gtk.get_current_event_time())
Example #18
0
    def Menu(self, songs, library, items):

        i = qltk.MenuItem(_("_Add to Library"), Gtk.STOCK_ADD)
        i.set_sensitive(False)
        i.connect('activate', self.__add_songs, songs)
        for song in songs:
            if song not in self.__glibrary:
                i.set_sensitive(True)
                break

        items.append([i])
        menu = SongsMenu(library, songs, remove=self.__remove_songs,
                         delete=True, items=items)
        return menu
Example #19
0
 def Menu(self, songs, songlist, library):
     menu = SongsMenu(library,
                      songs,
                      remove=self.__remove_songs,
                      delete=True,
                      parent=self)
     i = qltk.MenuItem(_("_Add to Library"), Gtk.STOCK_ADD)
     i.set_sensitive(False)
     i.connect('activate', self.__add_songs, songs)
     for song in songs:
         if song not in self.__glibrary:
             i.set_sensitive(True)
             break
     menu.preseparate()
     menu.prepend(i)
     return menu
    def __init__(self, player, library):
        hbox = Gtk.HBox(spacing=3)
        l = TimeLabel()
        hbox.pack_start(l, True, True, 0)
        arrow = Gtk.Arrow(Gtk.ArrowType.RIGHT, Gtk.ShadowType.NONE)
        hbox.pack_start(arrow, False, True, 0)
        super(SeekBar, self).__init__(hbox)

        self.scale.connect('button-press-event', self.__seek_lock)
        self.scale.connect('button-release-event', self.__seek_unlock, player)
        self.scale.connect('key-press-event', self.__seek_lock)
        self.scale.connect('key-release-event', self.__seek_unlock, player)
        self.connect('scroll-event', self.__scroll, player)
        self.scale.connect('value-changed', self.__update_time, l)

        m = Gtk.Menu()
        c = ConfigCheckMenuItem(_("Display remaining time"), "player",
                                "time_remaining")
        c.set_active(config.getboolean("player", "time_remaining"))
        c.connect_object('toggled', self.scale.emit, 'value-changed')
        self.__remaining = c
        m.append(c)
        m.append(SeparatorMenuItem())
        i = qltk.MenuItem(_("_Edit Bookmarks..."), Gtk.STOCK_EDIT)

        def edit_bookmarks_cb(menu_item):
            window = bookmarks.EditBookmarks(self, library, player)
            window.show()

        i.connect('activate', edit_bookmarks_cb)
        m.append(i)
        m.show_all()
        self.connect_object('button-press-event', self.__check_menu, m, player,
                            c)
        self.connect_object('popup-menu', self.__popup_menu, m, player)

        timer = TimeTracker(player)
        timer.connect_object('tick', self.__check_time, player)

        player.connect('song-started', self.__song_changed, l, m)
        player.connect('seek', self.__seeked)
Example #21
0
    def __popup_menu(self, view, library):
        model, itr = view.get_selection().get_selected()
        if itr is None:
            return
        songs = list(model[itr][0])
        songs = [s for s in songs if isinstance(s, AudioFile)]
        menu = SongsMenu(library,
                         songs,
                         playlists=False,
                         remove=False,
                         ratings=False)
        menu.preseparate()

        def _remove(model, itr):
            playlist = model[itr][0]
            response = confirm_remove_playlist_dialog_invoke(
                self, playlist, self.Confirmer)
            if response:
                playlist.delete()
            else:
                print_d("Playlist removal cancelled through prompt")

        rem = MenuItem(_("_Delete"), Icons.EDIT_DELETE)
        connect_obj(rem, 'activate', _remove, model, itr)
        menu.prepend(rem)

        def _rename(path):
            self._start_rename(path)

        ren = qltk.MenuItem(_("_Rename"), Icons.EDIT)
        qltk.add_fake_accel(ren, "F2")
        connect_obj(ren, 'activate', _rename, model.get_path(itr))
        menu.prepend(ren)

        playlist = model[itr][0]
        PLAYLIST_HANDLER.populate_menu(menu, library, self, [playlist])
        menu.show_all()
        return view.popup_menu(menu, 0, Gtk.get_current_event_time())
Example #22
0
    def __popup_menu(self, view, library):
        model, itr = view.get_selection().get_selected()
        if itr is None:
            return
        songs = list(model[itr][0])
        songs = filter(lambda s: isinstance(s, AudioFile), songs)
        menu = SongsMenu(library,
                         songs,
                         playlists=False,
                         remove=False,
                         ratings=False)
        menu.preseparate()

        def _remove(model, itr):
            playlist = model[itr][0]
            dialog = ConfirmRemovePlaylistDialog(self, playlist)
            if dialog.run() == Gtk.ResponseType.YES:
                playlist.delete()
                model.get_model().remove(model.convert_iter_to_child_iter(itr))

        rem = Gtk.ImageMenuItem(Gtk.STOCK_DELETE, use_stock=True)
        connect_obj(rem, 'activate', _remove, model, itr)
        menu.prepend(rem)

        def _rename(path):
            self.__render.set_property('editable', True)
            view.set_cursor(path, view.get_columns()[0], start_editing=True)

        ren = qltk.MenuItem(_("_Rename"), Gtk.STOCK_EDIT)
        qltk.add_fake_accel(ren, "F2")
        connect_obj(ren, 'activate', _rename, model.get_path(itr))
        menu.prepend(ren)

        playlist = model[itr][0]
        PLAYLIST_HANDLER.populate_menu(menu, library, self, [playlist])
        menu.show_all()
        return view.popup_menu(menu, 0, Gtk.get_current_event_time())
Example #23
0
    def __init__(self, library, song, close=False):
        super(EditBookmarksPane, self).__init__(spacing=6)

        hb = Gtk.HBox(spacing=12)
        self.time = time = Gtk.Entry()
        time.set_width_chars(5)
        self.markname = name = Gtk.Entry()
        add = qltk.Button(_("_Add"), Icons.LIST_ADD, Gtk.IconSize.MENU)
        hb.pack_start(time, False, True, 0)
        hb.pack_start(name, True, True, 0)
        hb.pack_start(add, False, True, 0)
        self.pack_start(hb, False, True, 0)

        model = Gtk.ListStore(int, str)
        sw = Gtk.ScrolledWindow()
        sw.set_shadow_type(Gtk.ShadowType.IN)
        sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
        sw.add(RCMHintedTreeView(model=model))

        render = Gtk.CellRendererText()

        def cdf(column, cell, model, iter, data):
            if model[iter][0] < 0:
                cell.set_property('text', _("N/A"))
            else:
                cell.set_property('text', util.format_time(model[iter][0]))
        render.set_property('editable', True)
        render.connect('edited', self.__edit_time, model)
        col = Gtk.TreeViewColumn(_("Time"), render)
        col.set_cell_data_func(render, cdf, None)
        sw.get_child().append_column(col)

        render = Gtk.CellRendererText()
        render.set_property('ellipsize', Pango.EllipsizeMode.END)
        col = Gtk.TreeViewColumn(_("Bookmark Name"), render, text=1)
        render.set_property('editable', True)
        render.connect('edited', self.__edit_name, model)
        sw.get_child().append_column(col)
        self.pack_start(sw, True, True, 0)
        self.accels = Gtk.AccelGroup()

        hbox = Gtk.HButtonBox()
        remove = qltk.Button(_("_Remove"), Icons.LIST_REMOVE)
        remove.set_sensitive(False)
        hbox.pack_start(remove, True, True, 0)
        if close:
            self.close = qltk.Button(_("_Close"), Icons.WINDOW_CLOSE)
            hbox.pack_start(self.close, True, True, 0)
        else:
            hbox.set_layout(Gtk.ButtonBoxStyle.END)
        self.pack_start(hbox, False, True, 0)

        connect_obj(add, 'clicked', self.__add, model, time, name)

        model.set_sort_column_id(0, Gtk.SortType.ASCENDING)
        model.connect('row-changed', self._set_bookmarks, library, song)
        model.connect('row-inserted', self._set_bookmarks, library, song)

        selection = sw.get_child().get_selection()
        selection.set_mode(Gtk.SelectionMode.MULTIPLE)
        selection.connect('changed', self.__check_selection, remove)
        remove.connect('clicked', self.__remove, selection, library, song)

        connect_obj(time, 'changed', self.__check_entry, add, time, name)
        connect_obj(name, 'changed', self.__check_entry, add, time, name)
        connect_obj(name, 'activate', Gtk.Button.clicked, add)

        time.set_text(_("MM:SS"))
        connect_obj(time, 'activate', Gtk.Entry.grab_focus, name)
        name.set_text(_("Bookmark Name"))

        menu = Gtk.Menu()
        remove = qltk.MenuItem(_("_Remove"), Icons.LIST_REMOVE)
        remove.connect('activate', self.__remove, selection, library, song)
        keyval, mod = Gtk.accelerator_parse("Delete")
        remove.add_accelerator(
            'activate', self.accels, keyval, mod, Gtk.AccelFlags.VISIBLE)
        menu.append(remove)
        menu.show_all()
        sw.get_child().connect('popup-menu', self.__popup, menu)
        sw.get_child().connect('key-press-event',
                                self.__view_key_press, remove)
        connect_obj(self, 'destroy', Gtk.Menu.destroy, menu)

        self.__fill(model, song)
Example #24
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)
Example #25
0
    def __init__(self, initial=None, folders=None):
        """
        initial -- the path to select/scroll to
        folders -- a list of paths to show in the tree view, None
                   will result in a separator.
        """

        model = ObjectTreeStore()
        super(DirectoryTree, self).__init__(model=model)

        if initial is not None:
            initial = util.fsnative(initial)

        column = TreeViewColumn(_("Folders"))
        column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
        render = Gtk.CellRendererPixbuf()
        render.set_property('stock_id', Gtk.STOCK_DIRECTORY)
        column.pack_start(render, False)
        render = Gtk.CellRendererText()
        column.pack_start(render, True)

        def cell_data(column, cell, model, iter_, userdata):
            value = model.get_value(iter_)
            if value is not None:
                text = fsdecode(os.path.basename(value) or value)
                cell.set_property('text', text)

        column.set_cell_data_func(render, cell_data)

        self.append_column(column)
        self.set_search_equal_func(search_func, True)

        if folders is None:
            folders = []

        for path in folders:
            niter = model.append(None, [path])
            if path is not None:
                model.append(niter, ["dummy"])

        self.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
        self.connect('test-expand-row', DirectoryTree.__expanded, model)

        self.set_row_separator_func(
            lambda model, iter_, data: model.get_value(iter_) is None, None)

        if initial:
            self.go_to(initial)

        menu = Gtk.Menu()
        m = qltk.MenuItem(_("_New Folder..."), Gtk.STOCK_NEW)
        m.connect('activate', self.__mkdir)
        menu.append(m)
        m = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_DELETE, None)
        m.connect('activate', self.__rmdir)
        menu.append(m)
        m = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_REFRESH, None)
        m.connect('activate', self.__refresh)
        menu.append(m)
        m = qltk.MenuItem(_("_Select All Subfolders"), Gtk.STOCK_DIRECTORY)
        m.connect('activate', self.__expand)
        menu.append(m)
        menu.show_all()
        self.connect_object('popup-menu', self.__popup_menu, menu)
Example #26
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)
Example #27
0
    def __init__(self, title, validator=None):
        super(_KeyValueEditor, self).__init__()
        self.set_border_width(12)
        self.set_title(title)
        self.set_default_size(self._WIDTH, self._HEIGHT)

        self.add(Gtk.VBox(spacing=6))

        t = Gtk.Table(n_rows=2, n_columns=3)
        t.set_row_spacings(3)
        t.set_col_spacing(0, 3)
        t.set_col_spacing(1, 12)

        l = Gtk.Label(label=_("_Name:"))
        name = entry.UndoEntry()
        l.set_mnemonic_widget(name)
        l.set_use_underline(True)
        l.set_alignment(0.0, 0.5)
        t.attach(l, 0, 1, 0, 1, xoptions=Gtk.AttachOptions.FILL)
        t.attach(name, 1, 2, 0, 1)

        l = Gtk.Label(label=_("_Value:"))
        self.value = entry.ValidatingEntry(validator)
        l.set_mnemonic_widget(self.value)
        l.set_use_underline(True)
        l.set_alignment(0.0, 0.5)
        t.attach(l, 0, 1, 1, 2, xoptions=Gtk.AttachOptions.FILL)
        t.attach(self.value, 1, 2, 1, 2)
        add = qltk.Button(_("_Add"), Icons.LIST_ADD)
        add.set_sensitive(False)
        t.attach(add, 2, 3, 1, 2, xoptions=Gtk.AttachOptions.FILL)

        self.get_child().pack_start(t, False, True, 0)

        # Set up the model for this widget
        self.model = Gtk.ListStore(str, str)
        self.fill_values()

        view = RCMHintedTreeView(model=self.model)
        view.set_headers_visible(False)
        view.set_reorderable(True)
        view.set_rules_hint(True)
        render = Gtk.CellRendererText()
        render.props.ellipsize = Pango.EllipsizeMode.END
        column = Gtk.TreeViewColumn("", render)
        column.set_cell_data_func(render, self.__cdf, None)
        view.append_column(column)

        sw = Gtk.ScrolledWindow()
        sw.set_shadow_type(Gtk.ShadowType.IN)
        sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
        sw.add(view)
        self.get_child().pack_start(sw, True, True, 0)

        menu = Gtk.Menu()
        remove = qltk.MenuItem(_("_Remove"), Icons.LIST_REMOVE)
        connect_obj(remove, 'activate', self.__remove, view)
        qltk.add_fake_accel(remove, "Delete")
        menu.append(remove)
        menu.show_all()

        bbox = Gtk.HButtonBox()
        rem_b = qltk.Button(_("_Remove"), Icons.LIST_REMOVE)
        rem_b.set_sensitive(False)
        bbox.pack_start(rem_b, True, True, 0)
        self.use_header_bar()
        close = qltk.Button(_("_Close"), Icons.WINDOW_CLOSE)
        if not self.has_close_button():
            bbox.pack_start(close, True, True, 0)
        else:
            bbox.set_layout(Gtk.ButtonBoxStyle.START)
        self.get_child().pack_start(bbox, False, True, 0)

        selection = view.get_selection()
        connect_obj(name, 'activate', Gtk.Entry.grab_focus, self.value)
        connect_obj(self.value, 'activate', Gtk.Button.clicked, add)
        self.value.connect('changed', self.__changed, [add])
        connect_obj(add, 'clicked', self.__add, selection, name, self.value,
                    self.model)
        selection.connect('changed', self.__set_text, name, self.value, rem_b)
        view.connect('popup-menu', self.__popup, menu)
        connect_obj(rem_b, 'clicked', self.__remove, view)
        connect_obj(close, 'clicked', qltk.Window.destroy, self)
        view.connect('key-press-event', self.__view_key_press)
        connect_obj(self, 'destroy', Gtk.Menu.destroy, menu)

        name.grab_focus()
        self.get_child().show_all()
Example #28
0
    def __init__(self, library):
        super(MaskedBox, self).__init__(spacing=6)

        self.model = model = Gtk.ListStore(object)
        view = RCMHintedTreeView(model=model)
        view.set_fixed_height_mode(True)
        view.set_headers_visible(False)
        self.view = view

        menu = Gtk.Menu()
        unhide_item = qltk.MenuItem(_("Unhide"), Gtk.STOCK_ADD)
        unhide_item.connect_object('activate', self.__unhide, view, library)
        menu.append(unhide_item)

        remove_item = Gtk.ImageMenuItem(label=Gtk.STOCK_REMOVE, use_stock=True)
        remove_item.connect_object('activate', self.__remove, view, library)
        menu.append(remove_item)

        menu.show_all()
        view.connect('popup-menu', self.__popup, menu)

        sw = Gtk.ScrolledWindow()
        sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
        sw.set_shadow_type(Gtk.ShadowType.IN)
        sw.add(view)
        sw.set_size_request(-1, max(sw.size_request().height, 80))

        def cdf(column, cell, model, iter, data):
            row = model[iter]
            cell.set_property('text', fsdecode(row[0]))

        def cdf_count(column, cell, model, iter, data):
            mount = model[iter][0]
            song_count = len(library.get_masked(mount))
            cell.set_property(
                'text',
                _("%(song_count)d songs") % {"song_count": song_count})

        column = Gtk.TreeViewColumn(None)
        column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)

        render = Gtk.CellRendererText()
        render.set_property('ellipsize', Pango.EllipsizeMode.END)
        column.pack_start(render, True)
        column.set_cell_data_func(render, cdf)

        render = Gtk.CellRendererText()
        render.props.sensitive = False
        column.pack_start(render, False)
        column.set_cell_data_func(render, cdf_count)

        view.append_column(column)

        unhide = qltk.Button(_("Unhide"), Gtk.STOCK_ADD)
        unhide.connect_object("clicked", self.__unhide, view, library)
        remove = Gtk.Button(stock=Gtk.STOCK_REMOVE)

        selection = view.get_selection()
        selection.set_mode(Gtk.SelectionMode.MULTIPLE)
        selection.connect("changed", self.__select_changed, remove, unhide)
        selection.emit("changed")

        remove.connect_object("clicked", self.__remove, view, library)

        vbox = Gtk.VBox(spacing=6)
        vbox.pack_start(unhide, False, True, 0)
        vbox.pack_start(remove, False, True, 0)

        self.pack_start(sw, True, True, 0)
        self.pack_start(vbox, False, True, 0)

        for path in library.masked_mount_points:
            model.append(row=[path])

        if not len(model):
            self.set_sensitive(False)

        for child in self.get_children():
            child.show_all()
Example #29
0
    def __init__(self, initial=None, folders=None):
        """
        initial -- the path to select/scroll to
        folders -- a list of paths to show in the tree view, None
                   will result in a separator.
        """

        model = ObjectTreeStore()
        super(DirectoryTree, self).__init__(model=model)

        if initial is not None:
            assert is_fsnative(initial)

        column = TreeViewColumn(title=_("Folders"))
        column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
        render = Gtk.CellRendererPixbuf()
        render.set_property('icon-name', Icons.FOLDER)
        render.props.xpad = 3
        column.pack_start(render, False)
        render = Gtk.CellRendererText()
        if self.supports_hints():
            render.set_property('ellipsize', Pango.EllipsizeMode.END)
        column.pack_start(render, True)

        def cell_data(column, cell, model, iter_, userdata):
            value = model.get_value(iter_)
            if value is not None:
                text = fsdecode(os.path.basename(value) or value)
                cell.set_property('text', text)

        column.set_cell_data_func(render, cell_data)

        self.append_column(column)
        self.set_search_equal_func(search_func, True)
        self.set_search_column(0)

        if folders is None:
            folders = []

        for path in folders:
            niter = model.append(None, [path])
            if path is not None:
                assert is_fsnative(path)
                model.append(niter, ["dummy"])

        self.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
        self.connect('test-expand-row', DirectoryTree.__expanded, model)

        self.set_row_separator_func(
            lambda model, iter_, data: model.get_value(iter_) is None, None)

        if initial:
            self.go_to(initial)

        menu = Gtk.Menu()
        m = qltk.MenuItem(_(u"_New Folder…"), Icons.DOCUMENT_NEW)
        m.connect('activate', self.__mkdir)
        menu.append(m)
        m = qltk.MenuItem(_("_Delete"), Icons.EDIT_DELETE)
        m.connect('activate', self.__rmdir)
        menu.append(m)
        m = qltk.MenuItem(_("_Refresh"), Icons.VIEW_REFRESH)
        m.connect('activate', self.__refresh)
        menu.append(m)
        m = qltk.MenuItem(_("_Select all Sub-Folders"), Icons.FOLDER)
        m.connect('activate', self.__expand)
        menu.append(m)
        menu.show_all()
        connect_obj(self, 'popup-menu', self.__popup_menu, menu)

        # Allow to drag and drop files from outside
        targets = [("text/uri-list", 0, 42)]
        targets = [Gtk.TargetEntry.new(*t) for t in targets]
        self.drag_dest_set(Gtk.DestDefaults.ALL, targets, Gdk.DragAction.COPY)
        self.connect('drag-data-received', self.__drag_data_received)
Example #30
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)