Пример #1
0
    def __init__(self, browser):
        super(PreferencesButton, self).__init__()

        self._menu = menu = Gtk.Menu()

        wide_mode = ConfigCheckMenuItem(
            _("_Wide Mode"), "browsers", "pane_wide_mode", True)
        wide_mode.connect("toggled", self.__wide_mode_changed, browser)
        menu.append(wide_mode)

        pref_item = MenuItem(_("_Preferences"), Icons.PREFERENCES_SYSTEM)

        def preferences_cb(menu_item):
            window = Preferences(browser)
            window.show()
        pref_item.connect("activate", preferences_cb)
        menu.append(pref_item)

        menu.show_all()

        button = MenuButton(
                SymbolicIconImage(Icons.EMBLEM_SYSTEM, Gtk.IconSize.MENU),
                arrow=True)
        button.set_menu(menu)
        button.show()
        self.pack_start(button, True, True, 0)
Пример #2
0
    def __popup(self, library):
        songs = self.get_selected_songs()
        if not songs:
            return

        menu = SongsMenu(library, songs, queue=False, remove=False, delete=False, ratings=False)
        menu.preseparate()
        remove = MenuItem(_("_Remove"), Icons.LIST_REMOVE)
        qltk.add_fake_accel(remove, "Delete")
        remove.connect("activate", self.__remove)
        menu.prepend(remove)
        menu.show_all()
        return self.popup_menu(menu, 0, Gtk.get_current_event_time())
Пример #3
0
    def __popup(self, view, library):
        albums = self.__get_selected_albums()
        songs = self.__get_songs_from_albums(albums)

        items = []
        if self.__cover_column.get_visible():
            num = len(albums)
            button = MenuItem(ngettext("Reload album _cover", "Reload album _covers", num), Icons.VIEW_REFRESH)
            button.connect("activate", self.__refresh_album, view)
            items.append(button)

        menu = SongsMenu(library, songs, items=[items])
        menu.show_all()
        return view.popup_menu(menu, 0, Gtk.get_current_event_time())
Пример #4
0
    def __popup(self, view, library):

        albums = self.__get_selected_albums()
        songs = self.__get_songs_from_albums(albums)

        items = []
        num = len(albums)
        button = MenuItem(
            ngettext("Reload album _cover", "Reload album _covers", num),
            Icons.VIEW_REFRESH)
        button.connect('activate', self.__refresh_album, view)
        items.append(button)

        menu = SongsMenu(library, songs, items=[items])
        menu.show_all()
        popup_menu_at_widget(menu, view,
            Gdk.BUTTON_SECONDARY,
            Gtk.get_current_event_time())
Пример #5
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)
Пример #6
0
    def __init__(self, browser):
        super(PreferencesButton, self).__init__()

        self._menu = menu = Gtk.Menu()

        pref_item = MenuItem(_("_Preferences"), Icons.PREFERENCES_SYSTEM)

        def preferences_cb(menu_item):
            window = Preferences(browser)
            window.show()
        pref_item.connect("activate", preferences_cb)
        menu.append(pref_item)

        menu.show_all()

        button = MenuButton(
                SymbolicIconImage(Icons.EMBLEM_SYSTEM, Gtk.IconSize.MENU),
                arrow=True)
        button.set_menu(menu)
        button.show()
        self.pack_start(button, True, True, 0)
Пример #7
0
    def Menu(self, songs, songlist, library):
        menu = SongsMenu(self.__librarian, songs, playlists=False, remove=True,
                         queue=False, accels=songlist.accelerators,
                         devices=False, parent=self)

        menu.prepend(gtk.SeparatorMenuItem())

        in_fav = False
        in_all = False
        for song in songs:
            if song in self.__fav_stations:
                in_fav = True
            elif song in self.__stations:
                in_all = True
            if in_fav and in_all:
                break

        button = MenuItem(_("Remove from Favorites"), gtk.STOCK_REMOVE)
        button.set_sensitive(in_fav)
        gobject_weak(button.connect_object, 'activate',
                     self.__remove_fav, songs)
        menu.prepend(button)

        button = MenuItem(_("Add to Favorites"), gtk.STOCK_ADD)
        button.set_sensitive(in_all)
        gobject_weak(button.connect_object, 'activate',
                     self.__add_fav, songs)
        menu.prepend(button)

        return menu
Пример #8
0
    def Menu(self, songs, library, items):
        in_fav = False
        in_all = False
        for song in songs:
            if song in self.__fav_stations:
                in_fav = True
            elif song in self.__stations:
                in_all = True
            if in_fav and in_all:
                break

        iradio_items = []
        button = MenuItem(_("Add to Favorites"), Gtk.STOCK_ADD)
        button.set_sensitive(in_all)
        connect_obj(button, 'activate', self.__add_fav, songs)
        iradio_items.append(button)
        button = MenuItem(_("Remove from Favorites"), Gtk.STOCK_REMOVE)
        button.set_sensitive(in_fav)
        connect_obj(button, 'activate', self.__remove_fav, songs)
        iradio_items.append(button)

        items.append(iradio_items)
        menu = SongsMenu(self.__librarian, songs, playlists=False, remove=True,
                         queue=False, devices=False, items=items)
        return menu
Пример #9
0
    def __popup(self, view, event, library):
        x = int(event.x)
        y = int(event.y)
        current_path = view.get_path_at_pos(x, y)
        if event.button == Gdk.BUTTON_SECONDARY and current_path:
            if not view.path_is_selected(current_path):
                view.unselect_all()
            view.select_path(current_path)
            albums = self.__get_selected_albums()
            songs = self.__get_songs_from_albums(albums)

            items = []
            num = len(albums)
            button = MenuItem(
                ngettext("Reload album _cover", "Reload album _covers", num),
                Icons.VIEW_REFRESH)
            button.connect('activate', self.__refresh_album, view)
            items.append(button)

            menu = SongsMenu(library, songs, items=[items])
            menu.show_all()
            menu.popup(None, None, None, event.button, event.time,
                Gtk.get_current_event_time())
Пример #10
0
    def __map(self, menu, songs):
        remove_item = MenuItem(_("_Remove all Images"), "edit-delete")
        remove_item.connect('activate', self.__remove_images, songs)
        menu.append(remove_item)

        set_item = MenuItem(_("_Embed Current Image"), "edit-paste")
        set_item.connect('activate', self.__set_image, songs)
        menu.append(set_item)

        menu.show_all()
