def __init__(self): builder = Gtk.Builder() builder.add_from_file(xdg.get_data_path('ui', 'splash.ui')) image = builder.get_object('splash_image') image.set_from_file(xdg.get_data_path('images', 'splash.png')) self.window = builder.get_object('SplashScreen')
def get_rating_html(self, rating): html='' star = xdg.get_data_path("images", "star.png") bstar = xdg.get_data_path("images", "emptystar.png") maximum = settings.get_option("rating/maximum", 5) for i in range(rating): html+='<a href="rate://%d"><img src="file://%s"/></a>' % (i+1, star) for i in range(maximum-rating): html+='<a href="rate://%d"><img src="file://%s"/></a>' % (rating+i+1, bstar) return html
def __init__(self, parent=None): builder = gtk.Builder() builder.add_from_file(xdg.get_data_path('ui', 'about_dialog.ui')) self.dialog = builder.get_object('AboutDialog') self.dialog.set_transient_for(parent) logo = gtk.gdk.pixbuf_new_from_file( xdg.get_data_path('images', 'exailelogo.png')) self.dialog.set_logo(logo) from xl.main import __version__ self.dialog.set_version('\n%s' % __version__) self.dialog.connect('response', lambda dialog, response: dialog.destroy())
def __init__(self): self.icon_theme = Gtk.IconTheme.get_default() self.icon_factory = Gtk.IconFactory() self.icon_factory.add_default() # Any arbitrary widget is fine self.render_widget = Gtk.Button() self.system_visual = Gdk.Visual.get_system() # TODO: Make svg actually recognized self._sizes = [16, 22, 24, 32, 48, 128, 'scalable'] self._cache = {} self.rating_active_pixbuf = extended_pixbuf_new_from_file( xdg.get_data_path('images', 'star.png')) self.rating_inactive_pixbuf = extended_pixbuf_new_from_file( xdg.get_data_path('images', 'emptystar.png'))
def show_about_dialog(self, *e): """ Displays the about dialog """ import xl.main as xlmain builder = gtk.Builder() builder.add_from_file(xdg.get_data_path('ui/about_dialog.ui')) dialog = builder.get_object('AboutDialog') logo = gtk.gdk.pixbuf_new_from_file( xdg.get_data_path('images/exailelogo.png')) dialog.set_logo(logo) dialog.set_program_name('Exaile') dialog.set_version("\n" + str(xlmain.__version__)) dialog.set_transient_for(self.main.window) dialog.connect('response', lambda d, r: d.destroy()) dialog.show()
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)
def __init__(self, location): """ :param location: The directory to load and store data in. """ providers.ProviderHandler.__init__(self, "covers") self.__cache = Cacher(os.path.join(location, 'cache')) self.location = location self.methods = {} self.order = settings.get_option( 'covers/preferred_order', []) self.db = {} self.load() for method in self.get_providers(): self.on_provider_added(method) default_cover_file = open(xdg.get_data_path('images', 'nocover.png'), 'rb') self.default_cover_data = default_cover_file.read() default_cover_file.close() self.tag_fetcher = TagCoverFetcher() self.localfile_fetcher = LocalFileCoverFetcher() if settings.get_option('covers/use_tags', True): providers.register('covers', self.tag_fetcher) if settings.get_option('covers/use_localfile', True): providers.register('covers', self.localfile_fetcher) event.add_callback(self._on_option_set, 'covers_option_set')
def __init__(self, parent, collection): """ Initializes the dialog """ self.parent = parent self.collection = collection builder = gtk.Builder() builder.add_from_file(xdg.get_data_path( 'ui', 'collection_manager.ui')) self.dialog = builder.get_object('CollectionManager') self.dialog.set_transient_for(self.parent) self.view = builder.get_object('view') self.model = builder.get_object('model') self.remove_button = builder.get_object('remove_button') self.message = dialogs.MessageBar( parent=builder.get_object('content_area'), buttons=gtk.BUTTONS_CLOSE ) builder.connect_signals(self) selection = self.view.get_selection() selection.connect('changed', self.on_selection_changed) for location, library in collection.libraries.iteritems(): self.model.append([location, library.monitored, library.startup_scan])
def __init__(self, parent, track, search=None): """ Expects the parent control, a track, an an optional search string """ gobject.GObject.__init__(self) self.parent = parent self.builder = gtk.Builder() self.builder.add_from_file(xdg.get_data_path("ui/coverchooser.ui")) self.builder.connect_signals(self) self.window = self.builder.get_object("CoverChooser") self.window.set_title( _("Cover options for %(artist)s - %(album)s") % {"artist": track.get_tag_display("artist"), "album": track.get_tag_display("album")} ) self.window.set_transient_for(parent) self.message = dialogs.MessageBar(parent=self.builder.get_object("main_container"), buttons=gtk.BUTTONS_CLOSE) self.message.connect("response", self.on_message_response) self.track = track self.covers = [] self.current = 0 self.cover = guiutil.ScalableImageWidget() self.cover.set_image_size(350, 350) self.cover_image_box = self.builder.get_object("cover_image_box") self.loading_indicator = gtk.Alignment() self.loading_indicator.props.xalign = 0.5 self.loading_indicator.props.yalign = 0.5 self.loading_indicator.set_size_request(350, 350) self.cover_image_box.pack_start(self.loading_indicator) try: spinner = gtk.Spinner() spinner.set_size_request(100, 100) spinner.start() self.loading_indicator.add(spinner) except AttributeError: # Older than GTK 2.20 and PyGTK 2.22 self.loading_indicator.add(gtk.Label(_("Loading..."))) self.size_label = self.builder.get_object("size_label") self.source_label = self.builder.get_object("source_label") self.covers_model = self.builder.get_object("covers_model") self.previews_box = self.builder.get_object("previews_box") self.previews_box.set_no_show_all(True) self.previews_box.hide() self.previews_box.set_model(None) self.set_button = self.builder.get_object("set_button") self.set_button.set_sensitive(False) self.window.show_all() self.stopper = threading.Event() self.fetcher_thread = threading.Thread(target=self.fetch_cover, name="Coverfetcher") self.fetcher_thread.start()
def __setup_context_page(): '''Some of these icons may not exist''' ContextPage.TRACK_ICO_PATH = xdg.get_data_path('images/16x16/audio-x-generic.png') ContextPage.ARTIST_ICO_PATH = xdg.get_data_path("images/16x16/artist.png") ContextPage.SEARCH_ICO_PATH = None search_icon = gtk.icon_theme_get_default().lookup_icon(gtk.STOCK_FIND, gtk.ICON_SIZE_SMALL_TOOLBAR, gtk.ICON_LOOKUP_NO_SVG) if search_icon is not None: ContextPage.SEARCH_ICON_PATH = search_icon.get_filename() ContextPage.ALBUM_ICO_PATH = None album_icon = gtk.icon_theme_get_default().lookup_icon(gtk.STOCK_CDROM, gtk.ICON_SIZE_SMALL_TOOLBAR, gtk.ICON_LOOKUP_NO_SVG) if album_icon is not None: ContextPage.ALBUM_ICO_PATH = album_icon.get_filename()
def get_image_data(data, size): imbuff = ImageBuffer() try: im = Image.open(StringIO(data)) except Exception: im = Image.open(xdg.get_data_path('images/nocover.png')) im = im.resize(size, Image.ANTIALIAS) im.save(imbuff, "PNG") return 'data:image/png;base64,%s' % imbuff.get_base64()
def initialize_from_xml(this, other=None): ''' DEPRECATED. Use GtkComposite, GtkCallback, and GtkChild instead Initializes the widgets and signals from a GtkBuilder XML file. Looks for the following attributes in the instance you pass: ui_filename = builder filename -- either an absolute path, or a tuple with the path relative to the xdg data directory. ui_widgets = [list of widget names] ui_signals = [list of function names to connect to a signal] For each widget in ui_widgets, it will be retrieved from the builder object and set as an attribute on the object you pass in. other is a list of widgets to also initialize with the same file Returns the builder object when done ''' builder = Gtk.Builder() if isinstance(this.ui_filename, basestring) and os.path.exists(this.ui_filename): builder.add_from_file(this.ui_filename) else: builder.add_from_file(xdg.get_data_path(*this.ui_filename)) objects = [this] if other is not None: objects.extend(other) for obj in objects: if hasattr(obj, 'ui_widgets') and obj.ui_widgets is not None: for widget_name in obj.ui_widgets: widget = builder.get_object(widget_name) if widget is None: raise RuntimeError("Widget '%s' is not present in '%s'" % (widget_name, this.ui_filename)) setattr(obj, widget_name, widget) signals = None for obj in objects: if hasattr(obj, 'ui_signals') and obj.ui_signals is not None: if signals is None: signals = {} for signal_name in obj.ui_signals: if not hasattr(obj, signal_name): raise RuntimeError("Function '%s' is not present in '%s'" % (signal_name, obj)) signals[signal_name] = getattr(obj, signal_name) if signals is not None: missing = builder.connect_signals(signals) if missing is not None: err = 'The following signals were found in %s but have no assigned handler: %s' % (this.ui_filename, str(missing)) raise RuntimeError(err) return builder
def __init__(self, parent, pixbuf, album=None, savedir=None): """Initializes and shows the cover :param parent: Parent window to attach to :type parent: Gtk.Window :param pixbuf: Pixbuf of the cover image :type pixbuf: GdkPixbuf.Pixbuf :param album: Album title :type album: basestring :param savedir: Initial directory for the Save As functionality :type savedir: basestring """ self.builder = Gtk.Builder() self.builder.add_from_file(xdg.get_data_path('ui', 'coverwindow.ui')) self.builder.connect_signals(self) self.cover_window = self.builder.get_object('CoverWindow') self.layout = self.builder.get_object('layout') self.toolbar = self.builder.get_object('toolbar') self.save_as_button = self.builder.get_object('save_as_button') self.zoom_in_button = self.builder.get_object('zoom_in_button') self.zoom_out_button = self.builder.get_object('zoom_out_button') self.zoom_100_button = self.builder.get_object('zoom_100_button') self.zoom_fit_button = self.builder.get_object('zoom_fit_button') self.close_button = self.builder.get_object('close_button') self.image = self.builder.get_object('image') self.statusbar = self.builder.get_object('statusbar') self.scrolledwindow = self.builder.get_object('scrolledwindow') self.scrolledwindow.set_hadjustment(self.layout.get_hadjustment()) self.scrolledwindow.set_vadjustment(self.layout.get_vadjustment()) if album: title = _('Cover for %s') % album else: title = _('Cover') self.savedir = savedir self.cover_window.set_title(title) self.cover_window.set_transient_for(parent) self.cover_window_width = 500 tb_min_height, tb_natural_height = self.toolbar.get_preferred_height() sb_min_height, sb_natural_height = self.statusbar.get_preferred_height() self.cover_window_height = 500 + tb_natural_height + sb_natural_height self.cover_window.set_default_size(self.cover_window_width, \ self.cover_window_height) self.image_original_pixbuf = pixbuf self.image_pixbuf = self.image_original_pixbuf self.min_percent = 1 self.max_percent = 500 self.ratio = 1.5 self.image_interp = GdkPixbuf.InterpType.BILINEAR self.image_fitted = True self.set_ratio_to_fit() self.update_widgets()
def __init__(self, parent, pixbuf, album=None, savedir=None): """Initializes and shows the cover :param parent: Parent window to attach to :type parent: gtk.Window :param pixbuf: Pixbuf of the cover image :type pixbuf: gtk.gdk.Pixbuf :param album: Album title :type album: basestring :param savedir: Initial directory for the Save As functionality :type savedir: basestring """ self.builder = gtk.Builder() self.builder.add_from_file(xdg.get_data_path("ui/coverwindow.ui")) self.builder.connect_signals(self) self.cover_window = self.builder.get_object("CoverWindow") self.layout = self.builder.get_object("layout") self.toolbar = self.builder.get_object("toolbar") self.save_as_button = self.builder.get_object("save_as_button") self.zoom_in_button = self.builder.get_object("zoom_in_button") self.zoom_out_button = self.builder.get_object("zoom_out_button") self.zoom_100_button = self.builder.get_object("zoom_100_button") self.zoom_fit_button = self.builder.get_object("zoom_fit_button") self.close_button = self.builder.get_object("close_button") self.image = self.builder.get_object("image") self.statusbar = self.builder.get_object("statusbar") self.scrolledwindow = self.builder.get_object("scrolledwindow") self.scrolledwindow.set_hadjustment(self.layout.get_hadjustment()) self.scrolledwindow.set_vadjustment(self.layout.get_vadjustment()) if album: title = _("Cover for %s") % album else: title = _("Cover") self.savedir = savedir self.cover_window.set_title(title) self.cover_window.set_transient_for(parent) self.cover_window_width = 500 self.cover_window_height = 500 + self.toolbar.size_request()[1] + self.statusbar.size_request()[1] self.cover_window.set_default_size(self.cover_window_width, self.cover_window_height) self.image_original_pixbuf = pixbuf self.image_pixbuf = self.image_original_pixbuf self.min_percent = 1 self.max_percent = 500 self.ratio = 1.5 self.image_interp = gtk.gdk.INTERP_BILINEAR self.image_fitted = True self.set_ratio_to_fit() self.update_widgets()
def show_splash(show=True): """ Show a splash screen @param show: [bool] show the splash screen """ if not show: return image = gtk.Image() image.set_from_file(xdg.get_data_path("images/splash.png")) builder = gtk.Builder() builder.add_from_file(xdg.get_data_path("ui/splash.ui")) splash_screen = builder.get_object('SplashScreen') box = builder.get_object('splash_box') box.pack_start(image, True, True) splash_screen.set_transient_for(None) splash_screen.show_all() #ensure that the splash gets completely drawn before we move on while gtk.events_pending(): gtk.main_iteration() return splash_screen
def __init__(self, parent, collection): """ Initializes the window """ GObject.GObject.__init__(self) # List of identifiers of albums without covers self.outstanding = [] # Map of album identifiers and their tracks self.album_tracks = {} self.outstanding_text = _('{outstanding} covers left to fetch') self.completed_text = _('All covers fetched') self.cover_size = (90, 90) self.default_cover_pixbuf = icons.MANAGER.pixbuf_from_data( COVER_MANAGER.get_default_cover(), self.cover_size) builder = Gtk.Builder() builder.add_from_file(xdg.get_data_path('ui', 'covermanager.ui')) builder.connect_signals(self) self.window = builder.get_object('window') self.window.set_transient_for(parent) self.message = dialogs.MessageBar( parent=builder.get_object('content_area'), buttons=Gtk.ButtonsType.CLOSE ) self.previews_box = builder.get_object('previews_box') self.model = builder.get_object('covers_model') # Map of album identifiers and model paths self.model_path_cache = {} self.menu = CoverMenu(self) self.menu.attach_to_widget(self.previews_box, lambda menu, widget: True) self.progress_bar = builder.get_object('progressbar') self.progress_bar.set_text(_('Collecting albums and covers...')) self.progress_bar.pulse_timeout = \ GLib.timeout_add(100, self.on_progress_pulse_timeout) self.close_button = builder.get_object('close_button') self.stop_button = builder.get_object('stop_button') self.stop_button.set_sensitive(False) self.fetch_button = builder.get_object('fetch_button') self.window.show_all() self.stopper = threading.Event() thread = threading.Thread(target=self.prefetch, name='CoverPrefetch', args=(collection,)) thread.daemon = True thread.start()
def __init__(self, parent, main): self.main = main self.parent = parent self.device_manager = self.main.exaile.devices self.builder = gtk.Builder() self.builder.add_from_file(xdg.get_data_path('ui/device_manager.ui')) self.window = self.builder.get_object('device_manager') self.window.set_transient_for(self.parent) self.window.set_position(gtk.WIN_POS_CENTER_ON_PARENT) self.window.connect('delete-event', self.on_close) self.builder.connect_signals({ 'on_btn_connect_clicked': self.on_connect, 'on_btn_disconnect_clicked': self.on_disconnect, 'on_btn_edit_clicked': self.on_edit, 'on_btn_add_clicked': self.on_add, 'on_btn_remove_clicked': self.on_remove, 'on_btn_close_clicked': self.on_close, }) # TODO: make these actually work. For now, they are hidden for item in ('add', 'edit', 'remove'): self.builder.get_object('btn_%s' % item).destroy() # object should really be devices.Device, but it doesnt work :/ self.model = gtk.ListStore(object, gtk.gdk.Pixbuf, str, str) self.tree = self.builder.get_object('tree_devices') self.tree.set_model(self.model) render = gtk.CellRendererPixbuf() col = gtk.TreeViewColumn(_("Icon"), render) col.add_attribute(render, "pixbuf", 1) self.tree.append_column(col) render = gtk.CellRendererText() col = gtk.TreeViewColumn(_("Device"), render) col.set_expand(True) col.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE) col.add_attribute(render, "text", 2) self.tree.append_column(col) render = gtk.CellRendererText() col = gtk.TreeViewColumn(_("Driver"), render) col.add_attribute(render, "text", 3) self.tree.append_column(col) self.populate_tree() event.add_callback(self.populate_tree, 'device_added') event.add_callback(self.populate_tree, 'device_removed')
def show_splash(show=True): """ Show a splash screen @param show: [bool] show the splash screen """ if not show: return builder = gtk.Builder() builder.add_from_file(xdg.get_data_path("ui/splash.ui")) image = builder.get_object('splash_image') image.set_from_file(xdg.get_data_path("images/splash.png")) splash_screen = builder.get_object('SplashScreen') splash_screen.set_transient_for(None) # Show the splash screen without causing startup notification. gtk.window_set_auto_startup_notification(False) splash_screen.show_all() gtk.window_set_auto_startup_notification(True) #ensure that the splash gets completely drawn before we move on while gtk.events_pending(): gtk.main_iteration() return splash_screen
def ui_path(*path, **kwargs): ''' Returns absolute path to a UI file. Each arg will be concatenated to construct the final path. :param relto: If keyword arg 'relto' is specified, path will be relative to this. Otherwise, it will be relative to the Exaile data directory .. versionadded:: 3.5.0 ''' relto = kwargs.pop('relto', None) if len(kwargs): raise ValueError("Only 'relto' is allowed as a keyword argument") if relto is None: return xdg.get_data_path(*path) else: return os.path.abspath(os.path.join(os.path.dirname(relto), *path))
def __init__(self, player): Gtk.Bin.__init__(self) self.__player = player builder = Gtk.Builder() builder.add_from_file(xdg.get_data_path('ui', 'widgets', 'track_info.ui')) info_box = builder.get_object('info_box') info_box.reparent(self) self.__auto_update = False self.__display_progress = False self.__formatter = formatter.TrackFormatter( _( '<span size="x-large" weight="bold">$title</span>\n' 'by $artist\n' 'from $album' ) ) self.__formatter.connect('notify::format', self.on_notify_format) self.__default_text = '<span size="x-large" ' 'weight="bold">%s</span>\n\n' % _( 'Not Playing' ) self.__cover_size = None self.__timer = None self.__track = None self.info_label = builder.get_object('info_label') self.action_area = builder.get_object('action_area') self.progress_box = builder.get_object('progress_box') self.playback_image = builder.get_object('playback_image') self.progressbar = PlaybackProgressBar(player) guiutil.gtk_widget_replace(builder.get_object('progressbar'), self.progressbar) self.cover = cover.CoverWidget(builder.get_object('cover_image')) self.cover.hide() self.cover.set_no_show_all(True) self.clear() self.__update_widget_state()
def __init__(self, parent, name, label=None): """ Intializes the panel @param controller: the main gui controller @param name: the name of the panel. should be unique. @param label: text of the label displayed to the user """ gobject.GObject.__init__(self) self.name = name # panel id self.label = label # label to be displayed self.parent = parent # if the UI designer file starts with file:// use the full path minus # file://, otherwise check in the data directories ui_file = self.ui_info[0] if not os.path.isabs(ui_file): ui_file = xdg.get_data_path('ui', 'panel', ui_file) self.builder = gtk.Builder() self.builder.add_from_file(ui_file) self._child = None
def __init__(self, display_tracklist=False): """ :param display_tracklist: Whether to display a short list of tracks """ Gtk.Alignment.__init__(self) builder = Gtk.Builder() builder.add_from_file(xdg.get_data_path( 'ui', 'widgets', 'tracklist_info.ui')) info_box = builder.get_object('info_box') info_box.reparent(self) self._display_tracklist = display_tracklist self.cover = cover.CoverWidget(builder.get_object('cover_image')) self.album_label = builder.get_object('album_label') self.artist_label = builder.get_object('artist_label') if self._display_tracklist: self.tracklist_table = builder.get_object('tracklist_table') self.tracklist_table.set_no_show_all(False) self.tracklist_table.set_property('visible', True) self.total_label = builder.get_object('total_label') self.total_label.set_no_show_all(False) self.total_label.set_property('visible', True) self.rownumber = 1 self.pango_attributes = Pango.AttrList() self.pango_attributes.insert( Pango.AttrScale(Pango.SCALE_SMALL, end_index=-1)) self.pango_attributes.insert( Pango.AttrStyle(Pango.Style.ITALIC, end_index=-1)) self.ellipse_pango_attributes = Pango.AttrList() self.ellipse_pango_attributes.insert( Pango.AttrWeight(Pango.Weight.BOLD, end_index=-1))
def __init__(self, player): self.__volume_setting = '%s/volume' % player._name gtk.Alignment.__init__(self, xalign=1) self.restore_volume = settings.get_option(self.__volume_setting, 1) self.icon_names = ['low', 'medium', 'high'] builder = gtk.Builder() builder.add_from_file(xdg.get_data_path('ui', 'widgets', 'volume_control.ui')) builder.connect_signals(self) box = builder.get_object('volume_control') box.reparent(self) self.button = builder.get_object('button') self.button.add_events(gtk.gdk.KEY_PRESS_MASK) self.button_image = builder.get_object('button_image') self.slider = builder.get_object('slider') self.slider_adjustment = builder.get_object('slider_adjustment') self.__update(self.restore_volume) event.add_callback(self.on_option_set, '%s_option_set' % player._name)
def __init__(self, parent, main): """ Initializes the preferences dialog """ self.main = main self.last_child = None self.last_page = None self.parent = parent self.settings = MANAGER self.fields = {} self.panes = {} self.builders = {} self.popup = None self.builder = Gtk.Builder() self.builder.set_translation_domain('exaile') self.builder.add_from_file( xdg.get_data_path('ui', 'preferences', 'preferences_dialog.ui')) self.builder.connect_signals(self) self.window = self.builder.get_object('PreferencesDialog') self.window.set_transient_for(parent) self.window.set_position(Gtk.WindowPosition.CENTER_ON_PARENT) self.window.connect('delete-event', lambda *e: self.close()) self.box = self.builder.get_object('preferences_box') self.tree = self.builder.get_object('preferences_tree') self.model = self.builder.get_object('model') title_cellrenderer = self.builder.get_object('title_cellrenderer') title_cellrenderer.props.ypad = 3 self.default_icon = icons.MANAGER.pixbuf_from_stock( Gtk.STOCK_PROPERTIES, Gtk.IconSize.MENU) # sets up the default panes for page in self.PAGES: icon = self.default_icon if hasattr(page, 'icon'): if isinstance(page.icon, GdkPixbuf.Pixbuf): icon = page.icon else: stock = Gtk.stock_lookup(page.icon) if stock is not None: icon = icons.MANAGER.pixbuf_from_stock( stock.stock_id , Gtk.IconSize.MENU) else: icon = icons.MANAGER.pixbuf_from_icon_name( page.icon, Gtk.IconSize.MENU) self.model.append(None, [page, page.name, icon]) # Use icon name to allow overrides plugin_icon = icons.MANAGER.pixbuf_from_icon_name( 'extension', Gtk.IconSize.MENU) self.plug_root = self.model.append(None, [plugin, _('Plugins'), plugin_icon]) self._load_plugin_pages() selection = self.tree.get_selection() selection.connect('changed', self.switch_pane) # Disallow selection on rows with no widget to show selection.set_select_function( (lambda sel, model, path, issel, dat: model[path][0] is not None), None) GLib.idle_add(selection.select_path, (0,))
def __init(self): """ Initializes Exaile """ # pylint: disable-msg=W0201 logger.info("Loading Exaile %s on Python %s..." % (__version__, platform.python_version())) logger.info("Loading settings...") try: from xl import settings except common.VersionError: logger.exception("Error loading settings") sys.exit(1) logger.debug("Settings loaded from %s" % settings.location) # display locale information if available try: import locale lc, enc = locale.getlocale() if enc is not None: logger.info("Using %s %s locale" % (lc, enc)) else: logger.info("Using unknown locale") except: pass splash = None if self.options.StartGui: from xl import settings if settings.get_option('gui/use_splash', True): from xlgui.widgets.info import Splash splash = Splash() splash.show() firstrun = settings.get_option("general/first_run", True) if not self.options.NoImport and \ (firstrun or self.options.ForceImport): try: sys.path.insert(0, xdg.get_data_path("migrations")) import migration_200907100931 as migrator del sys.path[0] migrator.migrate(force=self.options.ForceImport) del migrator except: logger.exception("Failed to migrate from 0.2.14") # Migrate old rating options from xl.migrations.settings import rating rating.migrate() # Migrate builtin OSD to plugin from xl.migrations.settings import osd osd.migrate() # Migrate engines from xl.migrations.settings import engine engine.migrate() # TODO: enable audio plugins separately from normal # plugins? What about plugins that use the player? # Gstreamer doesn't initialize itself automatically, and fails # miserably when you try to inherit from something and GST hasn't # been initialized yet. So this is here. from gi.repository import Gst Gst.init(None) # Initialize plugin manager from xl import plugins self.plugins = plugins.PluginsManager(self) if not self.options.SafeMode: logger.info("Loading plugins...") self.plugins.load_enabled() else: logger.info("Safe mode enabled, not loading plugins.") # Initialize the collection logger.info("Loading collection...") from xl import collection try: self.collection = collection.Collection("Collection", location=os.path.join(xdg.get_data_dir(), 'music.db')) except common.VersionError: logger.exception("VersionError loading collection") sys.exit(1) from xl import event # Set up the player and playback queue from xl import player event.log_event("player_loaded", player.PLAYER, None) # Initalize playlist manager from xl import playlist self.playlists = playlist.PlaylistManager() self.smart_playlists = playlist.PlaylistManager('smart_playlists', playlist.SmartPlaylist) if firstrun: self._add_default_playlists() event.log_event("playlists_loaded", self, None) # Initialize dynamic playlist support from xl import dynamic dynamic.MANAGER.collection = self.collection # Initalize device manager logger.info("Loading devices...") from xl import devices self.devices = devices.DeviceManager() event.log_event("device_manager_ready", self, None) # Initialize dynamic device discovery interface # -> if initialized and connected, then the object is not None self.udisks2 = None self.udisks = None self.hal = None if self.options.Hal: from xl import hal udisks2 = hal.UDisks2(self.devices) if udisks2.connect(): self.udisks2 = udisks2 else: udisks = hal.UDisks(self.devices) if udisks.connect(): self.udisks = udisks else: self.hal = hal.HAL(self.devices) self.hal.connect() else: self.hal = None # Radio Manager from xl import radio self.stations = playlist.PlaylistManager('radio_stations') self.radio = radio.RadioManager() self.gui = None # Setup GUI if self.options.StartGui: logger.info("Loading interface...") import xlgui self.gui = xlgui.Main(self) self.gui.main.window.show_all() event.log_event("gui_loaded", self, None) if splash is not None: splash.destroy() restore = True if self.gui: # Find out if the user just passed in a list of songs # TODO: find a better place to put this # using arg[2:] because arg[1:] will include --startgui args = [ Gio.File.new_for_path(arg).get_uri() for arg in self.options.locs ] if len(args) > 0: restore = False self.gui.open_uri(args[0], play=True) for arg in args[1:]: self.gui.open_uri(arg) # kick off autoscan of libraries # -> don't do it in command line mode, since that isn't expected self.gui.rescan_collection_with_progress(True) if restore: player.QUEUE._restore_player_state( os.path.join(xdg.get_data_dir(), 'player.state')) if firstrun: settings.set_option("general/first_run", False) self.loading = False Exaile._exaile = self event.log_event("exaile_loaded", self, None)
# from your version. import gtk from xl import ( covers, settings, xdg ) from xl.nls import gettext as _ from xlgui import icons 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, widgets.CheckConditional): default = ['front', 'cover', 'album'] name = 'covers/localfile/preferred_names' condition_preference_name = 'covers/use_localfile' def __init__(self, preferences, widget):
def __init__(self, parent, tracks, current_position=0, with_extras=False): """ :param parent: the parent window for modal operation :type parent: :class:`Gtk.Window` :param tracks: the tracks to process :type tracks: list of :class:`xl.trax.Track` objects :param current_position: the position of the currently selected track in the list :type current_position: int :param with_extras: whether there are extra, non-selected tracks in `tracks` (currently happens when only 1 track is selected) :type with_extras: bool """ GObject.GObject.__init__(self) self.builder = Gtk.Builder() self.builder.add_from_file(xdg.get_data_path('ui', 'trackproperties_dialog.ui')) self.builder.connect_signals(self) self.dialog = self.builder.get_object('TrackPropertiesDialog') self.dialog.set_transient_for(parent) self.__default_attributes = Pango.AttrList() self.__changed_attributes = Pango.AttrList() self.message = dialogs.MessageBar( parent=self.builder.get_object('main_container'), buttons=Gtk.ButtonsType.CLOSE ) self.remove_tag_button = self.builder.get_object('remove_tag_button') self.cur_track_label = self.builder.get_object('current_track_label') self.apply_button = self.builder.get_object('apply_button') self.prev_button = self.builder.get_object('prev_track_button') self.next_button = self.builder.get_object('next_track_button') self.tags_table = self.builder.get_object('tags_table') self.properties_table = self.builder.get_object('properties_table') self.rows = [] self.new_tag_combo = self.builder.get_object('new_tag_combo') self.new_tag_combo_list = Gtk.ListStore(str, str) for tag, tag_info in tag_data.iteritems(): if tag_info is not None and tag_info.editable: self.new_tag_combo_list.append((tag, tag_info.translated_name)) self.new_tag_combo_list.set_sort_column_id(1, Gtk.SortType.ASCENDING) self.new_tag_combo.set_model(self.new_tag_combo_list) self.add_tag_button = self.builder.get_object('add_tag_button') self.add_tag_button.set_sensitive(False) # Show these tags for all tracks, no matter what def_tags = [ 'tracknumber', 'title', 'artist', 'album', 'discnumber', 'date', 'genre', 'cover', 'comment', '__startoffset', '__stopoffset' ] self.def_tags = OrderedDict([(tag, tag_data[tag]) for tag in def_tags]) # Store the tracks and a working copy self.tracks = tracks self.trackdata = self._tags_copy(tracks) self.trackdata_original = self._tags_copy(tracks) self.current_position = current_position self._build_from_track(self.current_position) self.dialog.resize(600, 350) self.dialog.show() self.rows[0].field.grab_focus()
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import gtk from xl import xdg from xl.nls import gettext as _ from xlgui.preferences import widgets name = _('Collection') icon = 'folder-music' ui = xdg.get_data_path('ui', 'preferences', 'collection.ui') def _get_default_strip_list(): return [] # currently, this is broken by the backend not also having access to the default set here, so we will just NOT set one. FIXME #TRANSLATORS: Grammatical articles that are ignored while sorting the #collection panel. For example, in French locales this could be #the space-separated list "l' la le les". #If this practice is not common in your locale, simply #translate this to an empty string. default_strip_list = _("the") return [v.lower() for v in default_strip_list.split(' ') if v is not ''] class CollectionStripArtistPreference(widgets.ListPreference): default = _get_default_strip_list() name = 'collection/strip_list'
def __init__(self, exaile): """ Initializes the GUI @param exaile: The Exaile instance """ from xlgui import main, panel, tray, progress from xlgui.panel import collection, radio, playlists, files gtk.gdk.set_program_class("Exaile") self.exaile = exaile self.first_removed = False self.tray_icon = None self.panels = {} self.builder = gtk.Builder() self.builder.add_from_file(xdg.get_data_path("ui/main.ui")) self.progress_box = self.builder.get_object('progress_box') self.progress_manager = progress.ProgressManager(self.progress_box) icons.MANAGER.add_icon_name_from_directory('exaile', xdg.get_data_path('images')) gtk.window_set_default_icon_name('exaile') icons.MANAGER.add_icon_name_from_directory('exaile-pause', xdg.get_data_path('images')) icons.MANAGER.add_icon_name_from_directory('exaile-play', xdg.get_data_path('images')) for name in ('dynamic', 'repeat', 'shuffle'): icon_name = 'media-playlist-%s' % name icons.MANAGER.add_icon_name_from_directory(icon_name, xdg.get_data_path('images')) logger.info("Loading main window...") self.main = main.MainWindow(self, self.builder, exaile.collection, exaile.player, exaile.queue, covers.MANAGER) self.panel_notebook = self.builder.get_object('panel_notebook') self.play_toolbar = self.builder.get_object('play_toolbar') logger.info("Loading panels...") self.panels['collection'] = collection.CollectionPanel(self.main.window, exaile.collection, _show_collection_empty_message=True) self.panels['radio'] = radio.RadioPanel(self.main.window, exaile.collection, exaile.radio, exaile.stations) self.panels['playlists'] = playlists.PlaylistsPanel(self.main.window, exaile.playlists, exaile.smart_playlists, exaile.collection) self.panels['files'] = files.FilesPanel(self.main.window, exaile.collection) for panel in ('collection', 'radio', 'playlists', 'files'): self.add_panel(*self.panels[panel].get_panel()) # add the device panels for device in self.exaile.devices.list_devices(): if device.connected: self.add_device_panel(None, None, device) logger.info("Connecting panel events...") self.main._connect_panel_events() if settings.get_option('gui/use_tray', False): self.tray_icon = tray.TrayIcon(self.main) self.device_panels = {} event.add_callback(self.add_device_panel, 'device_connected') event.add_callback(self.remove_device_panel, 'device_disconnected') event.add_callback(self.on_gui_loaded, 'gui_loaded') logger.info("Done loading main window...") Main._main = self
# This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. from xlgui.preferences import widgets from xl.nls import gettext as _ from xl import xdg name = _('Lyrics Viewer') ui = xdg.get_data_path('ui', 'preferences', 'lyrics.ui') DEFAULT_FONT = None class LyricsFontPreference(widgets.FontButtonPreference): default = None name = 'plugin/lyricsviewer/lyrics_font' def __init__(self, preferences, widget): self.default = DEFAULT_FONT widgets.FontButtonPreference.__init__(self, preferences, widget) class LyricsFontResetButtonPreference(widgets.FontResetButtonPreference):
# 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, widgets.CheckConditional): default = ['front', 'cover', 'album']