Пример #1
0
def __create_help_menu():
    items = []
    accelerators = []
    
    def show_report_issue(*args):
        webbrowser.open('https://github.com/exaile/exaile/issues')
        
    def show_user_guide(*args):
        # TODO: Other languages
        webbrowser.open('http://exaile.readthedocs.org/en/latest/user/index.html')
    
    def show_about_dialog(widget, name, parent, context):
        dialog = dialogs.AboutDialog(parent.window)
        dialog.show()
    
    items.append(_smi('guide', [], _("User's Guide (website)"), 'help',
        show_user_guide))
    items.append(_smi('report', [items[-1].name], _("Report an issue (GitHub)"), None,
        show_report_issue))
    items.append(_sep('about-sep', [items[-1].name]))
    items.append(_smi('about', [items[-1].name], _("_About"), 'help-about',
        show_about_dialog))
    for item in items:
        providers.register('menubar-help-menu', item)
    for accelerator in accelerators:
        providers.register('mainwindow-accelerators', accelerator)
Пример #2
0
    def check_login(self):
        """
            Tries to connect to the AudioScrobbler
            service with the existing login data
        """
        username = settings.get_option('plugin/ascrobbler/user', '')
        password = settings.get_option('plugin/ascrobbler/password', '')
        url = settings.get_option(
            'plugin/ascrobbler/url', 'http://post.audioscrobbler.com/'
        )
        login_verified = False

        try:
            _scrobbler.login(username, password, post_url=url)
        except _scrobbler.AuthError:
            try:
                _scrobbler.login(username, password, hashpw=True, post_url=url)
            except _scrobbler.AuthError:
                pass
            else:
                login_verified = True
        else:
            login_verified = True

        if login_verified:
            GLib.idle_add(self.message.show_info, _('Verification successful'), '')
        else:
            GLib.idle_add(
                self.message.show_error,
                _('Verification failed'),
                _('Please make sure the entered data is correct.'),
            )

        GLib.idle_add(self.widget.set_sensitive, True)
Пример #3
0
    def __update(self, volume):
        """
            Sets the volume level indicator
        """
        icon_name = 'audio-volume-muted'
        tooltip = _('Muted')

        if volume > 0:
            i = clamp(int(round(volume * 2)), 0, len(self.icon_names) - 1)
            icon_name = 'audio-volume-%s' % self.icon_names[i]
            #TRANSLATORS: Volume percentage
            tooltip = _('%d%%') % (volume * 100)
        else:
            volume = 0

        if volume == 1.0:
            tooltip = _('Full Volume')

        if volume > 0:
            self.button.set_active(False)

        self.button_image.set_from_icon_name(icon_name, Gtk.IconSize.BUTTON)
        self.button.set_tooltip_text(tooltip)
        self.slider.set_value(volume)
        self.slider.set_tooltip_text(tooltip)
Пример #4
0
 def __init__(self, title):
     dialogs.ListDialog.__init__(self, title)
     col = self.list.get_column(0)
     col.set_title(_('Name'))
     col.set_expand(True)
     col.set_resizable(True)
     self.list.set_headers_visible(True)
     text = Gtk.CellRendererText()
     text.set_property('xalign', 1.0)
     col = Gtk.TreeViewColumn(_('Bitrate'), text)
     col.set_cell_data_func(
         text,
         lambda column, cell, model, iter: cell.set_property(
             'text', model.get_value(iter, 0).bitrate
         ),
     )
     self.list.append_column(col)
     text = Gtk.CellRendererText()
     text.set_property('xalign', 0.5)
     col = Gtk.TreeViewColumn(_('Format'), text)
     col.set_cell_data_func(
         text,
         lambda column, cell, model, iter: cell.set_property(
             'text', model.get_value(iter, 0).format
         ),
     )
     self.list.append_column(col)
Пример #5
0
    def factory(self, menu, parent, context):
        """
            Sets up the menu item
        """
        item = Gtk.ImageMenuItem.new_with_mnemonic(_('_Love This Track'))
        item.set_image(Gtk.Image.new_from_icon_name('love', Gtk.IconSize.MENU))

        if self.get_tracks_function is not None:
            tracks = self.get_tracks_function()
            empty = len(tracks) == 0
        else:
            empty = context.get('selection-empty', True)
            if not empty:
                tracks = context.get('selected-tracks', [])

        if not empty and self.__lastfmlover.network is not None:
            # We only care about the first track
            track = tracks[0]
            lastfm_track = pylast.Track(
                track.get_tag_display('artist'),
                track.get_tag_display('title'),
                self.__lastfmlover.network,
            )

            if lastfm_track in self.__lastfmlover.loved_tracks:
                item.set_label(_('Unlove This Track'))

            item.connect('activate', self.on_activate, track)
        else:
            item.set_sensitive(False)

        return item
Пример #6
0
    def rename_playlist(self, playlist):
        """
            Renames the playlist
        """
        
        if playlist is None:
            return
        
        # Ask for new name
        dialog = dialogs.TextEntryDialog(
            _("Enter the new name you want for your playlist"),
            _("Rename Playlist"), playlist.name)
        
        result = dialog.run()
        name = dialog.get_value()
        
        dialog.destroy()
        
        if result != Gtk.ResponseType.OK or name == '':
            return
                
        if name in self.playlist_manager.playlists:
            # name is already in use
            dialogs.error(self.parent, _("The "
                "playlist name you entered is already in use."))
            return

        selection = self.tree.get_selection()
        (model, iter) = selection.get_selected()
        model.set_value(iter, 1, name)
        
        # Update the manager aswell
        self.playlist_manager.rename_playlist(playlist, name)
Пример #7
0
    def _load_playlists(self):
        """
            Loads the currently saved playlists
        """
        self.smart = self.model.append(None, [self.folder,
            _("Smart Playlists"), None])

        self.custom = self.model.append(None, [self.folder,
            _("Custom Playlists"), None])

        names = self.smart_manager.playlists[:]
        names.sort()
        for name in names:
            self.model.append(self.smart, [self.playlist_image, name,
                self.smart_manager.get_playlist(name)])

        names = self.playlist_manager.playlists[:]
        names.sort()
        for name in names:
            playlist = self.playlist_manager.get_playlist(name)
            self.playlist_nodes[playlist] = self.model.append(
                self.custom, [self.playlist_image, name, playlist])
            self._load_playlist_nodes(playlist)

        self.tree.expand_row(self.model.get_path(self.smart), False)
        self.tree.expand_row(self.model.get_path(self.custom), False)
Пример #8
0
def __create_marker_context_menu():
    items = []

    def on_jumpto_item_activate(widget, name, parent, context):
        # parent.seek(context['current-marker'].props.position)
        position = context['current-marker'].props.position
        player.PLAYER.set_progress(position)

    def on_remove_item_activate(widget, name, parent, context):
        providers.unregister('playback-markers', context['current-marker'])

    items.append(
        menu.simple_menu_item(
            'jumpto-marker', [], _("_Jump to"), 'go-jump', on_jumpto_item_activate
        )
    )
    items.append(MoveMarkerMenuItem('move-marker', [items[-1].name]))
    items.append(
        menu.simple_menu_item(
            'remove-marker',
            [items[-1].name],
            _("_Remove Marker"),
            'list-remove',
            on_remove_item_activate,
        )
    )

    for item in items:
        providers.register('playback-marker-context-menu', item)
Пример #9
0
    def format(self, track, parameters):
        """
            Formats a raw tag value

            :param track: the track to get the tag from
            :type track: :class:`xl.trax.Track`
            :param parameters: optionally passed parameters
            :type parameters: dictionary
            :returns: the formatted value
            :rtype: string
        """
        value = track.get_tag_raw(self.name)
        # TRANSLATORS: Indicates that a track has never been played before
        text = _('Never')

        try:
            last_played = date.fromtimestamp(value)
        except (TypeError, ValueError):
            text = _('Never')
        else:
            today = date.today()
            delta = today - last_played

            if delta.days == 0:
                text = _('Today')
            elif delta.days == 1:
                text = _('Yesterday')
            else:
                text = last_played.strftime('%x')

        return text