Пример #11
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())
Пример #12
0
    def __init__(self, browser, model):
        Gtk.HBox.__init__(self)

        sort_orders = [
            (_("_Title"), self.__compare_title),
            (_("_Artist"), self.__compare_artist),
            (_("_Date"), self.__compare_date),
            (_("_Genre"), self.__compare_genre),
            (_("_Rating"), self.__compare_rating),
        ]

        menu = Gtk.Menu()

        sort_item = Gtk.MenuItem(
            label=_(u"Sort _by…"), use_underline=True)
        sort_menu = Gtk.Menu()

        active = config.getint('browsers', 'album_sort', 1)

        item = None
        for i, (label, func) in enumerate(sort_orders):
            item = RadioMenuItem(group=item, label=label,
                                 use_underline=True)
            model.set_sort_func(100 + i, func)
            if i == active:
                model.set_sort_column_id(100 + i, Gtk.SortType.ASCENDING)
                item.set_active(True)
            item.connect("toggled",
                         util.DeferredSignal(self.__sort_toggled_cb),
                         model, i)
            sort_menu.append(item)

        sort_item.set_submenu(sort_menu)
        menu.append(sort_item)

        pref_item = MenuItem(_("_Preferences"), Icons.PREFERENCES_SYSTEM)
        menu.append(pref_item)
        connect_obj(pref_item, "activate", Preferences, browser)

        menu.show_all()

        button = MenuButton(
                SymbolicIconImage(Icons.EMBLEM_SYSTEM, Gtk.IconSize.MENU),
                arrow=True)
        button.set_menu(menu)
        self.pack_start(button, True, True, 0)
Пример #13
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()
                model.get_model().remove(model.convert_iter_to_child_iter(itr))
            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())
Пример #14
0
    def __popup_menu(self, view, library):
        model, iter = view.get_selection().get_selected()
        device = model[iter][0]

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

        menu.preseparate()

        props = MenuItem(_("_Properties"), Icons.DOCUMENT_PROPERTIES)
        connect_obj(props, 'activate', self.__properties, model[iter][0])
        props.set_sensitive(not self.__busy)
        menu.prepend(props)

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

        def rename(path):
            self.__render.set_property('editable', True)
            view.set_cursor(path, view.get_columns()[0], start_editing=True)
        connect_obj(ren, 'activate', rename, model.get_path(iter))
        menu.prepend(ren)

        menu.preseparate()

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

        refresh = MenuItem(_("_Refresh"), Icons.VIEW_REFRESH)
        refresh.set_sensitive(device.is_connected())
        connect_obj(refresh, 'activate', self.__refresh, True)
        menu.prepend(refresh)

        menu.show_all()
        return view.popup_menu(menu, 0, Gtk.get_current_event_time())
Пример #15
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 = MenuItem(_("_Delete"), Icons.EDIT_DELETE)
        connect_obj(rem, 'activate', _remove, model, itr)
        menu.prepend(rem)

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

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

        playlist = model[itr][0]
        PLAYLIST_HANDLER.populate_menu(menu, library, self, [playlist])
        menu.show_all()
        return view.popup_menu(menu, 0, Gtk.get_current_event_time())
Пример #16
0
    def __init__(self, library, player):
        super(QueueExpander, self).__init__(spacing=3)
        sw = ScrolledWindow()
        sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        sw.set_shadow_type(Gtk.ShadowType.IN)
        self.queue = PlayQueue(library, player)
        self.queue.props.expand = True
        sw.add(self.queue)

        add_css(self, ".ql-expanded title { margin-bottom: 5px; }")

        outer = ExpandBoxHack()

        left = Gtk.HBox(spacing=12)

        hb2 = Gtk.HBox(spacing=3)
        state_icon = PlaybackStatusIcon()
        state_icon.stop()
        state_icon.show()
        hb2.pack_start(state_icon, True, True, 0)
        name_label = Gtk.Label(label=_("_Queue"), use_underline=True)
        name_label.set_size_request(-1, 24)
        hb2.pack_start(name_label, True, True, 0)
        left.pack_start(hb2, False, True, 0)

        menu = Gtk.Menu()

        self.count_label = count_label = Gtk.Label()
        self.count_label.set_property("ellipsize", Pango.EllipsizeMode.END)
        self.count_label.set_width_chars(10)
        self.count_label.get_style_context().add_class("dim-label")
        left.pack_start(count_label, False, True, 0)

        outer.pack_start(left, True, True, 0)

        self.set_label_fill(True)

        rand_checkbox = ConfigCheckMenuItem(
                _("_Random"), "memory", "shufflequeue", populate=True)
        rand_checkbox.connect('toggled', self.__queue_shuffle)
        self.set_shuffled(rand_checkbox.get_active())
        menu.append(rand_checkbox)

        stop_checkbox = ConfigCheckMenuItem(
            _("Stop Once Empty"), "memory", "queue_stop_once_empty",
            populate=True)
        menu.append(stop_checkbox)

        clear_item = MenuItem(_("_Clear Queue"), Icons.EDIT_CLEAR)
        menu.append(clear_item)
        clear_item.connect("activate", self.__clear_queue)

        button = SmallMenuButton(
            SymbolicIconImage(Icons.EMBLEM_SYSTEM, Gtk.IconSize.MENU),
            arrow=True)
        button.set_relief(Gtk.ReliefStyle.NONE)
        button.show_all()
        button.hide()
        button.set_no_show_all(True)
        menu.show_all()
        button.set_menu(menu)

        outer.pack_start(button, False, False, 0)

        close_button = SmallImageButton(
            image=SymbolicIconImage("window-close", Gtk.IconSize.MENU),
            relief=Gtk.ReliefStyle.NONE)

        close_button.connect("clicked", lambda *x: self.hide())

        outer.pack_start(close_button, False, False, 6)

        self.set_label_widget(outer)
        self.add(sw)
        self.connect('notify::expanded', self.__expand, button)
        self.connect('notify::expanded', self.__expand, button)

        targets = [
            ("text/x-quodlibet-songs", Gtk.TargetFlags.SAME_APP, DND_QL),
            ("text/uri-list", 0, DND_URI_LIST)
        ]
        targets = [Gtk.TargetEntry.new(*t) for t in targets]

        self.drag_dest_set(Gtk.DestDefaults.ALL, targets, Gdk.DragAction.COPY)
        self.connect('drag-motion', self.__motion)
        self.connect('drag-data-received', self.__drag_data_received)

        self.queue.model.connect_after('row-inserted',
            util.DeferredSignal(self.__check_expand), count_label)
        self.queue.model.connect_after('row-deleted',
            util.DeferredSignal(self.__update_count), count_label)

        self.__update_count(self.model, None, count_label)

        connect_destroy(
            player, 'song-started', self.__update_state_icon, state_icon)
        connect_destroy(
            player, 'paused', self.__update_state_icon_pause,
            state_icon, True)
        connect_destroy(
            player, 'unpaused', self.__update_state_icon_pause,
            state_icon, False)

        connect_destroy(
            player, 'song-started', self.__update_queue_stop, self.queue.model)

        # to make the children clickable if mapped
        # ....no idea why, but works
        def hack(expander):
            label = expander.get_label_widget()
            if label:
                label.unmap()
                label.map()
        self.connect("map", hack)

        self.set_expanded(config.getboolean("memory", "queue_expanded"))
        self.notify("expanded")

        for child in self.get_children():
            child.show_all()
Пример #17
0
    def _popup_menu(self, icon, button, time):
        if self.__destroy_win32_menu():
            return
        self.__menu = menu = Gtk.Menu()

        player = app.player
        window = app.window

        if player.paused:
            playpause = MenuItem(_("_Play"), Icons.MEDIA_PLAYBACK_START)
        else:
            playpause = MenuItem(_("P_ause"), Icons.MEDIA_PLAYBACK_PAUSE)
        playpause.connect('activate', self.__play_pause)

        previous = MenuItem(_("Pre_vious"), Icons.MEDIA_SKIP_BACKWARD)
        previous.connect('activate', lambda *args: player.previous())

        next = MenuItem(_("_Next"), Icons.MEDIA_SKIP_FORWARD)
        next.connect('activate', lambda *args: player.next())

        orders = Gtk.MenuItem(label=_("Play _Order"), use_underline=True)

        repeat = Gtk.CheckMenuItem(label=_("_Repeat"), use_underline=True)
        repeat.set_active(window.repeat.get_active())
        repeat.connect('toggled',
            lambda s: window.repeat.set_active(s.get_active()))

        def set_safter(widget, safter_action):
            safter_action.set_active(widget.get_active())

        safter_action = app.window.stop_after
        safter = Gtk.CheckMenuItem(label=_("Stop _after this song"),
                                   use_underline=True)
        safter.set_active(safter_action.get_active())
        safter.connect('toggled', set_safter, safter_action)

        def set_order(widget, order):
            name = order.name
            try:
                window.order.set_active_by_name(name)
            except ValueError:
                pass

        order_items = []
        item = None
        active_order = window.order.get_active()
        for Kind in ORDERS:
            item = RadioMenuItem(
                    group=item,
                    label=Kind.accelerated_name,
                    use_underline=True)
            order_items.append(item)
            if Kind is active_order:
                item.set_active(True)
            item.connect('toggled', set_order, Kind)

        order_sub = Gtk.Menu()
        order_sub.append(repeat)
        order_sub.append(safter)
        order_sub.append(SeparatorMenuItem())
        for item in order_items:
            order_sub.append(item)
        orders.set_submenu(order_sub)

        browse = qltk.MenuItem(_("_Browse Library"), Icons.EDIT_FIND)
        browse_sub = Gtk.Menu()

        for Kind in browsers.browsers:
            if Kind.is_empty:
                continue
            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)

        props = qltk.MenuItem(_("Edit _Tags"), Icons.DOCUMENT_PROPERTIES)
        props.connect('activate', self.__properties)

        info = MenuItem(_("_Information"), Icons.DIALOG_INFORMATION)
        info.connect('activate', self.__information)

        def set_rating(value):
            song = player.song
            if song is None:
                return
            else:
                song["~#rating"] = value
                app.librarian.changed([song])

        rating = Gtk.MenuItem(label=_("_Rating"), use_underline=True)
        rating_sub = Gtk.Menu()
        for r in RATINGS.all:
            item = Gtk.MenuItem(label="%0.2f\t%s" % (r, util.format_rating(r)))
            connect_obj(item, 'activate', set_rating, r)
            rating_sub.append(item)
        rating.set_submenu(rating_sub)

        quit = MenuItem(_("_Quit"), Icons.APPLICATION_EXIT)
        quit.connect('activate', lambda *x: app.quit())

        menu.append(playpause)
        menu.append(SeparatorMenuItem())
        menu.append(previous)
        menu.append(next)
        menu.append(orders)
        menu.append(SeparatorMenuItem())
        menu.append(browse)
        menu.append(SeparatorMenuItem())
        menu.append(props)
        menu.append(info)
        menu.append(rating)
        menu.append(SeparatorMenuItem())
        menu.append(quit)

        menu.show_all()

        if sys.platform in ("win32", "darwin"):
            pos_func = pos_arg = None
        else:
            pos_func = Gtk.StatusIcon.position_menu
            pos_arg = self._icon

        menu.popup(None, None, pos_func, pos_arg, button, time)
Пример #18
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)
Пример #19
0
    def __init__(self, library, player):
        super().__init__(spacing=3)
        sw = ScrolledWindow()
        sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        sw.set_shadow_type(Gtk.ShadowType.IN)
        save_interval_secs = config.getint("autosave", "queue_interval")
        self.queue = PlayQueue(library, player, save_interval_secs)
        self.queue.props.expand = True
        sw.add(self.queue)

        add_css(self, ".ql-expanded title { margin-bottom: 5px; }")

        outer = ExpandBoxHack()

        left = Gtk.HBox(spacing=12)

        hb2 = Gtk.HBox(spacing=3)
        state_icon = PlaybackStatusIcon()
        state_icon.stop()
        state_icon.show()
        hb2.pack_start(state_icon, True, True, 0)
        name_label = Gtk.Label(label=_("_Queue"), use_underline=True)
        name_label.set_size_request(-1, 24)
        hb2.pack_start(name_label, True, True, 0)
        left.pack_start(hb2, False, True, 0)

        menu = Gtk.Menu()

        self.count_label = count_label = Gtk.Label()
        self.count_label.set_property("ellipsize", Pango.EllipsizeMode.END)
        self.count_label.set_width_chars(10)
        self.count_label.get_style_context().add_class("dim-label")
        left.pack_start(count_label, False, True, 0)

        outer.pack_start(left, True, True, 0)

        self.set_label_fill(True)

        clear_item = SmallImageButton(image=SymbolicIconImage(
            Icons.USER_TRASH, Gtk.IconSize.MENU),
                                      relief=Gtk.ReliefStyle.NONE,
                                      tooltip_text=_("Clear Queue"))
        clear_item.connect("clicked", self.__clear_queue)
        outer.pack_start(clear_item, False, False, 3)

        toggle = SmallImageToggleButton(
            image=SymbolicIconImage(Icons.SYSTEM_LOCK_SCREEN,
                                    Gtk.IconSize.MENU),
            relief=Gtk.ReliefStyle.NONE,
            tooltip_text=_(
                "Disable queue - the queue will be ignored when playing"))
        disabled = config.getboolean("memory", "queue_disable", False)
        toggle.props.active = disabled
        self.__queue_disable(disabled)
        toggle.connect('toggled',
                       lambda b: self.__queue_disable(b.props.active))
        outer.pack_start(toggle, False, False, 3)

        mode_menu = Gtk.Menu()

        norm_mode_item = RadioMenuItem(
            label=_("Ephemeral"),
            tooltip_text=_("Remove songs from the queue after playing them"),
            group=None)
        mode_menu.append(norm_mode_item)
        norm_mode_item.set_active(True)
        norm_mode_item.connect("toggled",
                               lambda _: self.__keep_songs_enable(False))

        keep_mode_item = RadioMenuItem(
            label=_("Persistent"),
            tooltip_text=_("Keep songs in the queue after playing them"),
            group=norm_mode_item)
        mode_menu.append(keep_mode_item)
        keep_mode_item.connect("toggled",
                               lambda b: self.__keep_songs_enable(True))
        keep_mode_item.set_active(
            config.getboolean("memory", "queue_keep_songs", False))

        mode_item = MenuItem(_("Mode"), Icons.SYSTEM_RUN)
        mode_item.set_submenu(mode_menu)
        menu.append(mode_item)

        rand_checkbox = ConfigCheckMenuItem(_("_Random"),
                                            "memory",
                                            "shufflequeue",
                                            populate=True)
        rand_checkbox.connect('toggled', self.__queue_shuffle)
        self.set_shuffled(rand_checkbox.get_active())
        menu.append(rand_checkbox)

        stop_checkbox = ConfigCheckMenuItem(_("Stop at End"),
                                            "memory",
                                            "queue_stop_at_end",
                                            populate=True)
        menu.append(stop_checkbox)

        button = SmallMenuButton(SymbolicIconImage(Icons.EMBLEM_SYSTEM,
                                                   Gtk.IconSize.MENU),
                                 arrow=True)
        button.set_relief(Gtk.ReliefStyle.NORMAL)
        button.show_all()
        button.hide()
        button.set_no_show_all(True)
        menu.show_all()
        button.set_menu(menu)

        outer.pack_start(button, False, False, 3)

        close_button = SmallImageButton(image=SymbolicIconImage(
            "window-close", Gtk.IconSize.MENU),
                                        relief=Gtk.ReliefStyle.NONE)

        close_button.connect("clicked", lambda *x: self.hide())

        outer.pack_start(close_button, False, False, 6)

        self.set_label_widget(outer)
        self.add(sw)
        self.connect('notify::expanded', self.__expand, button)
        self.connect('notify::expanded', self.__expand, button)

        targets = [("text/x-quodlibet-songs", Gtk.TargetFlags.SAME_APP,
                    DND_QL), ("text/uri-list", 0, DND_URI_LIST)]
        targets = [Gtk.TargetEntry.new(*t) for t in targets]

        self.drag_dest_set(Gtk.DestDefaults.ALL, targets, Gdk.DragAction.COPY)
        self.connect('drag-motion', self.__motion)
        self.connect('drag-data-received', self.__drag_data_received)

        self.queue.model.connect_after('row-inserted',
                                       DeferredSignal(self.__check_expand),
                                       count_label)
        self.queue.model.connect_after('row-deleted',
                                       DeferredSignal(self.__update_count),
                                       count_label)

        self.__update_count(self.model, None, count_label)

        connect_destroy(player, 'song-started', self.__update_state_icon,
                        state_icon)
        connect_destroy(player, 'paused', self.__update_state_icon_pause,
                        state_icon, True)
        connect_destroy(player, 'unpaused', self.__update_state_icon_pause,
                        state_icon, False)

        connect_destroy(player, 'song-started', self.__song_started,
                        self.queue.model)
        connect_destroy(player, 'song-ended', self.__update_queue_stop,
                        self.queue.model)

        # to make the children clickable if mapped
        # ....no idea why, but works
        def hack(expander):
            label = expander.get_label_widget()
            if label:
                label.unmap()
                label.map()

        self.connect("map", hack)

        self.set_expanded(config.getboolean("memory", "queue_expanded"))
        self.notify("expanded")

        for child in self.get_children():
            child.show_all()