Пример #10
0
    def __init__(self, all_button=True):
        gtk.HBox.__init__(self, homogeneous=False, spacing=5)

        self.parent_row = None
        self.all_func = None
        self.update_func = None
        # Prevents the update function from being called, make 
        # sure you do that manually after the batch update
        self.batch_update = False

        self.pixbuf = None
        self.info = CoverImage(None, None, None, None)
        self.default_type = 3
        self.mime_info = {
            'image/jpeg': {
                # Title for display
                'title': _('JPEG image'),
                # Type and options for GDK Pixbuf saving
                'type': 'jpeg',
                'options': {'quality': '90'}
            },
            'image/png': {
                'title': _('PNG image'),
                'type': 'png',
                'options': {}
            },
            'image/': {
                'title': _('Image'),
                # Store unknown images as JPEG
                'type': 'jpeg',
                'options': {'quality': '90'}
            },
            # TODO: Handle linked images
            '-->': {
                'title': _('Linked image')
            }
        }

        builder = gtk.Builder()
        builder.add_from_file(xdg.get_data_path('ui', 'trackproperties_dialog_cover_row.ui'))
        builder.connect_signals(self)
        cover_row = builder.get_object('cover_row')
        cover_row.reparent(self)

        button = builder.get_object('button')
        button.drag_dest_set(gtk.DEST_DEFAULT_ALL, [], gtk.gdk.ACTION_COPY)
        button.drag_dest_add_uri_targets()

        self.image = builder.get_object('image')
        self.info_label = builder.get_object('info_label')
        self.type_model = builder.get_object('type_model')
        self.type_selection = builder.get_object('type_selection')
        self.type_selection.set_sensitive(False)
        self.description_entry = builder.get_object('description_entry')
        self.description_entry.set_sensitive(False)

        self.all_button = None
        if all_button:
            self.all_button = AllButton(self)
            self.pack_start(self.all_button, expand=False, fill=False)
Пример #11
0
    def set_pixbuf(self, pixbuf, mime=None):
        """
            Updates the displayed cover image and info values
        """
        self.pixbuf = pixbuf

        if pixbuf is None:
            self.image.set_from_icon_name('list-add', Gtk.IconSize.DIALOG)
            self.info_label.set_markup('')
        else:
            self.image.set_from_pixbuf(pixbuf.scale_simple(
                100, 100, GdkPixbuf.InterpType.BILINEAR))

            width, height = pixbuf.get_width(), pixbuf.get_height()
            if mime is None:
                # TRANSLATORS: do not translate 'width' and 'height'
                markup = _('{width}x{height} pixels').format(width=width, height=height)
            else:
                # TRANSLATORS: do not translate 'format', 'width', and 'height'
                markup = _('{format} ({width}x{height} pixels)').format(
                    format=self.mime_info.get(mime, self.mime_info['image/'])['title'],
                    width=width, height=height
                )
            self.info_label.set_markup(markup)

            self.info = self.info._replace(mime=mime)
Пример #12
0
    def __init__(self, playlist, parent=None):
        """
            :param playlist: the playlist to export
            :type playlist: :class:`xl.playlist.Playlist`
            :param parent: a parent window for modal operation or None
            :type parent: :class:`gtk.Window`
        """
        FileOperationDialog.__init__(self,
            title=_('Export Current Playlist'),
            parent=parent,
            action=gtk.FILE_CHOOSER_ACTION_SAVE,
            buttons=(
                gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                gtk.STOCK_SAVE, gtk.RESPONSE_OK
            )
        )

        self.set_local_only(False)

        self.relative_checkbox = gtk.CheckButton(_('Use relative paths to tracks'))
        self.relative_checkbox.set_active(True)
        self.extras_box.pack_start(self.relative_checkbox, False, False, 3)
        self.relative_checkbox.show()

        self.playlist = playlist

        extensions = {}

        for provider in providers.get('playlist-format-converter'):
            extensions[provider.name] = provider.title

        self.add_extensions(extensions)
        self.set_current_name('%s.m3u' % playlist.name)

        self.connect('response', self.on_response)
Пример #13
0
    def set_pixbuf(self, pixbuf, mime=None):
        """
            Updates the displayed cover image and info values
        """
        self.pixbuf = pixbuf

        if pixbuf is None:
            self.image.set_from_stock(gtk.STOCK_ADD, gtk.ICON_SIZE_DIALOG)
            self.info_label.set_markup('')
        else:
            self.image.set_from_pixbuf(pixbuf.scale_simple(
                100, 100, gtk.gdk.INTERP_BILINEAR))

            width, height = pixbuf.get_width(), pixbuf.get_height()
            if mime is None:
                # TRANSLATORS: do not translate 'width' and 'height'
                markup = _('{width}x{height} pixels').format(width=width, height=height)
            else:
                # TRANSLATORS: do not translate 'format', 'width', and 'height'
                markup = _('{format} ({width}x{height} pixels)').format(
                    format=self.mime_info.get(mime, self.mime_info['image/'])['title'],
                    width=width, height=height
                )
            self.info_label.set_markup(markup)

            self.info = self.info._replace(mime=mime)
Пример #14
0
def ask_for_playlist_name(playlist_manager, name=None):
    """
        Returns a user-selected name that is not already used
            in the specified playlist manager
            
        :param name: A default name to show to the user
        Returns None if the user hits cancel
    """
    
    while True:
            
        dialog = TextEntryDialog(
            _('Playlist name:'),
            _('Add new playlist...'), name, okbutton=gtk.STOCK_ADD)
            
        result = dialog.run()
        if result != gtk.RESPONSE_OK:
            return None
            
        name = dialog.get_value()
        
        if name == '':
            error(None, _("You did not enter a name for your playlist"))
        elif playlist_manager.has_playlist_name(name):
            # name is already in use
            error(None, _("The playlist name you entered is already in use."))
        else:
            return name
Пример #15
0
    def __init__(self, parent=None):
        """
            :param parent: a parent window for modal operation or None
            :type parent: :class:`gtk.Window`
        """
        gtk.FileChooserDialog.__init__(self,
            title=_('Import Playlist'),
            parent=parent,
            buttons=(
                gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                gtk.STOCK_OPEN, gtk.RESPONSE_OK))

        self.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
        self.set_local_only(False)
        self.set_select_multiple(True)

        playlist_filter = gtk.FileFilter()
        playlist_filter.set_name(_('Playlist Files'))
        all_filter = gtk.FileFilter()
        all_filter.set_name(_('All Files'))
        all_filter.add_pattern('*')

        playlist_file_extensions = sum([p.file_extensions \
            for p in providers.get('playlist-format-converter')], [])

        for extension in playlist_file_extensions:
            pattern = '*.%s' % extension
            playlist_filter.add_pattern(pattern)

        self.add_filter(playlist_filter)
        self.add_filter(all_filter)

        self.connect('response', self.on_response)
Пример #16
0
    def do_init(self, captcha_id=None, captcha_solution=None):
        username = settings.get_option("plugin/douban_radio/username")
        password = settings.get_option("plugin/douban_radio/password")
        try:
            self.doubanfm = DoubanFM(username, password, captcha_id, captcha_solution)
        except DoubanLoginException as e:
            if e.data['captcha_id'] is None:
                self.exaile.gui.main.message.show_error(
                    _('Douban FM Error'),
                    _('Failed to login to douban.fm with your credential'))
                return
            else:
                captcha_id = e.data['captcha_id']
                self.show_captcha_dialog(captcha_id)
                return

        self.channels = self.doubanfm.channels

        self.__create_menu_item__()

        self.check_to_enable_dbus()

        self.__register_events()

        self.doubanfm_cover = DoubanFMCover()
        providers.register('covers', self.doubanfm_cover)

        self.doubanfm_mode = DoubanFMMode(self.exaile, self)