Пример #20
0
class IndicatorMenu(Gtk.Menu):

    __gsignals__: GSignals = {
        'action-item-changed': (GObject.SignalFlags.RUN_LAST, None, tuple()),
    }

    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)

    def get_action_item(self):
        """Returns the 'Play' or 'Pause' action menu item (used for unity).
        'action-item-changed' gets emitted if this changes.
        """

        return self._action_item

    def set_paused(self, paused):
        """Update the menu based on the player paused state"""

        self._play_item.set_visible(paused)
        self._pause_item.set_visible(not paused)
        self._action_item = self._play_item if paused else self._pause_item
        self.emit("action-item-changed")

    def set_song(self, song):
        """Update the menu based on the passed song. Can be None.

        This should be the persistent song and not a stream/info one.
        """

        self._rating_item.set_sensitive(song is not None)
        self._info.set_sensitive(song is not None)
        self._props.set_sensitive(song is not None)
        self._rating_item.set_songs([song])
        self._new_playlist_submenu_for(song)

    def _new_playlist_submenu_for(self, song):
        submenu = self._playlists_item.get_submenu()
        if submenu:
            submenu.destroy()
        playlist_menu = PlaylistMenu([song], PlaylistsBrowser.playlists())

        def on_new(widget, playlist):
            PlaylistsBrowser.changed(playlist)

        playlist_menu.connect('new', on_new)
        self._playlists_item.set_submenu(playlist_menu)
        self._playlists_item.set_sensitive(bool(song) and song.can_add)
        self._playlists_item.show_all()

    def _on_play_pause(self, menuitem, player):
        player.playpause()
Пример #21
0
def TrashMenuItem():
    return (MenuItem(_("_Move to Trash"), "user-trash") if trash.can_trash()
            else Gtk.ImageMenuItem(Gtk.STOCK_DELETE, use_stock=True))
Пример #22
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(listmap(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())

        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())
Пример #23
0
class IndicatorMenu(Gtk.Menu):

    __gsignals__ = {
        'action-item-changed': (GObject.SignalFlags.RUN_LAST, None, tuple()),
    }

    def __init__(self, app, add_show_item=False):
        super(IndicatorMenu, self).__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()
                pconfig.set("window_visible", menuitem.get_active())

            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("random", shuffle, "active",
                                     GObject.BindingFlags.BIDIRECTIONAL)
        player_options.notify("random")

        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.DOCUMENT_PROPERTIES)

        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)

        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._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)

    def get_action_item(self):
        """Returns the 'Play' or 'Pause' action menu item (used for unity).
        'action-item-changed' gets emitted if this changes.
        """

        return self._action_item

    def set_paused(self, paused):
        """Update the menu based on the player paused state"""

        self._play_item.set_visible(paused)
        self._pause_item.set_visible(not paused)
        self._action_item = self._play_item if paused else self._pause_item
        self.emit("action-item-changed")

    def set_song(self, song):
        """Update the menu based on the passed song. Can be None.

        This should be the persistent song and not a stream/info one.
        """

        self._rating_item.set_sensitive(song is not None)
        self._info.set_sensitive(song is not None)
        self._props.set_sensitive(song is not None)
        self._rating_item.set_songs([song])

    def _on_play_pause(self, menuitem, player):
        if player.song:
            player.paused ^= True
        else:
            player.reset()
Пример #24
0
def TrashMenuItem():
    if trash.use_trash():
        return MenuItem(_("_Move to Trash"), Icons.USER_TRASH)
    else:
        return MenuItem(_("_Delete"), Icons.EDIT_DELETE)
Пример #25
0
    def __init__(self):
        super().__init__(spacing=6)

        self.model = model = ObjectStore()
        self.view = view = RCMHintedTreeView(model=model)
        view.set_fixed_height_mode(True)
        view.set_headers_visible(False)

        menu = Gtk.Menu()
        remove_item = MenuItem(_("_Remove"), Icons.LIST_REMOVE)
        menu.append(remove_item)
        menu.show_all()
        view.connect('popup-menu', self.__popup, menu)
        connect_obj(remove_item, 'activate', self.__remove, view)

        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))
        sw.set_tooltip_text(
            _("Songs in the listed folders will be added "
              "to the library during a library refresh"))
        render = Gtk.CellRendererText()
        render.set_property('ellipsize', Pango.EllipsizeMode.END)

        def cdf(column, cell, model, iter_, data):
            path = model.get_value(iter_)
            cell.set_property('text', fsn2text(unexpand(path)))

        column = Gtk.TreeViewColumn(None, render)
        column.set_cell_data_func(render, cdf)
        column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
        view.append_column(column)

        add = Button(_("_Add"), Icons.LIST_ADD)
        add.set_tooltip_text(
            _("The new directory will be scanned after adding"))
        add.connect("clicked", self.__add)
        remove = Button(_("_Remove"), Icons.LIST_REMOVE)
        remove.set_tooltip_text(
            _("All songs in the selected directories "
              "will also be removed from the library"))

        move = Button(_("_Move"), Icons.EDIT_REDO)
        move.connect("clicked", self.__move)
        move.set_tooltip_text(
            _("Move a scan root (but not the files), "
              "migrating metadata for all included tracks."))

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

        connect_obj(remove, "clicked", self.__remove, view)

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

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

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

        for child in self.get_children():
            child.show_all()
Пример #26
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)

        about = Gtk.Button()
        about.add(Gtk.Image.new_from_icon_name(
            Icons.HELP_ABOUT, Gtk.IconSize.BUTTON))
        connect_obj(about, 'clicked', self.__show_about, self)
        bbox.pack_start(about, False, True, 0)

        def prefs_cb(*args):
            window = PreferencesWindow(self)
            window.show()

        def plugin_window_cb(*args):
            window = PluginWindow(self)
            window.show()

        menu = Gtk.Menu()
        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)

        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)
Пример #27
0
    def __init__(self, app):
        super(DockMenu, self).__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:
            if Kind.is_empty:
                continue
            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()
Пример #28
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())
Пример #29
0
    def __init__(self, library, player):
        super(QueueExpander, self).__init__(spacing=3)
        sw = ScrolledWindow()
        sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        sw.set_shadow_type(Gtk.ShadowType.IN)
        self.queue = PlayQueue(library, player)
        self.queue.props.expand = True
        sw.add(self.queue)

        add_css(self, ".ql-expanded title { margin-bottom: 5px; }")

        outer = ExpandBoxHack()

        left = Gtk.HBox(spacing=12)

        hb2 = Gtk.HBox(spacing=3)
        state_icon = PlaybackStatusIcon()
        state_icon.stop()
        state_icon.show()
        hb2.pack_start(state_icon, True, True, 0)
        name_label = Gtk.Label(label=_("_Queue"), use_underline=True)
        name_label.set_size_request(-1, 24)
        hb2.pack_start(name_label, True, True, 0)
        left.pack_start(hb2, False, True, 0)

        menu = Gtk.Menu()

        self.count_label = count_label = Gtk.Label()
        self.count_label.set_property("ellipsize", Pango.EllipsizeMode.END)
        self.count_label.set_width_chars(10)
        self.count_label.get_style_context().add_class("dim-label")
        left.pack_start(count_label, False, True, 0)

        outer.pack_start(left, True, True, 0)

        self.set_label_fill(True)

        rand_checkbox = ConfigCheckMenuItem(
                _("_Random"), "memory", "shufflequeue", populate=True)
        rand_checkbox.connect('toggled', self.__queue_shuffle)
        self.set_shuffled(rand_checkbox.get_active())
        menu.append(rand_checkbox)

        stop_checkbox = ConfigCheckMenuItem(
            _("Stop Once Empty"), "memory", "queue_stop_once_empty",
            populate=True)
        menu.append(stop_checkbox)

        clear_item = MenuItem(_("_Clear Queue"), Icons.EDIT_CLEAR)
        menu.append(clear_item)
        clear_item.connect("activate", self.__clear_queue)

        button = SmallMenuButton(
            SymbolicIconImage(Icons.EMBLEM_SYSTEM, Gtk.IconSize.MENU),
            arrow=True)
        button.set_relief(Gtk.ReliefStyle.NONE)
        button.show_all()
        button.hide()
        button.set_no_show_all(True)
        menu.show_all()
        button.set_menu(menu)

        outer.pack_start(button, False, False, 0)

        close_button = SmallImageButton(
            image=SymbolicIconImage("window-close", Gtk.IconSize.MENU),
            relief=Gtk.ReliefStyle.NONE)

        close_button.connect("clicked", lambda *x: self.hide())

        outer.pack_start(close_button, False, False, 6)

        self.set_label_widget(outer)
        self.add(sw)
        self.connect('notify::expanded', self.__expand, button)
        self.connect('notify::expanded', self.__expand, button)

        targets = [
            ("text/x-quodlibet-songs", Gtk.TargetFlags.SAME_APP, DND_QL),
            ("text/uri-list", 0, DND_URI_LIST)
        ]
        targets = [Gtk.TargetEntry.new(*t) for t in targets]

        self.drag_dest_set(Gtk.DestDefaults.ALL, targets, Gdk.DragAction.COPY)
        self.connect('drag-motion', self.__motion)
        self.connect('drag-data-received', self.__drag_data_received)

        self.queue.model.connect_after('row-inserted',
            util.DeferredSignal(self.__check_expand), count_label)
        self.queue.model.connect_after('row-deleted',
            util.DeferredSignal(self.__update_count), count_label)

        self.__update_count(self.model, None, count_label)

        connect_destroy(
            player, 'song-started', self.__update_state_icon, state_icon)
        connect_destroy(
            player, 'paused', self.__update_state_icon_pause,
            state_icon, True)
        connect_destroy(
            player, 'unpaused', self.__update_state_icon_pause,
            state_icon, False)

        connect_destroy(
            player, 'song-started', self.__song_started, self.queue.model)
        connect_destroy(
            player, 'song-ended', self.__update_queue_stop, self.queue.model)

        self._last_queue_song = None

        # to make the children clickable if mapped
        # ....no idea why, but works
        def hack(expander):
            label = expander.get_label_widget()
            if label:
                label.unmap()
                label.map()
        self.connect("map", hack)

        self.set_expanded(config.getboolean("memory", "queue_expanded"))
        self.notify("expanded")

        for child in self.get_children():
            child.show_all()
Пример #30
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()
Пример #31
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(
                            list(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())

        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())