Пример #17
0
    def _parse_podcast(self, url, add_to_db=False):
        try:
            url = url.replace("itpc://", "http://")

            self._set_status(_("Loading %s...") % url)
            d = fp.parse(url)
            entries = d["entries"]

            title = d["feed"]["title"]

            if add_to_db:
                self._add_to_db(url, title)

            pl = playlist.Playlist(md5(url).hexdigest())

            tracks = []
            for e in entries:
                for link in e.get("enclosures", []):
                    tr = trax.Track(link.href)
                    date = e["updated_parsed"]
                    tr.set_tag_raw("artist", title)
                    tr.set_tag_raw("title", "%s: %s" % (e["title"], link.href.split("/")[-1]))
                    tr.set_tag_raw("date", "%d-%02d-%02d" % (date.tm_year, date.tm_mon, date.tm_mday))
                    tracks.append(tr)

            pl.extend(tracks)
            self._set_status("")

            self._open_podcast(pl, title)
            self.podcast_playlists.save_playlist(pl, overwrite=True)
        except:
            logger.exception("Error loading podcast")
            self._set_status(_("Error loading podcast."), 2)
Пример #18
0
    def __init__(self, preferences, widget):
        """
            Initializes the preferences item
            expects the name of the widget in the designer file, the default for
            this setting, an optional function to be called when the value is
            changed, and an optional function to be called when this setting
            is applied
        """

        self.widget = widget
        self.preferences = preferences

        if self.restart_required:
            self.message = dialogs.MessageBar(
                parent=preferences.builder.get_object('preferences_box'),
                type=gtk.MESSAGE_QUESTION,
                buttons=gtk.BUTTONS_CLOSE,
                text=_('Restart Exaile?'))
            self.message.set_secondary_text(
                _('A restart is required for this change to take effect.'))

            button = self.message.add_button(_('Restart'), gtk.RESPONSE_ACCEPT)
            button.set_image(gtk.image_new_from_stock(
                gtk.STOCK_REFRESH, gtk.ICON_SIZE_BUTTON))

            self.message.connect('response', self.on_message_response)

        self._set_value()
        self._setup_change()
Пример #19
0
    def get_document(self, url):
        """
            Connects to the server and retrieves the document
        """
        set_status(_('Contacting SomaFM server...'))
        hostinfo = urlparse.urlparse(url)

        try:
            c = httplib.HTTPConnection(hostinfo.netloc, timeout = 20)
        except TypeError:
            c = httplib.HTTPConnection(hostinfo.netloc)

        try:
            c.request('GET', hostinfo.path, headers={'User-Agent':
                    self.user_agent})
            response = c.getresponse()
        except (socket.timeout, socket.error):
            raise radio.RadioException(_('Error connecting to SomaFM server.'))

        if response.status != 200:
            raise radio.RadioException(_('Error connecting to SomaFM server.'))

        document = response.read()
        c.close()

        set_status('')
        return document
Пример #20
0
        def factory(menu_, parent, context):
            item = None
            
            dt = (datetime.now() - close_time)
            if dt.seconds > 60:
                display_name = _('{playlist_name} ({track_count} tracks, closed {minutes} min ago)').format(
                    playlist_name=playlist.name,
                    track_count=len(playlist),
                    minutes=dt.seconds // 60
                )
            else:
                display_name = _('{playlist_name} ({track_count} tracks, closed {seconds} sec ago)').format(
                    playlist_name=playlist.name,
                    track_count=len(playlist),
                    seconds=dt.seconds
                )
            item = gtk.ImageMenuItem(display_name)
            item.set_image(gtk.image_new_from_icon_name('music-library', gtk.ICON_SIZE_MENU))

            # Add accelerator to top item
            if self.tab_history[0][1].name == item_name:
                key, mods = gtk.accelerator_parse(self.accelerator.keys)
                item.add_accelerator('activate', menu.FAKEACCELGROUP, key, mods,
                        gtk.ACCEL_VISIBLE)


            item.connect('activate', lambda w: self.restore_closed_tab(item_name=item_name))

            return item
Пример #21
0
    def _parse_podcast(self, url, add_to_db=False):
        try:
            url = url.replace('itpc://', 'http://')

            self._set_status(_('Loading %s...') % url)
            d = fp.parse(url)
            entries = d['entries']

            title = d['feed']['title']

            if add_to_db:
                self._add_to_db(url, title)

            pl = playlist.Playlist(md5(url).hexdigest())

            tracks = []
            for e in entries:
                for link in e.get('enclosures', []):
                    tr = trax.Track(link.href)
                    date = e['updated_parsed']
                    tr.set_tag_raw('artist', title)
                    tr.set_tag_raw('title', '%s: %s' % (e['title'], link.href.split('/')[-1]))
                    tr.set_tag_raw('date', "%d-%02d-%02d" %
                            (date.tm_year, date.tm_mon, date.tm_mday))
                    tracks.append(tr)

            pl.extend(tracks)
            self._set_status('')

            self._open_podcast(pl, title)
            self.podcast_playlists.save_playlist(pl, overwrite=True)
        except:
            traceback.print_exc()
            self._set_status(_('Error loading podcast.'), 2)
Пример #22
0
def __create_edit_menu():
    items = []
    accelerators = []

    def collection_manager_cb(*args):
        from xlgui import get_controller
        get_controller().collection_manager()
    items.append(_smi('collection-manager', [], _("_Collection"), None, collection_manager_cb))

    def queue_cb(*args):
        get_main().playlist_container.show_queue()
    items.append(_smi('queue', [items[-1].name], _("_Queue"),
        callback=queue_cb, accelerator='<Control>m'))
    accelerators.append(Accelerator('<Control>m', queue_cb))

    def cover_manager_cb(*args):
        from xlgui.cover import CoverManager
        dialog = CoverManager(get_main().window, get_main().collection)
    items.append(_smi('cover-manager', [items[-1].name], _("C_overs"), None, cover_manager_cb))

    def preferences_cb(*args):
        from xlgui.preferences import PreferencesDialog
        dialog = PreferencesDialog(get_main().window, get_main().controller)
        dialog.run()
    items.append(_smi('preferences', [items[-1].name],
        icon_name=gtk.STOCK_PREFERENCES, callback=preferences_cb))

    for item in items:
        providers.register('menubar-edit-menu', item)
    for accelerator in accelerators:
        providers.register('mainwindow-accelerators', accelerator)
Пример #23
0
def __create_view_menu():
    items = []
    accelerators = []

    def show_playing_track_cb(*args):
        get_main().playlist_container.show_current_track()
    items.append(menuitems.ShowCurrentTrackMenuItem('show-playing-track', [],
        show_playing_track_cb, accelerator='<Control>j'))
    accelerators.append(Accelerator('<Control>j', show_playing_track_cb))

    items.append(_sep('show-playing-track-sep', [items[-1].name]))

    def playlist_utilities_cb(widget, name, parent, context):
        settings.set_option('gui/playlist_utilities_bar_visible',
            widget.get_active())
    def playlist_utilities_is_checked(name, parent, context):
        return settings.get_option('gui/playlist_utilities_bar_visible', True)
    items.append(menu.check_menu_item('playlist-utilities', [items[-1].name],
        _("_Playlist Utilities Bar"), playlist_utilities_is_checked, playlist_utilities_cb))

    items.append(_smi('columns', [items[-1].name], _('_Columns'),
        submenu=menu.ProviderMenu('playlist-columns-menu', get_main())))

    def clear_playlist_cb(*args):
        page = get_main().get_selected_page()
        if page:
            page.playlist.clear()
    items.append(_smi('clear-playlist', [items[-1].name], _('C_lear playlist'),
         gtk.STOCK_CLEAR, clear_playlist_cb, accelerator='<Control>l'))
    accelerators.append(Accelerator('<Control>l', clear_playlist_cb))

    for item in items:
        providers.register('menubar-view-menu', item)
    for accelerator in accelerators:
        providers.register('mainwindow-accelerators', accelerator)
Пример #24
0
    def __init__(self, preferences, widget):
        """
            Initializes the preferences item
            expects the name of the widget in the designer file, the default for
            this setting, an optional function to be called when the value is
            changed, and an optional function to be called when this setting
            is applied
        """

        self.widget = widget
        self.preferences = preferences

        if self.restart_required:
            self.message = dialogs.MessageBar(
                parent=preferences.builder.get_object('preferences_box'),
                type=Gtk.MessageType.QUESTION,
                buttons=Gtk.ButtonsType.CLOSE,
                text=_('Restart Exaile?'),
            )
            self.message.set_secondary_text(
                _('A restart is required for this change to take effect.')
            )

            button = self.message.add_button(_('Restart'), Gtk.ResponseType.ACCEPT)
            button.set_image(
                Gtk.Image.new_from_icon_name('view-refresh', Gtk.IconSize.BUTTON)
            )

            self.message.connect('response', self.on_message_response)

        self._set_value()
        self._setup_change()
Пример #25
0
    def __create_menu_item__(self):
        exaile = self.exaile
        
        self.menuItem = gtk.MenuItem(_('Open Douban.fm'))
        menu = gtk.Menu()
        self.menuItem.set_submenu(menu)

        for channel_name  in self.channels.keys():
            menuItem = gtk.MenuItem(_(channel_name))

            menuItem.connect('activate', self.active_douban_radio, channel_name)
            
            menu.prepend(menuItem)
            menuItem.show()

#       self.menu.connect('activate', self.active_douban_radio, self.exaile)

        exaile.gui.builder.get_object('file_menu').insert(self.menuItem, 5)

        self.menuItem.show()

        self.modeMenuItem = gtk.MenuItem(_('DoubanFM mode'))
        key, modifier = gtk.accelerator_parse('<Control><Alt>D')
        self.accels = gtk.AccelGroup()
        self.modeMenuItem.add_accelerator('activate', self.accels, key, modifier, gtk.ACCEL_VISIBLE)
        self.exaile.gui.main.window.add_accel_group(self.accels)
        self.modeMenuItem.connect('activate', self.show_mode)
        exaile.gui.builder.get_object('view_menu').append(self.modeMenuItem)
        self.modeMenuItem.show()
Пример #26
0
    def _setup_tree(self):
        self.tree = FlatPlaylistDragTreeView(self, False, True)
        selection = self.tree.get_selection()
        selection.set_mode(gtk.SELECTION_MULTIPLE)

        self.tree.set_headers_visible(True)
        self.tree.set_model(self.model)
        self.scroll = gtk.ScrolledWindow()
        self.scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        self.scroll.add(self.tree)
        self.scroll.set_shadow_type(gtk.SHADOW_IN)
        self.box.pack_start(self.scroll, True, True)

        text = gtk.CellRendererText()
        col = gtk.TreeViewColumn(_('#'))
        col.pack_start(text, False)
        col.set_attributes(text, text=0)
        col.set_fixed_width(50)
        col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
        self.tree.append_column(col)

        text = gtk.CellRendererText()
        col = gtk.TreeViewColumn(_('Title'))
        col.pack_start(text, True)
        col.set_attributes(text, text=1)
        col.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
        col.set_cell_data_func(text, self._title_data_func)
        self.tree.append_column(col)
        self.box.show_all()
Пример #27
0
    def on_timeout(self):
        """
            Tries to shutdown the computer
        """
        self.countdown = None
        if self.counter > 0:
            self.message.set_secondary_text(_("The computer will be shut down in %d seconds.") % self.counter)
            self.message.show()

            self.counter -= 1

            return True

        self.do_shutdown = False

        bus = dbus.SystemBus()

        try:
            proxy = bus.get_object("org.freedesktop.login1", "/org/freedesktop/login1")
            proxy.PowerOff(False, dbus_interface="org.freedesktop.login1.Manager")
        except dbus.exceptions.DBusException:
            try:
                proxy = bus.get_object("org.freedesktop.ConsoleKit", "/org/freedesktop/ConsoleKit/Manager")
                proxy.Stop(dbus_interface="org.freedesktop.ConsoleKit.Manager")
            except dbus.exceptions.DBusException:
                try:
                    proxy = bus.get_object("org.freedesktop.Hal", "/org/freedesktop/Hal/devices/computer")
                    proxy.Shutdown(dbus_interface="org.freedesktop.Hal.Device.SystemPowerManagement")
                except dbus.exceptions.DBusException:
                    self.message.show_warning(_("Shutdown failed"), _("Computer could not be shutdown using D-Bus."))
Пример #28
0
    def _add_default_playlists(self):
        """
            Adds some default smart playlists to the playlist manager
        """
        from xl import playlist

        # entire playlist
        entire_lib = playlist.SmartPlaylist(
            _("Entire Library"), collection=self.collection
        )
        self.smart_playlists.save_playlist(entire_lib, overwrite=True)

        # random playlists
        for count in (100, 300, 500):
            pl = playlist.SmartPlaylist(
                _("Random %d") % count, collection=self.collection
            )
            pl.set_return_limit(count)
            pl.set_random_sort(True)
            self.smart_playlists.save_playlist(pl, overwrite=True)

        # rating based playlists
        for item in (3, 4):
            pl = playlist.SmartPlaylist(
                _("Rating > %d") % item, collection=self.collection
            )
            pl.add_param('__rating', '>', item)
            self.smart_playlists.save_playlist(pl, overwrite=True)
Пример #29
0
    def Query(self):
        """
            Returns information about the currently playing track

            :returns: information about the current track
            :rtype: string
        """
        status = self.__get_playback_status()

        if status.current is None or status.state == "stopped":
            return _('Not playing.')

        result = _('status: %(status)s, title: %(title)s, artist: %(artist)s,'
                   ' album: %(album)s, length: %(length)s,'
                   ' position: %(progress)s%% [%(position)s]') % {
                         'status': status.state,
                         'title': status.current["title"],
                         'artist': status.current["artist"],
                         'album': status.current["album"],
                         'length': status.current["__length"],
                         'progress': status.progress,
                         'position': status.position,
                     }

        return result
Пример #30
0
    def Query(self):
        """
            Returns information about the currently playing track

            :returns: information about the current track
            :rtype: string
        """
        status = self.__get_playback_status()

        if status.current is None or status.state == "stopped":
            return _("Not playing.")

        result = _(
            "status: %(status)s, title: %(title)s, artist: %(artist)s,"
            " album: %(album)s, length: %(length)s,"
            " position: %(progress)s%% [%(position)s]"
        ) % {
            "status": status.state,
            "title": status.current["title"],
            "artist": status.current["artist"],
            "album": status.current["album"],
            "length": status.current["__length"],
            "progress": status.progress,
            "position": status.position,
        }

        return result
Пример #31
0
    def __init__(self, notebook, page, display_left=False):
        """
            :param notebook: The notebook this tab will belong to
            :param page: The page this tab will be associated with
        """
        gtk.EventBox.__init__(self)
        self.set_visible_window(False)

        self.closable = True

        self.notebook = notebook
        self.page = page

        self.menu = menu.ProviderMenu(self.menu_provider_name, self)

        self.connect('button-press-event', self.on_button_press)

        if display_left:
            box = gtk.VBox(False, 2)
        else:
            box = gtk.HBox(False, 2)
        self.add(box)

        self.icon = gtk.Image()
        self.icon.set_property("visible", False)

        self.label = gtk.Label(self.page.get_page_name())
        self.label.set_max_width_chars(20)

        if display_left:
            self.label.set_angle(90)
        else:
            self.label.set_ellipsize(pango.ELLIPSIZE_END)

        self.label.set_tooltip_text(self.page.get_page_name())

        if self.can_rename():
            self.entry = gtk.Entry()
            self.entry.set_width_chars(self.label.get_max_width_chars())
            self.entry.set_text(self.label.get_text())
            self.entry.set_inner_border(gtk.Border(left=1, right=1))
            self.entry.connect('activate', self.on_entry_activate)
            self.entry.connect('focus-out-event',
                               self.on_entry_focus_out_event)
            self.entry.connect('key-press-event',
                               self.on_entry_key_press_event)
            self.entry.set_no_show_all(True)

        self.button = button = gtk.Button()
        button.set_name("tabCloseButton")
        button.set_relief(gtk.RELIEF_NONE)
        button.set_focus_on_click(False)
        button.set_tooltip_text(_("Close Tab"))
        button.add(
            gtk.image_new_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_MENU))
        button.connect('clicked', self.close)
        button.connect('button-press-event', self.on_button_press)

        # pack the widgets in
        if display_left:
            box.pack_start(button, False, False)
            box.pack_end(self.icon, False, False)
            box.pack_end(self.label, False, False)
            if self.can_rename():
                box.pack_end(self.entry, False, False)

        else:
            box.pack_start(self.icon, False, False)
            box.pack_start(self.label, False, False)
            if self.can_rename():
                box.pack_start(self.entry, False, False)
            box.pack_end(button, False, False)

        page.set_tab(self)
        page.connect('name-changed', self.on_name_changed)
        self.show_all()