Пример #32
0
    def __init__(self, library, main):
        super(InternetRadio, self).__init__(spacing=12)

        if not self.instances():
            self._init(library)
        self._register_instance()

        self.connect('destroy', self.__destroy)

        completion = LibraryTagCompletion(self.__stations)
        self.accelerators = Gtk.AccelGroup()
        self.__searchbar = search = SearchBarBox(completion=completion,
                                                 accel_group=self.accelerators)
        gobject_weak(search.connect, 'query-changed', self.__filter_changed)

        menu = Gtk.Menu()
        new_item = MenuItem(_("_New Station..."), Gtk.STOCK_ADD)
        gobject_weak(new_item.connect, 'activate', self.__add)
        menu.append(new_item)
        update_item = MenuItem(_("_Update Stations"), Gtk.STOCK_REFRESH)
        gobject_weak(update_item.connect, 'activate', self.__update)
        menu.append(update_item)
        menu.show_all()

        button = MenuButton(
            SymbolicIconImage("emblem-system", Gtk.IconSize.MENU),
            arrow=True)
        button.set_menu(menu)

        def focus(widget, *args):
            qltk.get_top_parent(widget).songlist.grab_focus()
        gobject_weak(search.connect, 'focus-out', focus, parent=self)

        # treeview
        scrolled_window = ScrolledWindow()
        scrolled_window.set_shadow_type(Gtk.ShadowType.IN)
        self.view = view = AllTreeView()
        view.set_headers_visible(False)
        scrolled_window.set_policy(
            Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
        scrolled_window.add(view)
        model = Gtk.ListStore(int, str, str, str)

        model.append(row=[self.TYPE_ALL, Gtk.STOCK_DIRECTORY, "__all",
                          _("All Stations")])
        model.append(row=[self.TYPE_SEP, Gtk.STOCK_DIRECTORY, "", ""])
        #Translators: Favorite radio stations
        model.append(row=[self.TYPE_FAV, Gtk.STOCK_DIRECTORY, "__fav",
                          _("Favorites")])
        model.append(row=[self.TYPE_SEP, Gtk.STOCK_DIRECTORY, "", ""])

        filters = self.filters
        for text, k in sorted([(filters.text(k), k) for k in filters.keys()]):
            model.append(row=[self.TYPE_FILTER, Gtk.STOCK_FIND, k, text])

        model.append(row=[self.TYPE_NOCAT, Gtk.STOCK_DIRECTORY,
                          "nocat", _("No Category")])

        def separator(model, iter, data):
            return model[iter][self.TYPE] == self.TYPE_SEP
        view.set_row_separator_func(separator, None)

        def search_func(model, column, key, iter, data):
            return key.lower() not in model[iter][column].lower()
        view.set_search_column(self.NAME)
        view.set_search_equal_func(search_func, None)

        column = Gtk.TreeViewColumn("genres")
        column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)

        renderpb = Gtk.CellRendererPixbuf()
        renderpb.props.xpad = 3
        column.pack_start(renderpb, False)
        column.add_attribute(renderpb, "stock_id", self.STOCK)

        render = Gtk.CellRendererText()
        render.set_property('ellipsize', Pango.EllipsizeMode.END)
        view.append_column(column)
        column.pack_start(render, True)
        column.add_attribute(render, "text", self.NAME)

        view.set_model(model)

        # selection
        selection = view.get_selection()
        selection.set_mode(Gtk.SelectionMode.MULTIPLE)
        self.__changed_sig = gobject_weak(selection.connect, 'changed',
            util.DeferredSignal(lambda x: self.activate()), parent=view)

        box = Gtk.HBox(spacing=6)
        box.pack_start(search, True, True, 0)
        box.pack_start(button, False, True, 0)
        if main:
            self.pack_start(Alignment(box, left=6, right=6, top=6),
                            True, True, 0)
        else:
            self.pack_start(box, True, True, 0)
        self.__filter_list = scrolled_window

        def qbar_response(infobar, response_id):
            if response_id == infobar.RESPONSE_LOAD:
                self.__update()

        self.qbar = QuestionBar()
        self.qbar.connect("response", qbar_response)
        if self._is_library_empty():
            self.qbar.show()

        self.show_all()
Пример #33
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)
Пример #34
0
    def __init__(self, library):
        super(InternetRadio, self).__init__(spacing=12)
        self.set_orientation(Gtk.Orientation.VERTICAL)

        if not self.instances():
            self._init(library)
        self._register_instance()

        self.connect("destroy", self.__destroy)

        completion = LibraryTagCompletion(self.__stations)
        self.accelerators = Gtk.AccelGroup()
        self.__searchbar = search = SearchBarBox(completion=completion, accel_group=self.accelerators)
        search.connect("query-changed", self.__filter_changed)

        menu = Gtk.Menu()
        new_item = MenuItem(_(u"_New Station…"), Icons.LIST_ADD)
        new_item.connect("activate", self.__add)
        menu.append(new_item)
        update_item = MenuItem(_("_Update Stations"), Icons.VIEW_REFRESH)
        update_item.connect("activate", self.__update)
        menu.append(update_item)
        menu.show_all()

        button = MenuButton(SymbolicIconImage(Icons.EMBLEM_SYSTEM, Gtk.IconSize.MENU), arrow=True)
        button.set_menu(menu)

        def focus(widget, *args):
            qltk.get_top_parent(widget).songlist.grab_focus()

        search.connect("focus-out", focus)

        # treeview
        scrolled_window = ScrolledWindow()
        scrolled_window.show()
        scrolled_window.set_shadow_type(Gtk.ShadowType.IN)
        self.view = view = AllTreeView()
        view.show()
        view.set_headers_visible(False)
        scrolled_window.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
        scrolled_window.add(view)
        model = Gtk.ListStore(int, str, str, str)

        model.append(row=[self.TYPE_ALL, Icons.FOLDER, "__all", _("All Stations")])
        model.append(row=[self.TYPE_SEP, Icons.FOLDER, "", ""])
        # Translators: Favorite radio stations
        model.append(row=[self.TYPE_FAV, Icons.FOLDER, "__fav", _("Favorites")])
        model.append(row=[self.TYPE_SEP, Icons.FOLDER, "", ""])

        filters = self.filters
        for text, k in sorted([(filters.text(k), k) for k in filters.keys()]):
            model.append(row=[self.TYPE_FILTER, Icons.EDIT_FIND, k, text])

        model.append(row=[self.TYPE_NOCAT, Icons.FOLDER, "nocat", _("No Category")])

        def separator(model, iter, data):
            return model[iter][self.TYPE] == self.TYPE_SEP

        view.set_row_separator_func(separator, None)

        def search_func(model, column, key, iter, data):
            return key.lower() not in model[iter][column].lower()

        view.set_search_column(self.NAME)
        view.set_search_equal_func(search_func, None)

        column = Gtk.TreeViewColumn("genres")
        column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)

        renderpb = Gtk.CellRendererPixbuf()
        renderpb.props.xpad = 3
        column.pack_start(renderpb, False)
        column.add_attribute(renderpb, "icon-name", self.ICON_NAME)

        render = Gtk.CellRendererText()
        render.set_property("ellipsize", Pango.EllipsizeMode.END)
        view.append_column(column)
        column.pack_start(render, True)
        column.add_attribute(render, "text", self.NAME)

        view.set_model(model)

        # selection
        selection = view.get_selection()
        selection.set_mode(Gtk.SelectionMode.MULTIPLE)
        self.__changed_sig = connect_destroy(selection, "changed", util.DeferredSignal(lambda x: self.activate()))

        box = Gtk.HBox(spacing=6)
        box.pack_start(search, True, True, 0)
        box.pack_start(button, False, True, 0)
        self._searchbox = Align(box, left=0, right=6, top=6)
        self._searchbox.show_all()

        def qbar_response(infobar, response_id):
            if response_id == infobar.RESPONSE_LOAD:
                self.__update()

        self.qbar = QuestionBar()
        self.qbar.connect("response", qbar_response)
        if self._is_library_empty():
            self.qbar.show()

        pane = qltk.ConfigRHPaned("browsers", "internetradio_pos", 0.4)
        pane.show()
        pane.pack1(scrolled_window, resize=False, shrink=False)
        songbox = Gtk.VBox(spacing=6)
        songbox.pack_start(self._searchbox, False, True, 0)
        self._songpane_container = Gtk.VBox()
        self._songpane_container.show()
        songbox.pack_start(self._songpane_container, True, True, 0)
        songbox.pack_start(self.qbar, False, True, 0)
        songbox.show()
        pane.pack2(songbox, resize=True, shrink=False)
        self.pack_start(pane, True, True, 0)
        self.show()