Пример #32
0
    def __init__(self, notebook, page, vertical=False):
        """
            :param notebook: The notebook this tab will belong to
            :type notebook: SmartNotebook
            :param page: The page this tab will be associated with
            :type page: NotebookPage
            :param vertical: Whether the tab contents are to be laid out vertically
            :type vertical: bool
        """
        Gtk.EventBox.__init__(self)
        self.set_visible_window(False)

        self.closable = True

        self.notebook = notebook
        self.page = page
        self.page.tab_menu.attach_to_widget(self.page, None)

        self.connect('button-press-event', self.on_button_press)

        self.vertical = vertical
        if vertical:
            box = Gtk.Box(spacing=2, orientation=Gtk.Orientation.VERTICAL)
        else:
            box = Gtk.Box(spacing=2)
        self.add(box)
        apply_css(box)

        self.icon = Gtk.Image()
        self.icon.set_no_show_all(True)
        apply_css(self.icon)

        self.label = Gtk.Label(label=self.page.get_page_name())
        self.label.set_tooltip_text(self.page.get_page_name())
        apply_css(self.label)

        if vertical:
            self.label.set_angle(90)
            self.label.props.valign = Gtk.Align.CENTER
            # Don't ellipsize but give a sane maximum length.
            self.label.set_max_width_chars(20)
        else:
            self.label.props.halign = Gtk.Align.CENTER
            self.label.set_ellipsize(Pango.EllipsizeMode.END)
            self.adjust_label_width(Gtk.PositionType.TOP)

        if self.can_rename():
            self.entry = entry = Gtk.Entry()
            entry.set_width_chars(self.label.get_max_width_chars())
            entry.set_text(self.label.get_text())
            border = Gtk.Border.new()
            border.left = 1
            border.right = 1
            entry.set_inner_border(border)
            entry.connect('activate', self.on_entry_activate)
            entry.connect('focus-out-event', self.on_entry_focus_out_event)
            entry.connect('key-press-event', self.on_entry_key_press_event)
            entry.set_no_show_all(True)
            apply_css(entry)

        self.button = button = Gtk.Button()
        button.set_relief(Gtk.ReliefStyle.NONE)
        button.set_halign(Gtk.Align.CENTER)
        button.set_valign(Gtk.Align.CENTER)
        button.set_focus_on_click(False)
        button.set_tooltip_text(_("Close Tab"))
        button.add(
            Gtk.Image.new_from_icon_name('window-close', Gtk.IconSize.MENU))
        button.connect('clicked', self.close)
        button.connect('button-press-event', self.on_button_press)
        apply_css(button)

        # pack the widgets in
        if vertical:
            box.pack_start(button, False, False, 0)
            box.pack_end(self.icon, False, False, 0)
            box.pack_end(self.label, True, True, 0)
            if self.can_rename():
                box.pack_end(self.entry, True, True, 0)

        else:
            box.pack_start(self.icon, False, False, 0)
            box.pack_start(self.label, True, True, 0)
            if self.can_rename():
                box.pack_start(self.entry, True, True, 0)
            box.pack_end(button, False, False, 0)

        page.set_tab(self)
        page.connect('name-changed', self.on_name_changed)

        box.show_all()
Пример #33
0
 def _error_cb(self, gerror, message_string):
     self.running = False
     xlgui.main.mainwindow().message.show_error(
         _("Error transcoding files from CD."),
         "%s" % gerror.message.encode())
Пример #34
0
def DeletePlaylistMenuItem(name, after, get_pl_func=generic_get_playlist_func):
    return menu.simple_menu_item(
        name, after, _('_Delete Playlist'), 'edit-delete',
        lambda w, n, o, c: o.remove_playlist(get_pl_func(o, c)))