Пример #35
0
    def __init__(self, Prototype, values, filename, title):
        if self.is_not_unique():
            return
        super(JSONBasedEditor, self).__init__()
        self.Prototype = Prototype
        self.current = None
        self.filename = filename
        self.name = Prototype.NAME or Prototype.__name__
        self.input_entries = {}
        self.set_border_width(12)
        self.set_title(title)
        self.set_default_size(self._WIDTH, self._HEIGHT)

        self.add(Gtk.HBox(spacing=6))
        self.get_child().set_homogeneous(True)
        self.accels = Gtk.AccelGroup()

        # Set up the model for this widget
        self.model = Gtk.ListStore(object)
        self._fill_values(values)

        # The browser for existing data
        self.view = view = RCMHintedTreeView(model=self.model)
        view.set_headers_visible(False)
        view.set_reorderable(True)
        view.set_rules_hint(True)
        render = Gtk.CellRendererText()
        render.set_padding(3, 6)
        render.props.ellipsize = Pango.EllipsizeMode.END
        column = Gtk.TreeViewColumn("", render)
        column.set_cell_data_func(render, self.__cdf)
        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)

        vbox = Gtk.VBox(spacing=6)
        # Input for new ones.
        frame = self.__build_input_frame()
        vbox.pack_start(frame, False, True, 0)

        # Add context menu
        menu = Gtk.Menu()
        rem = MenuItem(_("_Remove"), Icons.LIST_REMOVE)
        keyval, mod = Gtk.accelerator_parse("Delete")
        rem.add_accelerator(
            'activate', self.accels, keyval, mod, Gtk.AccelFlags.VISIBLE)
        connect_obj(rem, 'activate', self.__remove, view)
        menu.append(rem)
        menu.show_all()
        view.connect('popup-menu', self.__popup, menu)
        view.connect('key-press-event', self.__view_key_press)
        connect_obj(self, 'destroy', Gtk.Menu.destroy, menu)

        # New and Close buttons
        bbox = Gtk.HButtonBox()
        self.remove_but = Button(_("_Remove"), Icons.LIST_REMOVE)
        self.remove_but.set_sensitive(False)
        self.new_but = Button(_("_New"), Icons.DOCUMENT_NEW)
        self.new_but.connect('clicked', self._new_item)
        bbox.pack_start(self.new_but, True, True, 0)
        close = Button(_("_Close"), Icons.WINDOW_CLOSE)
        connect_obj(close, 'clicked', qltk.Window.destroy, self)
        bbox.pack_start(close, True, True, 0)
        vbox.pack_end(bbox, False, True, 0)

        self.get_child().pack_start(vbox, True, True, 0)
        # Initialise
        self.selection = view.get_selection()

        self.selection.connect('changed', self.__select)
        self.connect('destroy', self.__finish)
        self.get_child().show_all()
Пример #36
0
    def __init__(self, library):
        super(InternetRadio, self).__init__(spacing=12)
        self.set_orientation(Gtk.Orientation.VERTICAL)

        if not self.instances():
            self._init(library)
        self._register_instance()

        self.connect('destroy', self.__destroy)

        completion = LibraryTagCompletion(self.__stations)
        self.accelerators = Gtk.AccelGroup()
        self.__searchbar = search = SearchBarBox(completion=completion,
                                                 accel_group=self.accelerators)
        search.connect('query-changed', self.__filter_changed)

        menu = Gtk.Menu()
        new_item = MenuItem(_(u"_New Station…"), Icons.LIST_ADD)
        new_item.connect('activate', self.__add)
        menu.append(new_item)
        update_item = MenuItem(_("_Update Stations"), Icons.VIEW_REFRESH)
        update_item.connect('activate', self.__update)
        menu.append(update_item)
        menu.show_all()

        button = MenuButton(SymbolicIconImage(Icons.EMBLEM_SYSTEM,
                                              Gtk.IconSize.MENU),
                            arrow=True)
        button.set_menu(menu)

        def focus(widget, *args):
            qltk.get_top_parent(widget).songlist.grab_focus()

        search.connect('focus-out', focus)

        # treeview
        scrolled_window = ScrolledWindow()
        scrolled_window.show()
        scrolled_window.set_shadow_type(Gtk.ShadowType.IN)
        self.view = view = AllTreeView()
        view.show()
        view.set_headers_visible(False)
        scrolled_window.set_policy(Gtk.PolicyType.NEVER,
                                   Gtk.PolicyType.AUTOMATIC)
        scrolled_window.add(view)
        model = Gtk.ListStore(int, str, str, str)

        model.append(
            row=[self.TYPE_ALL, Icons.FOLDER, "__all",
                 _("All Stations")])
        model.append(row=[self.TYPE_SEP, Icons.FOLDER, "", ""])
        #Translators: Favorite radio stations
        model.append(
            row=[self.TYPE_FAV, Icons.FOLDER, "__fav",
                 _("Favorites")])
        model.append(row=[self.TYPE_SEP, Icons.FOLDER, "", ""])

        filters = self.filters
        for text, k in sorted([(filters.text(k), k) for k in filters.keys()]):
            model.append(row=[self.TYPE_FILTER, Icons.EDIT_FIND, k, text])

        model.append(
            row=[self.TYPE_NOCAT, Icons.FOLDER, "nocat",
                 _("No Category")])

        def separator(model, iter, data):
            return model[iter][self.TYPE] == self.TYPE_SEP

        view.set_row_separator_func(separator, None)

        def search_func(model, column, key, iter, data):
            return key.lower() not in model[iter][column].lower()

        view.set_search_column(self.NAME)
        view.set_search_equal_func(search_func, None)

        column = Gtk.TreeViewColumn("genres")
        column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)

        renderpb = Gtk.CellRendererPixbuf()
        renderpb.props.xpad = 3
        column.pack_start(renderpb, False)
        column.add_attribute(renderpb, "icon-name", self.ICON_NAME)

        render = Gtk.CellRendererText()
        render.set_property('ellipsize', Pango.EllipsizeMode.END)
        view.append_column(column)
        column.pack_start(render, True)
        column.add_attribute(render, "text", self.NAME)

        view.set_model(model)

        # selection
        selection = view.get_selection()
        selection.set_mode(Gtk.SelectionMode.MULTIPLE)
        self.__changed_sig = connect_destroy(
            selection, 'changed',
            util.DeferredSignal(lambda x: self.activate()))

        box = Gtk.HBox(spacing=6)
        box.pack_start(search, True, True, 0)
        box.pack_start(button, False, True, 0)
        self._searchbox = Align(box, left=0, right=6, top=6)
        self._searchbox.show_all()

        def qbar_response(infobar, response_id):
            if response_id == infobar.RESPONSE_LOAD:
                self.__update()

        self.qbar = QuestionBar()
        self.qbar.connect("response", qbar_response)
        if self._is_library_empty():
            self.qbar.show()

        pane = qltk.ConfigRHPaned("browsers", "internetradio_pos", 0.4)
        pane.show()
        pane.pack1(scrolled_window, resize=False, shrink=False)
        songbox = Gtk.VBox(spacing=6)
        songbox.pack_start(self._searchbox, False, True, 0)
        self._songpane_container = Gtk.VBox()
        self._songpane_container.show()
        songbox.pack_start(self._songpane_container, True, True, 0)
        songbox.pack_start(self.qbar, False, True, 0)
        songbox.show()
        pane.pack2(songbox, resize=True, shrink=False)
        self.pack_start(pane, True, True, 0)
        self.show()
Пример #37
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)

        about = Gtk.Button()
        about.add(
            Gtk.Image.new_from_icon_name(Icons.HELP_ABOUT,
                                         Gtk.IconSize.BUTTON))
        connect_obj(about, 'clicked', self.__show_about, self)
        bbox.pack_start(about, False, True, 0)

        def prefs_cb(*args):
            window = PreferencesWindow(self)
            window.show()

        def plugin_window_cb(*args):
            window = PluginWindow(self)
            window.show()

        menu = Gtk.Menu()
        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)

        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)
Пример #38
0
    def __init__(self, app, add_show_item=False):
        super(IndicatorMenu, self).__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()
                pconfig.set("window_visible", menuitem.get_active())

            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("random", shuffle, "active",
                                     GObject.BindingFlags.BIDIRECTIONAL)
        player_options.notify("random")

        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.DOCUMENT_PROPERTIES)

        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)

        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._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)
Пример #39
0
    def __init__(self, title, values=None):
        super(TagListEditor, self).__init__()
        self.use_header_bar()
        self.data = values or []
        self.set_border_width(12)
        self.set_title(title)
        self.set_default_size(self._WIDTH, self._HEIGHT)

        vbox = Gtk.VBox(spacing=12)
        hbox = Gtk.HBox(spacing=12)

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

        # Main view
        view = self.view = HintedTreeView(model=self.model)
        view.set_fixed_height_mode(True)
        view.set_headers_visible(False)

        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, 100))
        hbox.pack_start(sw, True, True, 0)

        self.__setup_column(view)

        # Context menu
        menu = Gtk.Menu()
        remove_item = MenuItem(_("_Remove"), Icons.LIST_REMOVE)
        menu.append(remove_item)
        menu.show_all()
        view.connect('popup-menu', self.__popup, menu)
        connect_obj(remove_item, 'activate', self.__remove, view)

        # Add and Remove buttons
        vbbox = Gtk.VButtonBox()
        vbbox.set_layout(Gtk.ButtonBoxStyle.START)
        vbbox.set_spacing(6)
        add = Button(_("_Add"), Icons.LIST_ADD)
        add.connect("clicked", self.__add)
        vbbox.pack_start(add, False, True, 0)
        remove = Button(_("_Remove"), Icons.LIST_REMOVE)
        remove.connect("clicked", self.__remove)
        vbbox.pack_start(remove, False, True, 0)
        hbox.pack_start(vbbox, False, True, 0)
        vbox.pack_start(hbox, True, True, 0)

        # Close buttons
        bbox = Gtk.HButtonBox()
        self.remove_but = Button(_("_Remove"), Icons.LIST_REMOVE)
        self.remove_but.set_sensitive(False)
        close = Button(_("_Close"), Icons.WINDOW_CLOSE)
        connect_obj(close, 'clicked', qltk.Window.destroy, self)
        bbox.set_layout(Gtk.ButtonBoxStyle.END)
        if not self.has_close_button():
            bbox.pack_start(close, True, True, 0)
            vbox.pack_start(bbox, False, True, 0)

        # Finish up
        self.add(vbox)
        self.get_child().show_all()
Пример #40
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())
Пример #41
0
    def __init__(self, Prototype, values, filename, title):
        if self.is_not_unique():
            return
        super(JSONBasedEditor, self).__init__()
        self.Prototype = Prototype
        self.current = None
        self.filename = filename
        self.name = Prototype.NAME or Prototype.__name__
        self.input_entries = {}
        self.set_border_width(12)
        self.set_title(title)
        self.set_default_size(self._WIDTH, self._HEIGHT)

        self.add(Gtk.HBox(spacing=6))
        self.get_child().set_homogeneous(True)
        self.accels = Gtk.AccelGroup()

        # Set up the model for this widget
        self.model = Gtk.ListStore(object)
        self._fill_values(values)

        # The browser for existing data
        self.view = view = RCMHintedTreeView(model=self.model)
        view.set_headers_visible(False)
        view.set_reorderable(True)
        view.set_rules_hint(True)
        render = Gtk.CellRendererText()
        render.set_padding(3, 6)
        render.props.ellipsize = Pango.EllipsizeMode.END
        column = Gtk.TreeViewColumn("", render)
        column.set_cell_data_func(render, self.__cdf)
        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)

        vbox = Gtk.VBox(spacing=6)
        # Input for new ones.
        frame = self.__build_input_frame()
        vbox.pack_start(frame, False, True, 0)

        # Add context menu
        menu = Gtk.Menu()
        rem = MenuItem(_("_Remove"), Icons.LIST_REMOVE)
        keyval, mod = Gtk.accelerator_parse("Delete")
        rem.add_accelerator('activate', self.accels, keyval, mod,
                            Gtk.AccelFlags.VISIBLE)
        connect_obj(rem, 'activate', self.__remove, view)
        menu.append(rem)
        menu.show_all()
        view.connect('popup-menu', self.__popup, menu)
        view.connect('key-press-event', self.__view_key_press)
        connect_obj(self, 'destroy', Gtk.Menu.destroy, menu)

        # New and Close buttons
        bbox = Gtk.HButtonBox()
        self.remove_but = Button(_("_Remove"), Icons.LIST_REMOVE)
        self.remove_but.set_sensitive(False)
        self.new_but = Button(_("_New"), Icons.DOCUMENT_NEW)
        self.new_but.connect('clicked', self._new_item)
        bbox.pack_start(self.new_but, True, True, 0)
        close = Button(_("_Close"), Icons.WINDOW_CLOSE)
        connect_obj(close, 'clicked', qltk.Window.destroy, self)
        bbox.pack_start(close, True, True, 0)
        vbox.pack_end(bbox, False, True, 0)

        self.get_child().pack_start(vbox, True, True, 0)
        # Initialise
        self.selection = view.get_selection()

        self.selection.connect('changed', self.__select)
        self.connect('destroy', self.__finish)
        self.get_child().show_all()