Пример #35
0
def create_argument_parser():
    """Create command-line argument parser for Exaile"""

    import argparse
    # argparse hard-codes "usage:" uncapitalized. We replace this with an
    # empty string and put "Usage:" in the actual usage string instead.
    class Formatter(argparse.HelpFormatter):
        def _format_usage(self, usage, actions, groups, prefix):
            return super(self.__class__, self)._format_usage(usage, actions, groups, "")

    p = argparse.ArgumentParser(
        usage=_("Usage: exaile [OPTION...] [LOCATION...]"),
        description=_("Launch Exaile, optionally adding tracks specified by"
            " LOCATION to the active playlist."
            " If Exaile is already running, this attempts to use the existing"
            " instance instead of creating a new one."),
        add_help=False, formatter_class=Formatter)

    p.add_argument('locs', nargs='*', help=argparse.SUPPRESS)

    group = p.add_argument_group(_('Playback Options'))
    group.add_argument("-n", "--next", dest="Next", action="store_true",
        default=False, help=_("Play the next track"))
    group.add_argument("-p", "--prev", dest="Prev", action="store_true",
        default=False,   help=_("Play the previous track"))
    group.add_argument("-s", "--stop", dest="Stop", action="store_true",
        default=False, help=_("Stop playback"))
    group.add_argument("-a", "--play", dest="Play", action="store_true",
        default=False, help=_("Play"))
    group.add_argument("-u", "--pause", dest="Pause", action="store_true",
        default=False, help=_("Pause"))
    group.add_argument("-t", "--play-pause", dest="PlayPause",
        action="store_true", default=False, help=_("Pause or resume playback"))
    group.add_argument("--stop-after-current", dest="StopAfterCurrent",
        action="store_true", default=False,
        help=_("Stop playback after current track"))

    group = p.add_argument_group(_('Collection Options'))
    group.add_argument("--add", dest="Add",
        # TRANSLATORS: Meta variable for --add and --export-playlist
        metavar=_("LOCATION"),
        help=_("Add tracks from LOCATION to the collection"))

    group = p.add_argument_group(_('Playlist Options'))
    group.add_argument("--export-playlist", dest="ExportPlaylist",
        # TRANSLATORS: Meta variable for --add and --export-playlist
        metavar=_("LOCATION"),
        help=_('Export the current playlist to LOCATION'))

    group = p.add_argument_group(_('Track Options'))
    group.add_argument("-q", "--query", dest="Query", action="store_true",
        default=False, help=_("Query player"))
    group.add_argument("--format-query", dest="FormatQuery",
        # TRANSLATORS: Meta variable for --format-query
        metavar=_('FORMAT'),
        help=_('Retrieve the current playback state and track information as FORMAT'))
    group.add_argument("--format-query-tags", dest="FormatQueryTags",
        # TRANSLATORS: Meta variable for --format-query-tags
        metavar=_('TAGS'),
        help=_('Tags to retrieve from the current track; use with --format-query'))
    group.add_argument("--gui-query", dest="GuiQuery", action="store_true",
        default=False, help=_("Show a popup with data of the current track"))
    group.add_argument("--get-title", dest="GetTitle", action="store_true",
        default=False, help=_("Print the title of current track"))
    group.add_argument("--get-album", dest="GetAlbum", action="store_true",
        default=False, help=_("Print the album of current track"))
    group.add_argument("--get-artist", dest="GetArtist", action="store_true",
        default=False, help=_("Print the artist of current track"))
    group.add_argument("--get-length", dest="GetLength", action="store_true",
        default=False, help=_("Print the length of current track"))
    group.add_argument('--set-rating', dest="SetRating", type=int,
        # TRANSLATORS: Variable for command line options with arguments
        metavar=_('N'),
        help=_('Set rating for current track to N%').replace("%", "%%"))
    group.add_argument('--get-rating', dest='GetRating', action='store_true',
        default=False, help=_('Get rating for current track'))
    group.add_argument("--current-position", dest="CurrentPosition",
        action="store_true", default=False,
        help=_("Print the current playback position as time"))
    group.add_argument("--current-progress", dest="CurrentProgress",
        action="store_true", default=False,
        help=_("Print the current playback progress as percentage"))

    group = p.add_argument_group(_('Volume Options'))
    group.add_argument("-i", "--increase-vol", dest="IncreaseVolume", type=int,
        # TRANSLATORS: Meta variable for --increase-vol and--decrease-vol
        metavar=_("N"),
        help=_("Increase the volume by N%").replace("%", "%%"))
    group.add_argument("-l", "--decrease-vol", dest="DecreaseVolume", type=int,
        # TRANSLATORS: Meta variable for --increase-vol and--decrease-vol
        metavar=_("N"),
        help=_("Decrease the volume by N%").replace("%", "%%"))
    group.add_argument("-m", "--toggle-mute", dest="ToggleMute",
        action="store_true", default=False,
        help=_("Mute or unmute the volume"))
    group.add_argument("--get-volume", dest="GetVolume", action="store_true",
        default=False, help=_("Print the current volume percentage"))

    group = p.add_argument_group(_('Other Options'))
    group.add_argument("--new", dest="NewInstance", action="store_true",
        default=False, help=_("Start new instance"))
    group.add_argument("-h", "--help", action="help",
        help=_("Show this help message and exit"))
    group.add_argument("--version", dest="ShowVersion", action="store_true",
        help=_("Show program's version number and exit."))
    group.add_argument("--start-minimized", dest="StartMinimized",
        action="store_true", default=False,
        help=_("Start minimized (to tray, if possible)"))
    group.add_argument("--toggle-visible", dest="GuiToggleVisible",
        action="store_true", default=False,
        help=_("Toggle visibility of the GUI (if possible)"))
    group.add_argument("--safemode", dest="SafeMode", action="store_true",
        default=False, help=_("Start in safe mode - sometimes"
        " useful when you're running into problems"))
    group.add_argument("--force-import", dest="ForceImport",
        action="store_true", default=False, help=_("Force import of old data"
        " from version 0.2.x (overwrites current data)"))
    group.add_argument("--no-import", dest="NoImport",
        action="store_true", default=False, help=_("Do not import old data"
        " from version 0.2.x"))
    group.add_argument("--start-anyway", dest="StartAnyway",
        action="store_true", default=False, help=_("Make control options like"
        " --play start Exaile if it is not running"))

    group = p.add_argument_group(_('Development/Debug Options'))
    group.add_argument("--datadir", dest="UseDataDir",
        metavar=_('DIRECTORY'), help=_("Set data directory"))
    group.add_argument("--all-data-dir", dest="UseAllDataDir",
        metavar=_('DIRECTORY'), help=_("Set data and config directory"))
    group.add_argument("--modulefilter", dest="ModuleFilter",
        metavar=_('MODULE'), help=_('Limit log output to MODULE'))
    group.add_argument("--levelfilter", dest="LevelFilter",
        metavar=_('LEVEL'), help=_('Limit log output to LEVEL'),
        choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'])
    group.add_argument("--debug", dest="Debug", action="store_true",
        default=False, help=_("Show debugging output"))
    group.add_argument("--eventdebug", dest="DebugEvent",
        action="store_true", default=False, help=_("Enable debugging of"
        " xl.event. Generates lots of output"))
    group.add_argument("--eventdebug-full", dest="DebugEventFull",
        action="store_true", default=False, help=_("Enable full debugging of"
        " xl.event. Generates LOTS of output"))
    group.add_argument("--threaddebug", dest="DebugThreads",
        action="store_true", default=False, help=_("Add thread name to logging"
        " messages."))
    group.add_argument("--eventfilter", dest="EventFilter", metavar=_('TYPE'),
        help=_("Limit xl.event debug to output of TYPE"))
    group.add_argument("--quiet", dest="Quiet", action="store_true",
        default=False, help=_("Reduce level of output"))
    group.add_argument('--startgui', dest='StartGui', action='store_true',
        default=False)
    group.add_argument('--no-dbus', dest='Dbus', action='store_false',
        default=True, help=_("Disable D-Bus support"))
    group.add_argument('--no-hal', dest='Hal', action='store_false',
        default=True, help=_("Disable HAL support."))

    return p
Пример #36
0
def __create_tray_context_menu():
    sep = menu.simple_separator
    items = []
    # Play/Pause
    items.append(
        playback.PlayPauseMenuItem('playback-playpause', player.PLAYER, after=[])
    )
    # Next
    items.append(
        playback.NextMenuItem('playback-next', player.PLAYER, after=[items[-1].name])
    )
    # Prev
    items.append(
        playback.PrevMenuItem('playback-prev', player.PLAYER, after=[items[-1].name])
    )
    # Stop
    items.append(
        playback.StopMenuItem('playback-stop', player.PLAYER, after=[items[-1].name])
    )
    # ----
    items.append(sep('playback-sep', [items[-1].name]))
    # Shuffle
    items.append(
        playlist.ShuffleModesMenuItem('playlist-mode-shuffle', after=[items[-1].name])
    )
    # Repeat
    items.append(
        playlist.RepeatModesMenuItem('playlist-mode-repeat', after=[items[-1].name])
    )
    # Dynamic
    items.append(
        playlist.DynamicModesMenuItem('playlist-mode-dynamic', after=[items[-1].name])
    )
    # ----
    items.append(sep('playlist-mode-sep', [items[-1].name]))
    # Rating

    def rating_get_tracks_func(parent, context):
        current = player.PLAYER.current
        if current:
            return [current]
        else:
            return []

    items.append(
        menuitems.RatingMenuItem('rating', [items[-1].name], rating_get_tracks_func)
    )
    # Remove
    items.append(playlist.RemoveCurrentMenuItem([items[-1].name]))
    # ----
    items.append(sep('misc-actions-sep', [items[-1].name]))
    # Quit

    def quit_cb(*args):
        from xl import main

        main.exaile().quit()

    items.append(
        menu.simple_menu_item(
            'quit-application',
            [items[-1].name],
            _("_Quit Exaile"),
            'application-exit',
            callback=quit_cb,
        )
    )
    for item in items:
        providers.register('tray-icon-context', item)
Пример #37
0
    def add_new_playlist(self, tracks=[], name = None):
        """
            Adds a new playlist to the list of playlists. If name is 
            None or the name conflicts with an existing playlist, the
            user will be queried for a new name.
            
            Returns the name of the new playlist, or None if it was
            not added.
        """

        do_add_playlist = False
        if name:
            if name in self.playlist_manager.playlists:
                name = dialogs.ask_for_playlist_name(
                    self.get_panel().get_toplevel(), self.playlist_manager, name)
        else:
            if tracks:
                artists = []
                composers = []
                albums = []

                for track in tracks:
                    artist = track.get_tag_display('artist',
                        artist_compilations=False)

                    if artist is not None:
                        artists += [artist]

                    composer = track.get_tag_display('composer',
                        artist_compilations=False)

                    if composer is not None:
                        composers += composer

                    album = track.get_tag_display('album')

                    if album is not None:
                        albums += album

                artists = list(set(artists))[:3]
                composers = list(set(composers))[:3]
                albums = list(set(albums))[:3]

                if len(artists) > 0:
                    name = artists[0]

                    if len(artists) > 2:
                        # TRANSLATORS: Playlist title suggestion with more 
                        # than two values
                        name = _('%(first)s, %(second)s and others') % {
                            'first': artists[0], 'second': artists[1]
                        }
                    elif len(artists) > 1:
                        # TRANSLATORS: Playlist title suggestion with two values
                        name = _('%(first)s and %(second)s') % {
                            'first': artists[0], 'second': artists[1]
                        }
                elif len(composers) > 0:
                    name = composers[0]

                    if len(composers) > 2:
                        # TRANSLATORS: Playlist title suggestion with more 
                        # than two values
                        name = _('%(first)s, %(second)s and others') % {
                            'first': composers[0], 'second': composers[1]
                        }
                    elif len(composers) > 1:
                        # TRANSLATORS: Playlist title suggestion with two values
                        name = _('%(first)s and %(second)s') % {
                            'first': composers[0], 'second': composers[1]
                        }
                elif len(albums) > 0:
                    name = albums[0]

                    if len(albums) > 2:
                        # TRANSLATORS: Playlist title suggestion with more 
                        # than two values
                        name = _('%(first)s, %(second)s and others') % {
                            'first': albums[0], 'second': albums[1]
                        }
                    elif len(albums) > 1:
                        # TRANSLATORS: Playlist title suggestion with two values
                        name = _('%(first)s and %(second)s') % {
                            'first': albums[0], 'second': albums[1]
                        }
                else:
                    name = ''

            name = dialogs.ask_for_playlist_name(
                self.get_panel().get_toplevel(), self.playlist_manager, name)
        
        if name is not None:
            #Create the playlist from all of the tracks
            new_playlist = playlist.Playlist(name)
            new_playlist.extend(tracks)
            # We are adding a completely new playlist with tracks so we save it
            self.playlist_manager.save_playlist(new_playlist)
            
        return name
Пример #38
0
 def get_page_name(self):
     return _('GroupTagger')
Пример #39
0
def ExportPlaylistFilesMenuItem(name,
                                after,
                                get_pl_func=generic_get_playlist_func):
    return menu.simple_menu_item(
        name, after, _('Export _Files'), 'document-save-as',
        lambda w, n, o, c: dialogs.export_playlist_files(get_pl_func(o, c)))
Пример #40
0
#
# GroupTaggerView signal 'changed' enum
#

group_change = common.enum(added=object(), deleted=object(),
                           edited=object())  # edited/toggled group

category_change = common.enum(
    added=object(),
    deleted=object(),
    expanded=object(),  # user expanded category display
    collapsed=object(),  # user collapsed category display
    updated=object())  # added group, changed name

# default group category
uncategorized = _('Uncategorized')


class GTShowTracksMenuItem(menu.MenuItem):
    def __init__(self, name, after):
        menu.MenuItem.__init__(self, name, None, after)

    def factory(self, menu, parent, context):

        groups = context['groups']

        if len(groups) == 0:
            display_name = _('Show tracks with selected')
        elif len(groups) == 1:
            display_name = _('Show tracks tagged with "%s"') % groups[0]
        else:
Пример #41
0
from gi.repository import GLib
from gi.repository import Gtk

import os.path
import _scrobbler

from xl import (
    common,
    settings,
)
from xl.nls import gettext as _
from xlgui import icons
from xlgui.preferences import widgets
from xlgui.widgets import dialogs

name = _('AudioScrobbler')
basedir = os.path.dirname(os.path.realpath(__file__))
ui = os.path.join(basedir, "asprefs_pane.ui")

icons.MANAGER.add_icon_name_from_directory('audioscrobbler',
                                           os.path.join(basedir, 'icons'))
icon = 'audioscrobbler'


class SubmitPreference(widgets.CheckPreference):
    default = True
    name = 'plugin/ascrobbler/submit'


class MenuCheck(widgets.CheckPreference):
    default = False
Пример #42
0
 def on_playback_error(self, type, player, message):
     """
         Called when there has been a playback error
     """
     self.message.show_error(_('Playback error encountered!'), message)
Пример #43
0
    def __init__(self, exaile, model=None, editable=False):

        super(GroupTaggerView, self).__init__()

        self.exaile = exaile

        self.connect('notify::model', self.on_notify_model)

        self.set_model(model)
        self.set_enable_search(False)
        self.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)

        self._row_expanded_id = self.connect('row-expanded',
                                             self.on_row_expanded)
        self._row_collapsed_id = self.connect('row-collapsed',
                                              self.on_row_collapsed)

        if editable:
            self.set_reorderable(True)

        # Setup the first column, not shown by default
        cell = Gtk.CellRendererToggle()
        cell.set_property('mode', Gtk.CellRendererMode.ACTIVATABLE)
        cell.set_activatable(True)
        cell.connect('toggled', self.on_toggle)

        self.click_column = Gtk.TreeViewColumn(None, cell, active=0, visible=2)

        # Setup the second column
        cell = Gtk.CellRendererText()
        cell.set_property('editable', editable)
        if editable:
            cell.connect('edited', self.on_edit)

        self.text_column = cell
        self.append_column(
            Gtk.TreeViewColumn(_('Tag'), self.text_column, text=1, weight=3))

        #
        # Menu setup
        #

        self.menu = GroupTaggerContextMenu(self)
        smi = menu.simple_menu_item
        sep = menu.simple_separator

        self.connect('popup-menu', self.on_popup_menu)
        self.connect('button-release-event', self.on_mouse_release)

        if editable:

            item = smi( 'addgrp', [], _('Add new tag'), \
                        callback=self.on_menu_add_group )
            self.menu.add_item(item)

            item = smi( 'delgrp', ['addgrp'], _('Delete tag'), \
                        callback=self.on_menu_delete_group, \
                        condition_fn=lambda n,p,c: False if len(c['groups']) == 0 else True)
            self.menu.add_item(item)

            self.menu.add_item(sep('sep1', ['delgrp']))

            item = smi( 'addcat', ['sep1'], _('Add new category'), \
                        callback=self.on_menu_add_category )
            self.menu.add_item(item)

            item = smi( 'remcat', ['addcat'], _('Remove category'), \
                        callback=self.on_menu_del_category,
                        condition_fn=lambda n,p,c: False if len(c['categories']) == 0 else True)
            self.menu.add_item(item)

            self.menu.add_item(sep('sep2', ['remcat']))

        self.menu.add_item(GTShowTracksMenuItem('sel', ['sep2']))

        item = smi( 'selcust', ['sel'], _('Show tracks with selected (custom)'), \
                    callback=lambda w,n,p,c: gt_common.create_custom_search_playlist( c['groups'], exaile ),
                    condition_fn=lambda n,p,c: True if len(c['groups']) > 1 else False)
        self.menu.add_item(item)
Пример #44
0
 def get_collection_count(self):
     """
     Retrieves the collection count
     """
     return _('%d in collection') % main.exaile().collection.get_count()
Пример #45
0
 def on_buffering(self, type, player, percent):
     """
         Called when a stream is buffering
     """
     percent = min(percent, 100)
     self.statusbar.set_status(_("Buffering: %d%%...") % percent, 1)
Пример #46
0
#
#
# The developers of the Exaile media player hereby grant permission
# for non-GPL compatible GStreamer and Exaile plugins to be used and
# distributed together with GStreamer and Exaile. This permission is
# above and beyond the permissions granted by the GPL license by which
# Exaile is covered. If you modify this code, you may extend this
# exception to your version of the code, but you are not obligated to
# do so. If you do not wish to do so, delete this exception statement
# from your version.

from xl import covers, settings, xdg
from xl.nls import gettext as _
from xlgui.preferences import widgets

name = _('Covers')
icon = 'image-x-generic'
ui = xdg.get_data_path('ui', 'preferences', 'cover.ui')


class TagCoverFetching(widgets.CheckPreference):
    default = True
    name = 'covers/use_tags'


class LocalCoverFetching(widgets.CheckPreference):
    default = True
    name = 'covers/use_localfile'


class LocalFilePreferredNamesPreference(widgets.Preference,
Пример #47
0
    def __init__(self, manager_name, player, hotkey):
        SmartNotebook.__init__(self)

        self.tab_manager = PlaylistManager(manager_name)
        self.manager_name = manager_name
        self.player = player

        # For saving closed tab history
        self._moving_tab = False
        self.tab_history = []
        self.history_counter = 90000  # to get unique (reverse-ordered) item names

        # Build static menu entries
        item = menu.simple_separator('clear-sep', [])
        item.register('playlist-closed-tab-menu', self)

        item = menu.simple_menu_item('clear-history', ['clear-sep'],
                                     _("_Clear Tab History"), 'edit-clear-all',
                                     self.clear_closed_tabs)
        item.register('playlist-closed-tab-menu', self)

        # Simple factory for 'Recently Closed Tabs' MenuItem
        submenu = menu.ProviderMenu('playlist-closed-tab-menu', self)

        def factory(menu_, parent, context):
            if self.page_num(parent) == -1:
                return None
            item = Gtk.MenuItem.new_with_mnemonic(_("Recently Closed _Tabs"))
            if len(self.tab_history) > 0:
                item.set_submenu(submenu)
            else:
                item.set_sensitive(False)
            return item

        # Add menu to tab context menu
        item = menu.MenuItem('%s-tab-history' % manager_name, factory, ['tab-close'])
        item.register('playlist-tab-context-menu')

        # Add menu to View menu
        #item = menu.MenuItem('tab-history', factory, ['clear-playlist'])
        #providers.register('menubar-view-menu', item)

        # setup notebook actions
        self.actions = NotebookActionService(self, 'playlist-notebook-actions')

        # Add hotkey
        self.accelerator = Accelerator(hotkey, _('Restore closed tab'),
                                       lambda *x: self.restore_closed_tab(0))
        providers.register('mainwindow-accelerators', self.accelerator)

        # Load saved tabs
        self.load_saved_tabs()

        self.tab_placement_map = {
            'left': Gtk.PositionType.LEFT,
            'right': Gtk.PositionType.RIGHT,
            'top': Gtk.PositionType.TOP,
            'bottom': Gtk.PositionType.BOTTOM
        }

        self.connect('page-added', self.on_page_added)
        self.connect('page-removed', self.on_page_removed)

        self.on_option_set('gui_option_set', settings, 'gui/show_tabbar')
        self.on_option_set('gui_option_set', settings, 'gui/tab_placement')
        event.add_ui_callback(self.on_option_set, 'gui_option_set')
Пример #48
0
    def __init__(self, notebook, page, display_left=False):
        """
            :param notebook: The notebook this tab will belong to
            :type notebook: SmartNotebook
            :param page: The page this tab will be associated with
            :type page: NotebookPage
        """
        Gtk.EventBox.__init__(self)
        self.set_visible_window(False)

        self.closable = True

        self.notebook = notebook
        self.page = page

        self.menu = menu.ProviderMenu(self.menu_provider_name, self)

        self.connect('button-press-event', self.on_button_press)

        if display_left:
            box = Gtk.Box(False, 2, orientation=Gtk.Orientation.VERTICAL)
        else:
            box = Gtk.Box(False, 2)
        self.add(box)

        self.icon = Gtk.Image()
        self.icon.set_no_show_all(True)

        self.label = Gtk.Label(label=self.page.get_page_name())

        if display_left:
            self.label.set_angle(90)
            self.label.props.valign = Gtk.Align.CENTER
            # Don't ellipsize but give a sane maximum length.
            self.label.set_max_width_chars(20)
        else:
            self.label.props.halign = Gtk.Align.CENTER
            self.label.set_ellipsize(Pango.EllipsizeMode.END)
            self.label.set_width_chars(4)  # Minimum, including ellipsis

        self.label.set_tooltip_text(self.page.get_page_name())
        
        if self.can_rename():
            self.entry = Gtk.Entry()
            self.entry.set_width_chars(self.label.get_max_width_chars())
            self.entry.set_text(self.label.get_text())
            border = Gtk.Border.new()
            border.left = 1
            border.right = 1
            self.entry.set_inner_border(border)
            self.entry.connect('activate', self.on_entry_activate)
            self.entry.connect('focus-out-event', self.on_entry_focus_out_event)
            self.entry.connect('key-press-event', self.on_entry_key_press_event)
            self.entry.set_no_show_all(True)
        

        self.button = button = Gtk.Button()
        button.set_relief(Gtk.ReliefStyle.NONE)
        button.set_halign(Gtk.Align.CENTER)
        button.set_valign(Gtk.Align.CENTER)
        button.set_focus_on_click(False)
        button.set_tooltip_text(_("Close Tab"))
        button.add(Gtk.Image.new_from_icon_name('window-close-symbolic', Gtk.IconSize.MENU))
        button.connect('clicked', self.close)
        button.connect('button-press-event', self.on_button_press)
        
        # pack the widgets in
        if display_left:
            box.pack_start(button, False, False, 0)
            box.pack_end(self.icon, False, False, 0)
            box.pack_end(self.label, True, True, 0)
            if self.can_rename():
                box.pack_end(self.entry, True, True, 0)
            
        else:
            box.pack_start(self.icon, False, False, 0)
            box.pack_start(self.label, True, True, 0)
            if self.can_rename():
                box.pack_start(self.entry, True, True, 0)
            box.pack_end(button, False, False, 0)

        page.set_tab(self)
        page.connect('name-changed', self.on_name_changed)
        self.show_all()
Пример #49
0
def __create_file_menu():
    items = []
    accelerators = []

    def new_playlist_cb(*args):
        get_main().playlist_container.create_new_playlist()

    accelerators.append(
        Accelerator('<Primary>t', _("_New Playlist"), new_playlist_cb))
    items.append(
        _smi('new-playlist', [],
             icon_name='tab-new',
             callback=accelerators[-1]))
    items.append(_sep('new-sep', [items[-1].name]))

    def open_cb(*args):
        dialog = dialogs.MediaOpenDialog(get_main().window)
        dialog.connect('uris-selected',
                       lambda d, uris: get_main().controller.open_uris(uris))
        dialog.show()

    accelerators.append(Accelerator('<Primary>o', _("_Open"), open_cb))
    items.append(
        _smi('open', [items[-1].name],
             icon_name='document-open',
             callback=accelerators[-1]))

    def open_uri_cb(*args):
        dialog = dialogs.URIOpenDialog(get_main().window)
        dialog.connect('uri-selected',
                       lambda d, uri: get_main().controller.open_uri(uri))
        dialog.show()

    accelerators.append(
        Accelerator('<Primary><Shift>o', _("Open _URL"), open_uri_cb))
    items.append(
        _smi('open-uri', [items[-1].name],
             icon_name='emblem-web',
             callback=accelerators[-1]))

    def open_dirs_cb(*args):
        dialog = dialogs.DirectoryOpenDialog(get_main().window)
        dialog.props.create_folders = False
        dialog.connect('uris-selected',
                       lambda d, uris: get_main().controller.open_uris(uris))
        dialog.show()

    items.append(
        _smi('open-dirs', [items[-1].name], _("Open _Directories"),
             'folder-open', open_dirs_cb))

    items.append(_sep('open-sep', [items[-1].name]))

    items.append(
        _smi(
            'import-playlist', [items[-1].name], _("_Import Playlist"),
            'document-open', lambda *e: get_main().controller.get_panel(
                'playlists').import_playlist()))

    def export_playlist_cb(*args):
        main = get_main()
        page = get_selected_playlist()
        if not page:
            return

        def on_message(dialog, message_type, message):
            """
                Show messages in the main window message area
            """
            if message_type == Gtk.MessageType.INFO:
                main.message.show_info(markup=message)
            elif message_type == Gtk.MessageType.ERROR:
                main.message.show_error(_('Playlist export failed!'), message)
            return True

        dialog = dialogs.PlaylistExportDialog(page.playlist, main.window)
        dialog.connect('message', on_message)
        dialog.show()

    items.append(
        _smi('export-playlist', [items[-1].name],
             _("E_xport Current Playlist"), 'document-save-as',
             export_playlist_cb))
    items.append(_sep('export-sep', [items[-1].name]))

    def close_tab_cb(*args):
        get_main().get_selected_page().tab.close()

    accelerators.append(
        Accelerator('<Primary>w', _("Close _Tab"), close_tab_cb))
    items.append(
        _smi('close-tab', [items[-1].name],
             icon_name='window-close',
             callback=accelerators[-1]))

    if get_main().controller.exaile.options.Debug:

        def restart_cb(*args):
            from xl import main
            main.exaile().quit(True)

        accelerators.append(
            Accelerator('<Primary>r', _("_Restart"), restart_cb))
        items.append(
            _smi('restart-application', [items[-1].name],
                 callback=accelerators[-1]))

    def quit_cb(*args):
        from xl import main
        main.exaile().quit()

    accelerators.append(Accelerator('<Primary>q', _("_Quit Exaile"), quit_cb))
    items.append(
        _smi('quit-application', [items[-1].name],
             icon_name='application-exit',
             callback=accelerators[-1]))

    for item in items:
        providers.register('menubar-file-menu', item)
    for accelerator in accelerators:
        providers.register('mainwindow-accelerators', accelerator)