def _widgets_lyrics(self): horiz_spacing = 2 vert_spacing = 1 self.info_lyrics = ui.expander(markup="<b>%s</b>" % _("Lyrics"), expand=self.config.info_lyrics_expanded, can_focus=False) self.info_lyrics.connect("activate", self._expanded, "lyrics") lyricsbox = gtk.VBox() self.lyricsText = ui.textview(text="", edit=False, wrap=True) self._populate_lyrics_tag_table() self.lyricsSw = ui.scrollwindow(policy_x=gtk.POLICY_NEVER, policy_y=gtk.POLICY_NEVER, add=self.lyricsText) lyricsbox.pack_start(self.lyricsSw, True, True, vert_spacing) lyricsbox_bottom = gtk.HBox() self._searchlabel = ui.label(y=0) self._editlyricslabel = ui.label(y=0) searchevbox = ui.eventbox(add=self._searchlabel) editlyricsevbox = ui.eventbox(add=self._editlyricslabel) self._apply_link_signals(searchevbox, 'search', _("Search Lyricwiki.org for lyrics")) self._apply_link_signals(editlyricsevbox, 'editlyrics', _("Edit lyrics at Lyricwiki.org")) lyricsbox_bottom.pack_start(searchevbox, False, False, horiz_spacing) lyricsbox_bottom.pack_start(editlyricsevbox, False, False, horiz_spacing) lyricsbox.pack_start(lyricsbox_bottom, False, False, vert_spacing) self.info_lyrics.add(lyricsbox) return self.info_lyrics
def _widgets_lyrics(self): horiz_spacing = 2 vert_spacing = 1 self.info_lyrics = ui.expander(markup='<b>%s</b>' % _('Lyrics'), expand=self.config.info_lyrics_expanded, can_focus=False) self.info_lyrics.connect('activate', self._expanded, 'lyrics') lyricsbox = gtk.VBox() self.lyricsText = ui.label(markup=' ', y=0, select=True, wrap=True) lyricsbox.pack_start(self.lyricsText, True, True, vert_spacing) lyricsbox_bottom = gtk.HBox() self._searchlabel = ui.label(y=0) self._editlyricslabel = ui.label(y=0) searchevbox = ui.eventbox(add=self._searchlabel) editlyricsevbox = ui.eventbox(add=self._editlyricslabel) self._apply_link_signals(searchevbox, 'search', _('Search Lyricwiki.org for lyrics')) self._apply_link_signals(editlyricsevbox, 'editlyrics', _('Edit lyrics at Lyricwiki.org')) lyricsbox_bottom.pack_start(searchevbox, False, False, horiz_spacing) lyricsbox_bottom.pack_start(editlyricsevbox, False, False, horiz_spacing) lyricsbox.pack_start(lyricsbox_bottom, False, False, vert_spacing) self.info_lyrics.add(lyricsbox) return self.info_lyrics
def _widgets_song(self): info_song = ui.expander(markup="<b>%s</b>" % _("Song Info"), expand=self.config.info_song_expanded, can_focus=False) info_song.connect("activate", self._expanded, "song") self.info_labels = {} self.info_boxes_in_more = [] labels = [(_("Title"), 'title', False, "", False), (_("Artist"), 'artist', True, _("Launch artist in Wikipedia"), False), (_("Album"), 'album', True, _("Launch album in Wikipedia"), False), (_("Date"), 'date', False, "", False), (_("Track"), 'track', False, "", False), (_("Genre"), 'genre', False, "", False), (_("File"), 'file', False, "", True), (_("Bitrate"), 'bitrate', False, "", True)] tagtable = gtk.Table(len(labels), 2) tagtable.set_col_spacings(12) for i,(text, name, link, tooltip, in_more) in enumerate(labels): label = ui.label(markup="<b>%s:</b>" % text, y=0) tagtable.attach(label, 0, 1, i, i+1, yoptions=gtk.SHRINK) if i == 0: self.info_left_label = label # Using set_selectable overrides the hover cursor that # sonata tries to set for the links, and I can't figure # out how to stop that. So we'll disable set_selectable # for those labels until it's figured out. tmplabel2 = ui.label(wrap=True, y=0, select=not link) if link: tmpevbox = ui.eventbox(add=tmplabel2) self._apply_link_signals(tmpevbox, name, tooltip) to_pack = tmpevbox if link else tmplabel2 tagtable.attach(to_pack, 1, 2, i, i+1, yoptions=gtk.SHRINK) self.info_labels[name] = tmplabel2 if in_more: self.info_boxes_in_more.append(label) self.info_boxes_in_more.append(to_pack) self._morelabel = ui.label(y=0) self.toggle_more() moreevbox = ui.eventbox(add=self._morelabel) self._apply_link_signals(moreevbox, 'more', _("Toggle extra tags")) self._editlabel = ui.label(y=0) editevbox = ui.eventbox(add=self._editlabel) self._apply_link_signals(editevbox, 'edit', _("Edit song tags")) mischbox = gtk.HBox() mischbox.pack_start(moreevbox, False, False, 3) mischbox.pack_start(editevbox, False, False, 3) tagtable.attach(mischbox, 0, 2, len(labels), len(labels) + 1) inner_hbox = gtk.HBox() inner_hbox.pack_start(self._imagebox, False, False, 6) inner_hbox.pack_start(tagtable, False, False, 6) info_song.add(inner_hbox) return info_song
def _widgets_song(self): info_song = ui.expander(markup="<b>%s</b>" % _("Song Info"), expand=self.config.info_song_expanded, can_focus=False) info_song.connect("activate", self._expanded, "song") self.info_labels = {} self.info_boxes_in_more = [] labels = [(_("Title"), 'title', False, "", False), (_("Artist"), 'artist', True, _("Launch artist in Wikipedia"), False), (_("Album"), 'album', True, _("Launch album in Wikipedia"), False), (_("Date"), 'date', False, "", False), (_("Track"), 'track', False, "", False), (_("Genre"), 'genre', False, "", False), (_("File"), 'file', False, "", True), (_("Bitrate"), 'bitrate', False, "", True)] tagtable = gtk.Table(len(labels), 2) tagtable.set_col_spacings(12) for i, (text, name, link, tooltip, in_more) in enumerate(labels): label = ui.label(markup="<b>%s:</b>" % text, y=0) tagtable.attach(label, 0, 1, i, i + 1, yoptions=gtk.SHRINK) if i == 0: self.info_left_label = label # Using set_selectable overrides the hover cursor that # sonata tries to set for the links, and I can't figure # out how to stop that. So we'll disable set_selectable # for those labels until it's figured out. tmplabel2 = ui.label(wrap=True, y=0, select=not link) if link: tmpevbox = ui.eventbox(add=tmplabel2) self._apply_link_signals(tmpevbox, name, tooltip) to_pack = tmpevbox if link else tmplabel2 tagtable.attach(to_pack, 1, 2, i, i + 1, yoptions=gtk.SHRINK) self.info_labels[name] = tmplabel2 if in_more: self.info_boxes_in_more.append(label) self.info_boxes_in_more.append(to_pack) self._morelabel = ui.label(y=0) self.toggle_more() moreevbox = ui.eventbox(add=self._morelabel) self._apply_link_signals(moreevbox, 'more', _("Toggle extra tags")) self._editlabel = ui.label(y=0) editevbox = ui.eventbox(add=self._editlabel) self._apply_link_signals(editevbox, 'edit', _("Edit song tags")) mischbox = gtk.HBox() mischbox.pack_start(moreevbox, False, False, 3) mischbox.pack_start(editevbox, False, False, 3) tagtable.attach(mischbox, 0, 2, len(labels), len(labels) + 1) inner_hbox = gtk.HBox() inner_hbox.pack_start(self._imagebox, False, False, 6) inner_hbox.pack_start(tagtable, False, False, 6) info_song.add(inner_hbox) return info_song
def on_streams_new(self, _action, stream_num=-1): if stream_num > -1: edit_mode = True else: edit_mode = False # Prompt user for playlist name: dialog = ui.dialog(title=None, parent=self.window, flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT), role="streamsNew") if edit_mode: dialog.set_title(_("Edit Stream")) else: dialog.set_title(_("New Stream")) hbox = gtk.HBox() namelabel = ui.label(text=_('Stream name') + ':') hbox.pack_start(namelabel, False, False, 5) nameentry = ui.entry() if edit_mode: nameentry.set_text(self.config.stream_names[stream_num]) hbox.pack_start(nameentry, True, True, 5) hbox2 = gtk.HBox() urllabel = ui.label(text=_('Stream URL') + ':') hbox2.pack_start(urllabel, False, False, 5) urlentry = ui.entry() if edit_mode: urlentry.set_text(self.config.stream_uris[stream_num]) hbox2.pack_start(urlentry, True, True, 5) ui.set_widths_equal([namelabel, urllabel]) dialog.vbox.pack_start(hbox) dialog.vbox.pack_start(hbox2) ui.show(dialog.vbox) response = dialog.run() if response == gtk.RESPONSE_ACCEPT: name = nameentry.get_text() uri = urlentry.get_text() if len(name.decode('utf-8')) > 0 and len(uri.decode('utf-8')) > 0: # Make sure this stream name doesn't already exit: i = 0 for item in self.config.stream_names: # Prevent a name collision in edit_mode.. if not edit_mode or (edit_mode and i != stream_num): if item == name: dialog.destroy() if ui.show_msg(self.window, _("A stream with this name already exists. Would you like to replace it?"), _("New Stream"), 'newStreamError', gtk.BUTTONS_YES_NO) == gtk.RESPONSE_YES: # Pop existing stream: self.config.stream_names.pop(i) self.config.stream_uris.pop(i) else: return i = i + 1 if edit_mode: self.config.stream_names.pop(stream_num) self.config.stream_uris.pop(stream_num) self.config.stream_names.append(name) self.config.stream_uris.append(uri) self.populate() self.settings_save() dialog.destroy() self.iterate_now()
def on_streams_new(self, _action, stream_num=-1): if stream_num > -1: edit_mode = True else: edit_mode = False # Prompt user for playlist name: dialog = ui.dialog(title=None, parent=self.window, flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT), role="streamsNew") if edit_mode: dialog.set_title(_("Edit Stream")) else: dialog.set_title(_("New Stream")) hbox = gtk.HBox() namelabel = ui.label(text=_('Stream name:')) hbox.pack_start(namelabel, False, False, 5) nameentry = ui.entry() if edit_mode: nameentry.set_text(self.config.stream_names[stream_num]) hbox.pack_start(nameentry, True, True, 5) hbox2 = gtk.HBox() urllabel = ui.label(text=_('Stream URL:')) hbox2.pack_start(urllabel, False, False, 5) urlentry = ui.entry() if edit_mode: urlentry.set_text(self.config.stream_uris[stream_num]) hbox2.pack_start(urlentry, True, True, 5) ui.set_widths_equal([namelabel, urllabel]) dialog.vbox.pack_start(hbox) dialog.vbox.pack_start(hbox2) ui.show(dialog.vbox) response = dialog.run() if response == gtk.RESPONSE_ACCEPT: name = nameentry.get_text() uri = urlentry.get_text() if len(name.decode('utf-8')) > 0 and len(uri.decode('utf-8')) > 0: # Make sure this stream name doesn't already exit: i = 0 for item in self.config.stream_names: # Prevent a name collision in edit_mode.. if not edit_mode or (edit_mode and i != stream_num): if item == name: dialog.destroy() if ui.show_msg(self.window, _("A stream with this name already exists. Would you like to replace it?"), _("New Stream"), 'newStreamError', gtk.BUTTONS_YES_NO) == gtk.RESPONSE_YES: # Pop existing stream: self.config.stream_names.pop(i) self.config.stream_uris.pop(i) else: return i = i + 1 if edit_mode: self.config.stream_names.pop(stream_num) self.config.stream_uris.pop(stream_num) self.config.stream_names.append(name) self.config.stream_uris.append(uri) self.populate() self.settings_save() dialog.destroy()
def prefs_art_location_changed(self, combobox): if combobox.get_active() == consts.ART_LOCATION_CUSTOM: # Prompt user for playlist name: dialog = ui.dialog( title=_("Custom Artwork"), parent=self.window, flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT), role='customArtwork', default=gtk.RESPONSE_ACCEPT) hbox = gtk.HBox() hbox.pack_start(ui.label(text=_('Artwork filename') + ':'), False, False, 5) entry = ui.entry() entry.set_activates_default(True) hbox.pack_start(entry, True, True, 5) dialog.vbox.pack_start(hbox) dialog.vbox.show_all() response = dialog.run() if response == gtk.RESPONSE_ACCEPT: self.art_location_custom_filename = entry.get_text().replace( "/", "") else: # Revert to non-custom item in combobox: combobox.set_active(self.art_location) dialog.destroy() self.art_location = combobox.get_active()
def on_prefs_real(self): """Display the preferences dialog""" self.prefswindow = ui.dialog(title=_("Preferences"), parent=self.window, flags=gtk.DIALOG_DESTROY_WITH_PARENT, role='preferences', resizable=False, separator=False) self.prefsnotebook = gtk.Notebook() tabs = [(_("MPD"), 'mpd'), (_("Display"), 'display'), (_("Behavior"), 'behavior'), (_("Format"), 'format'), (_("Extras"), 'extras'), (_("Plugins"), 'plugins'), ] for display_name, name in tabs: label = ui.label(text=display_name) func = getattr(self, '%s_tab' % name) cbs = globals().get('%s_cbs' % name.capitalize()) tab = func(cbs) self.prefsnotebook.append_page(tab, label) hbox = gtk.HBox() hbox.pack_start(self.prefsnotebook, False, False, 10) self.prefswindow.vbox.pack_start(hbox, False, False, 10) close_button = self.prefswindow.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE) self.prefswindow.show_all() self.prefsnotebook.set_current_page(self.last_tab) close_button.grab_focus() self.prefswindow.connect('response', self._window_response) # Save previous connection properties to determine if we should try to # connect to MPD after prefs are closed: self.prev_host = self.config.host[self.config.profile_num] self.prev_port = self.config.port[self.config.profile_num] self.prev_password = self.config.password[self.config.profile_num]
def prompt_for_playlist_name(self, title, role): plname = None if self.connected(): # Prompt user for playlist name: dialog = ui.dialog(title=title, parent=self.window, flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_SAVE, gtk.RESPONSE_ACCEPT), role=role, default=gtk.RESPONSE_ACCEPT) hbox = gtk.HBox() hbox.pack_start(ui.label(text=_('Playlist name:')), False, False, 5) entry = ui.entry() entry.set_activates_default(True) hbox.pack_start(entry, True, True, 5) dialog.vbox.pack_start(hbox) ui.show(dialog.vbox) response = dialog.run() if response == gtk.RESPONSE_ACCEPT: plname = misc.strip_all_slashes(entry.get_text()) dialog.destroy() return plname
def on_prefs_real(self, extras_cbs, display_cbs, behavior_cbs, format_cbs): """Display the preferences dialog""" self.prefswindow = ui.dialog(title=_("Preferences"), parent=self.window, flags=gtk.DIALOG_DESTROY_WITH_PARENT, role='preferences', resizable=False, separator=False) self.prefsnotebook = gtk.Notebook() tabs = [(_("MPD"), 'mpd'), (_("Display"), 'display'), (_("Behavior"), 'behavior'), (_("Format"), 'format'), (_("Extras"), 'extras'), (_("Plugins"), 'plugins'), ] for display_name, name in tabs[:-1]: label = ui.label(text=display_name) func = getattr(self, '%s_tab' % name) tab = func(locals().get('%s_cbs' % name)) self.prefsnotebook.append_page(tab, label) hbox = gtk.HBox() hbox.pack_start(self.prefsnotebook, False, False, 10) self.prefswindow.vbox.pack_start(hbox, False, False, 10) close_button = self.prefswindow.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE) self.prefswindow.show_all() self.prefsnotebook.set_current_page(self.last_tab) close_button.grab_focus() self.prefswindow.connect('response', self._window_response) # Save previous connection properties to determine if we should try to # connect to MPD after prefs are closed: self.prev_host = self.config.host[self.config.profile_num] self.prev_port = self.config.port[self.config.profile_num] self.prev_password = self.config.password[self.config.profile_num]
def prompt_for_playlist_name(self, title, role): plname = None if self.connected(): # Prompt user for playlist name: dialog = ui.dialog( title=title, parent=self.window, flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_SAVE, gtk.RESPONSE_ACCEPT), role=role, default=gtk.RESPONSE_ACCEPT) hbox = gtk.HBox() hbox.pack_start(ui.label(text=_('Playlist name') + ':'), False, False, 5) entry = ui.entry() entry.set_activates_default(True) hbox.pack_start(entry, True, True, 5) dialog.vbox.pack_start(hbox) ui.show(dialog.vbox) response = dialog.run() if response == gtk.RESPONSE_ACCEPT: plname = misc.strip_all_slashes(entry.get_text()) dialog.destroy() return plname
def _widgets_album(self): info_album = ui.expander(markup='<b>%s</b>' % _('Album Info'), expand=self.config.info_album_expanded, can_focus=False) info_album.connect('activate', self._expanded, 'album') self.albumText = ui.label(markup=' ', y=0, select=True, wrap=True) info_album.add(self.albumText) return info_album
def _widgets_album(self): info_album = ui.expander(markup="<b>%s</b>" % _("Album Info"), expand=self.config.info_album_expanded, can_focus=False) info_album.connect("activate", self._expanded, "album") self.albumText = ui.label(markup=" ", y=0, select=True, wrap=True) info_album.add(self.albumText) return info_album
def __init__(self, config, info_image, linkcolor, on_link_click_cb, library_return_search_items, get_playing_song, TAB_INFO, on_image_activate, on_image_motion_cb, on_image_drop_cb): self.config = config self.info_image = info_image self.linkcolor = linkcolor self.on_link_click_cb = on_link_click_cb self.library_return_search_items = library_return_search_items self.get_playing_song = get_playing_song self.TAB_INFO = TAB_INFO self.on_image_activate = on_image_activate self.on_image_motion_cb = on_image_motion_cb self.on_image_drop_cb = on_image_drop_cb try: self.enc = locale.getpreferredencoding() except: print "Locale cannot be found; please set your system's locale. Aborting..." sys.exit(1) self.lyricServer = None self.last_info_bitrate = None self.info_boxes_in_more = None self.info_editlabel = None self.info_editlyricslabel = None self.info_labels = None self.info_left_label = None self.info_lyrics = None self.info_morelabel = None self.info_searchlabel = None self.info_tagbox = None self.info_type = None self.lyricsText = None self.albumText = None # Info tab self.info_area = ui.scrollwindow() if self.config.info_art_enlarged: self.info_imagebox = ui.eventbox() else: self.info_imagebox = ui.eventbox(w=152) self.info_imagebox.add(self.info_image) infohbox = gtk.HBox() infohbox.pack_start(ui.image(stock=gtk.STOCK_JUSTIFY_FILL), False, False, 2) infohbox.pack_start(ui.label(text=self.TAB_INFO), False, False, 2) self.infoevbox = ui.eventbox(add=infohbox) self.infoevbox.show_all() self.info_imagebox.drag_dest_set(gtk.DEST_DEFAULT_HIGHLIGHT | gtk.DEST_DEFAULT_DROP, [("text/uri-list", 0, 80), ("text/plain", 0, 80)], gtk.gdk.ACTION_DEFAULT) self.info_imagebox.connect('button_press_event', self.on_image_activate) self.info_imagebox.connect('drag_motion', self.on_image_motion_cb) self.info_imagebox.connect('drag_data_received', self.on_image_drop_cb) self.widgets_initialize(self.info_area)
def __init__(self, config, window, client, UIManager, update_menu_visibility, iterate_now, on_add_item, on_playlists_button_press, get_current_songs, connected, TAB_PLAYLISTS): self.config = config self.window = window self.client = client self.UIManager = UIManager self.update_menu_visibility = update_menu_visibility self.iterate_now = iterate_now # XXX Do we really need this? self.on_add_item = on_add_item self.on_playlists_button_press = on_playlists_button_press self.get_current_songs = get_current_songs self.connected = connected self.TAB_PLAYLISTS = TAB_PLAYLISTS self.mergepl_id = None self.actionGroupPlaylists = None # Playlists tab self.playlists = ui.treeview() self.playlists_selection = self.playlists.get_selection() self.playlistswindow = ui.scrollwindow(add=self.playlists) playlistshbox = gtk.HBox() playlistshbox.pack_start(ui.image(stock=gtk.STOCK_JUSTIFY_CENTER), False, False, 2) playlistshbox.pack_start(ui.label(text=self.TAB_PLAYLISTS), False, False, 2) self.playlistsevbox = ui.eventbox(add=playlistshbox) self.playlistsevbox.show_all() self.playlists.connect('button_press_event', self.on_playlists_button_press) self.playlists.connect('row_activated', self.playlists_activated) self.playlists.connect('key-press-event', self.playlists_key_press) # Initialize playlist data and widget self.playlistsdata = gtk.ListStore(str, str) self.playlists.set_model(self.playlistsdata) self.playlists.set_search_column(1) self.playlistsimg = gtk.CellRendererPixbuf() self.playlistscell = gtk.CellRendererText() self.playlistscell.set_property("ellipsize", pango.ELLIPSIZE_END) self.playlistscolumn = gtk.TreeViewColumn() self.playlistscolumn.pack_start(self.playlistsimg, False) self.playlistscolumn.pack_start(self.playlistscell, True) self.playlistscolumn.set_attributes(self.playlistsimg, stock_id=0) self.playlistscolumn.set_attributes(self.playlistscell, markup=1) self.playlists.append_column(self.playlistscolumn) self.playlists_selection.set_mode(gtk.SELECTION_MULTIPLE)
def _create_label_entry_button_hbox(self, label_name, track=False): """Creates a label, entry, apply all button, packing them into an hbox. This is usually one row in the tagedit dialog, for example the title. """ entry = ui.entry() button = ui.button() buttonvbox = self.tags_win_create_apply_all_button(button, entry, track) label = ui.label(text=label_name, x=1) hbox = gtk.HBox() hbox.pack_start(label, False, False, 2) hbox.pack_start(entry, True, True, 2) hbox.pack_start(buttonvbox, False, False, 2) return (label, entry, button, hbox)
def _art_location_changed(self, combobox): if combobox.get_active() == consts.ART_LOCATION_CUSTOM: # Prompt user for playlist name: dialog = ui.dialog(title=_("Custom Artwork"), parent=self.window, flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT), role='customArtwork', default=gtk.RESPONSE_ACCEPT) hbox = gtk.HBox() hbox.pack_start(ui.label(text=_('Artwork filename') + ':'), False, False, 5) entry = ui.entry() entry.set_activates_default(True) hbox.pack_start(entry, True, True, 5) dialog.vbox.pack_start(hbox) dialog.vbox.show_all() response = dialog.run() if response == gtk.RESPONSE_ACCEPT: self.config.art_location_custom_filename = entry.get_text().replace("/", "") else: # Revert to non-custom item in combobox: combobox.set_active(self.config.art_location) dialog.destroy() self.config.art_location = combobox.get_active()
def show_tooltip(self, id_, x, y): height = self.rect.height // 30 try: label = ui.label(layout=ui.fill_layout(), text=repr(id_)[1:-1], color=(1., 1., 1., 1.)) except UnicodeDecodeError: print "Bad string", repr(id_) return lw, lh = label.content_size(height) margin = .2 bg_width = lw * (1 + 2 * margin) bg_height = lh * (1 + 2 * margin) x, y = self.world_to_window(x, y) x = max(0, min(self.rect.width - bg_width, x)) y = max(0, min(self.rect.height - bg_height, y)) bg_rect = ui.rect(x, y, bg_width, bg_height) background = ui.plain_color(id='tooltip', rect=bg_rect, color=(.0, .0, .0, .5)) background.children.append(label) background.layout_children() self.children.append(background)
def __init__(self, config, window, on_streams_button_press, on_add_item, settings_save, iterate_now, TAB_STREAMS): self.config = config self.window = window self.on_streams_button_press = on_streams_button_press self.on_add_item = on_add_item self.settings_save = settings_save self.iterate_now = iterate_now # XXX Do we really need this? self.TAB_STREAMS = TAB_STREAMS # Streams tab self.streams = ui.treeview() self.streams_selection = self.streams.get_selection() self.streamswindow = ui.scrollwindow(add=self.streams) streamshbox = gtk.HBox() streamshbox.pack_start(ui.image(stock=gtk.STOCK_NETWORK), False, False, 2) streamshbox.pack_start(ui.label(text=self.TAB_STREAMS), False, False, 2) self.streamsevbox = ui.eventbox(add=streamshbox) self.streamsevbox.show_all() self.streams.connect('button_press_event', self.on_streams_button_press) self.streams.connect('row_activated', self.on_streams_activated) self.streams.connect('key-press-event', self.on_streams_key_press) # Initialize streams data and widget self.streamsdata = gtk.ListStore(str, str, str) self.streams.set_model(self.streamsdata) self.streams.set_search_column(1) self.streamsimg = gtk.CellRendererPixbuf() self.streamscell = gtk.CellRendererText() self.streamscell.set_property("ellipsize", pango.ELLIPSIZE_END) self.streamscolumn = gtk.TreeViewColumn() self.streamscolumn.pack_start(self.streamsimg, False) self.streamscolumn.pack_start(self.streamscell, True) self.streamscolumn.set_attributes(self.streamsimg, stock_id=0) self.streamscolumn.set_attributes(self.streamscell, markup=1) self.streams.append_column(self.streamscolumn) self.streams_selection.set_mode(gtk.SELECTION_MULTIPLE)
def __init__(self, config, find_path, is_lang_rtl, info_imagebox_get_size_request, schedule_gc_collect, target_image_filename, imagelist_append, remotefilelist_append, notebook_get_allocation, allow_art_search, status_is_play_or_pause, album_filename, get_current_song_text): self.config = config self.album_filename = album_filename # constants from main self.is_lang_rtl = is_lang_rtl # callbacks to main XXX refactor to clear this list self.info_imagebox_get_size_request = info_imagebox_get_size_request self.schedule_gc_collect = schedule_gc_collect self.target_image_filename = target_image_filename self.imagelist_append = imagelist_append self.remotefilelist_append = remotefilelist_append self.notebook_get_allocation = notebook_get_allocation self.allow_art_search = allow_art_search self.status_is_play_or_pause = status_is_play_or_pause self.get_current_song_text = get_current_song_text # local pixbufs, image file names self.sonatacd = find_path('sonatacd.png') self.sonatacd_large = find_path('sonatacd_large.png') self.casepb = gtk.gdk.pixbuf_new_from_file(find_path('sonata-case.png')) self.albumpb = None self.currentpb = None # local UI widgets provided to main by getter methods self.albumimage = ui.image() self.albumimage.set_from_file(self.sonatacd) self.trayalbumimage1 = ui.image(w=51, h=77, x=1) self.trayalbumeventbox = ui.eventbox(w=59, h=90, add=self.trayalbumimage1, state=gtk.STATE_SELECTED, visible=True) self.trayalbumimage2 = ui.image(w=26, h=77) self.fullscreenalbumimage = ui.image(w=consts.FULLSCREEN_COVER_SIZE, h=consts.FULLSCREEN_COVER_SIZE, x=1) self.fullscreenalbumlabel = ui.label(x=0.5) self.fullscreenalbumlabel2 = ui.label(x=0.5) self.fullscreen_cover_art_reset_image() self.fullscreen_cover_art_reset_text() self.info_image = ui.image(y=0) self.info_image.set_from_file(self.sonatacd_large) # local version of Main.songinfo mirrored by update_songinfo self.songinfo = None # local state self.lastalbumart = None self.single_img_in_dir = None self.misc_img_in_dir = None self.stop_art_update = False self.downloading_image = False self.lib_art_cond = None # local artwork, cache for library self.lib_model = None self.lib_art_rows_local = [] self.lib_art_rows_remote = [] self.lib_art_pb_size = 0 self.cache = {} self.artwork_load_cache()
def about_shortcuts(self, _button): # define the shortcuts and their descriptions # these are all gettextable mainshortcuts = \ [[ "F1", _("About Sonata") ], [ "F5", _("Preferences") ], [ "F11", _("Fullscreen Artwork Mode") ], [ "Alt-[1-5]", _("Switch to [1st-5th] tab") ], [ "Alt-C", _("Connect to MPD") ], [ "Alt-D", _("Disconnect from MPD") ], [ "Alt-R", _("Randomize current playlist") ], [ "Alt-Down", _("Expand player") ], [ "Alt-Left", _("Switch to previous tab") ], [ "Alt-Right", _("Switch to next tab") ], [ "Alt-Up", _("Collapse player") ], [ "Ctrl-H", _("Search library") ], [ "Ctrl-Q", _("Quit") ], [ "Ctrl-Shift-U", _("Update entire library") ], [ "Menu", _("Display popup menu") ], [ "Escape", _("Minimize to system tray (if enabled)") ]] playbackshortcuts = \ [[ "Ctrl-Left", _("Previous track") ], [ "Ctrl-Right", _("Next track") ], [ "Ctrl-P", _("Play/Pause") ], [ "Ctrl-S", _("Stop") ], [ "Ctrl-Minus", _("Lower the volume") ], [ "Ctrl-Plus", _("Raise the volume") ]] currentshortcuts = \ [[ "Enter/Space", _("Play selected song") ], [ "Delete", _("Remove selected song(s)") ], [ "Ctrl-I", _("Center currently playing song") ], [ "Ctrl-T", _("Edit selected song's tags") ], [ "Ctrl-Shift-S", _("Save to new playlist") ], [ "Ctrl-Delete", _("Clear list") ], [ "Alt-R", _("Randomize list") ]] libraryshortcuts = \ [[ "Enter/Space", _("Add selected song(s) or enter directory") ], [ "Backspace", _("Go to parent directory") ], [ "Ctrl-D", _("Add selected item(s)") ], [ "Ctrl-R", _("Replace with selected item(s)") ], [ "Ctrl-T", _("Edit selected song's tags") ], [ "Ctrl-Shift-D", _("Add selected item(s) and play") ], [ "Ctrl-Shift-R", _("Replace with selected item(s) and play") ], [ "Ctrl-U", _("Update selected item(s)/path(s)") ]] playlistshortcuts = \ [[ "Enter/Space", _("Add selected playlist(s)") ], [ "Delete", _("Remove selected playlist(s)") ], [ "Ctrl-D", _("Add selected playlist(s)") ], [ "Ctrl-R", _("Replace with selected playlist(s)") ], [ "Ctrl-Shift-D", _("Add selected playlist(s) and play") ], [ "Ctrl-Shift-R", _("Replace with selected playlist(s) and play") ]] streamshortcuts = \ [[ "Enter/Space", _("Add selected stream(s)") ], [ "Delete", _("Remove selected stream(s)") ], [ "Ctrl-D", _("Add selected stream(s)") ], [ "Ctrl-R", _("Replace with selected stream(s)") ], [ "Ctrl-Shift-D", _("Add selected stream(s) and play") ], [ "Ctrl-Shift-R", _("Replace with selected stream(s) and play") ]] infoshortcuts = \ [[ "Ctrl-T", _("Edit playing song's tags") ]] # define the main array- this adds headings to each section of # shortcuts that will be displayed shortcuts = [[_("Main Shortcuts"), mainshortcuts], [_("Playback Shortcuts"), playbackshortcuts], [_("Current Shortcuts"), currentshortcuts], [_("Library Shortcuts"), libraryshortcuts], [_("Playlist Shortcuts"), playlistshortcuts], [_("Stream Shortcuts"), streamshortcuts], [_("Info Shortcuts"), infoshortcuts]] dialog = ui.dialog(title=_("Shortcuts"), parent=self.about_dialog, flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, buttons=(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE), role='shortcuts', default=gtk.RESPONSE_CLOSE, h=320) # each pair is a [ heading, shortcutlist ] vbox = gtk.VBox() for pair in shortcuts: titlelabel = ui.label(markup="<b>" + pair[0] + "</b>") vbox.pack_start(titlelabel, False, False, 2) # print the items of [ shortcut, desc ] for item in pair[1]: tmphbox = gtk.HBox() tmplabel = ui.label(markup="<b>" + item[0] + ":</b>", y=0) tmpdesc = ui.label(text=item[1], wrap=True, y=0) tmphbox.pack_start(tmplabel, False, False, 2) tmphbox.pack_start(tmpdesc, True, True, 2) vbox.pack_start(tmphbox, False, False, 2) vbox.pack_start(ui.label(text=" "), False, False, 2) scrollbox = ui.scrollwindow(policy_x=gtk.POLICY_NEVER, addvp=vbox) dialog.vbox.pack_start(scrollbox, True, True, 2) dialog.show_all() dialog.run() dialog.destroy()
def __init__( self, config, client, TAB_CURRENT, on_current_button_press, parse_formatting_colnames, parse_formatting, connected, sonata_loaded, songinfo, update_statusbar, iterate_now, libsearchfilter_get_style, ): self.config = config self.client = client self.TAB_CURRENT = TAB_CURRENT self.on_current_button_press = on_current_button_press self.parse_formatting_colnames = parse_formatting_colnames self.parse_formatting = parse_formatting self.connected = connected self.sonata_loaded = sonata_loaded self.songinfo = songinfo self.update_statusbar = update_statusbar self.iterate_now = iterate_now self.libsearchfilter_get_style = libsearchfilter_get_style self.currentdata = None self.filterbox_visible = False self.current_update_skip = False self.filter_row_mapping = [] # Mapping between filter rows and self.currentdata rows self.columnformat = None self.columns = None self.current_songs = None self.filterbox_cmd_buf = None self.filterbox_cond = None self.filterbox_source = None self.column_sorted = (None, gtk.SORT_DESCENDING) # TreeViewColumn, order self.total_time = 0 self.edit_style_orig = None self.resizing_columns = None self.prev_boldrow = -1 self.prevtodo = None self.plpos = None self.playlist_pos_before_filter = None self.sel_rows = None # Current tab self.current = ui.treeview(reorder=True, search=False, headers=True) self.current_selection = self.current.get_selection() self.expanderwindow = ui.scrollwindow(shadow=gtk.SHADOW_IN, add=self.current) self.filterpattern = ui.entry() self.filterbox = gtk.HBox() self.filterbox.pack_start(ui.label(text=_("Filter") + ":"), False, False, 5) self.filterbox.pack_start(self.filterpattern, True, True, 5) filterclosebutton = ui.button(img=ui.image(stock=gtk.STOCK_CLOSE), relief=gtk.RELIEF_NONE) self.filterbox.pack_start(filterclosebutton, False, False, 0) self.filterbox.set_no_show_all(True) self.vbox_current = gtk.VBox() self.vbox_current.pack_start(self.expanderwindow, True, True) self.vbox_current.pack_start(self.filterbox, False, False, 5) playlisthbox = gtk.HBox() playlisthbox.pack_start(ui.image(stock=gtk.STOCK_CDROM), False, False, 2) playlisthbox.pack_start(ui.label(text=self.TAB_CURRENT), False, False, 2) self.playlistevbox = ui.eventbox(add=playlisthbox) self.playlistevbox.show_all() self.current.connect("drag_data_received", self.on_dnd) self.current.connect("row_activated", self.on_current_click) self.current.connect("button_press_event", self.on_current_button_press) self.current.connect("drag-begin", self.on_current_drag_begin) self.current.connect_after("drag-begin", self.dnd_after_current_drag_begin) self.current.connect("button_release_event", self.on_current_button_release) self.filter_changed_handler = self.filterpattern.connect("changed", self.searchfilter_feed_loop) self.filterpattern.connect("activate", self.searchfilter_on_enter) self.filterpattern.connect("key-press-event", self.searchfilter_key_pressed) filterclosebutton.connect("clicked", self.searchfilter_toggle) # Set up current view self.initialize_columns() self.current_selection.set_mode(gtk.SELECTION_MULTIPLE) target_reorder = ("MY_TREE_MODEL_ROW", gtk.TARGET_SAME_WIDGET, 0) target_file_managers = ("text/uri-list", 0, 0) self.current.enable_model_drag_source( gtk.gdk.BUTTON1_MASK, [target_reorder, target_file_managers], gtk.gdk.ACTION_COPY | gtk.gdk.ACTION_DEFAULT ) self.current.enable_model_drag_dest( [target_reorder, target_file_managers], gtk.gdk.ACTION_MOVE | gtk.gdk.ACTION_DEFAULT ) self.current.connect("drag-data-get", self.dnd_get_data_for_file_managers)
def update_breadcrumbs(self): # remove previous buttons for b in self.breadcrumbs: self.breadcrumbs.remove(b) # add the views button first b = ui.button(text=_(" v "), can_focus=False, relief=gtk.RELIEF_NONE) b.connect('clicked', self.library_view_popup) self.breadcrumbs.pack_start(b, False, False) b.show() # add the ellipsis explicitly XXX make this unnecessary b = ui.label("...") self.breadcrumbs.pack_start(b, False, False) b.show() # find info for current view view, _name, icon, label = [v for v in self.VIEWS if v[0] == self.config.lib_view][0] # the first crumb is the root of the current view crumbs = [(label, icon, None, self.library_set_data(path='/'))] # rest of the crumbs are specific to the view if view == consts.VIEW_FILESYSTEM: path = self.library_get_data(self.config.wd, 'path') if path and path != '/': parts = path.split('/') else: parts = [] # no crumbs for / # append a crumb for each part for i, part in enumerate(parts): partpath = '/'.join(parts[:i+1]) target = self.library_set_data(path=partpath) crumbs.append((part, gtk.STOCK_OPEN, None, target)) else: if view == consts.VIEW_ALBUM: # We don't want to show an artist button in album view keys = 'genre', 'album' nkeys = 2 else: keys = 'genre', 'artist', 'album' nkeys = 3 parts = self.library_get_data(self.config.wd, *keys) # append a crumb for each part for i, key, part in zip(range(nkeys), keys, parts): if part is None: continue partdata = dict(zip(keys, parts)[:i+1]) target = self.library_set_data(**partdata) pb, icon = None, None if key == 'album': # Album artwork, with self.alumbpb as a backup: artist, album, path = self.library_get_data(self.config.wd, 'artist', 'album', 'path') cache_data = self.library_set_data(artist=artist, album=album, path=path) pb = self.artwork.get_library_artwork_cached_pb(cache_data, None) if pb is None: icon = 'album' elif key == 'artist': icon = 'artist' else: icon = gtk.STOCK_ORIENTATION_PORTRAIT crumbs.append((part, icon, pb, target)) # add a button for each crumb for crumb in crumbs: text, icon, pb, target = crumb text = misc.escape_html(text) if crumb is crumbs[-1]: text = "<b>%s</b>" % text label = ui.label(markup=text) if icon: image = ui.image(stock=icon) elif pb: pb = pb.scale_simple(16, 16, gtk.gdk.INTERP_HYPER) image = ui.image(pb=pb) b = breadcrumbs.CrumbButton(image, label) if crumb is crumbs[-1]: # FIXME makes the button request minimal space: # label.props.ellipsize = pango.ELLIPSIZE_END b.props.active = True # FIXME why doesn't the tooltip show? b.set_tooltip_text(label.get_label()) b.connect('toggled', self.library_browse, target) self.breadcrumbs.pack_start(b, False, False) b.show_all()
def on_prefs_real(self, parent_window, popuptimes, scrobbler, trayicon_available, trayicon_in_use, reconnect, renotify, reinfofile, prefs_notif_toggled, prefs_stylized_toggled, prefs_art_toggled, prefs_playback_toggled, prefs_progress_toggled, prefs_statusbar_toggled, prefs_lyrics_toggled, prefs_trayicon_toggled, prefs_crossfade_toggled, prefs_crossfade_changed, prefs_window_response, prefs_last_tab): """Display the preferences dialog""" self.window = parent_window self.scrobbler = scrobbler self.reconnect = reconnect self.renotify = renotify self.reinfofile = reinfofile self.last_tab = prefs_last_tab self.prefswindow = ui.dialog(title=_("Preferences"), parent=self.window, flags=gtk.DIALOG_DESTROY_WITH_PARENT, role='preferences', resizable=False, separator=False) hbox = gtk.HBox() prefsnotebook = gtk.Notebook() # MPD tab mpdlabel = ui.label(markup='<b>' + _('MPD Connection') + '</b>', y=1) mpd_frame = gtk.Frame() mpd_frame.set_label_widget(mpdlabel) mpd_frame.set_shadow_type(gtk.SHADOW_NONE) controlbox = gtk.HBox() profiles = ui.combo() add_profile = ui.button(img=ui.image(stock=gtk.STOCK_ADD)) remove_profile = ui.button(img=ui.image(stock=gtk.STOCK_REMOVE)) self.prefs_populate_profile_combo(profiles, self.config.profile_num, remove_profile) controlbox.pack_start(profiles, False, False, 2) controlbox.pack_start(remove_profile, False, False, 2) controlbox.pack_start(add_profile, False, False, 2) namelabel = ui.label(textmn=_("_Name") + ":") nameentry = ui.entry() namelabel.set_mnemonic_widget(nameentry) hostlabel = ui.label(textmn=_("_Host") + ":") hostentry = ui.entry() hostlabel.set_mnemonic_widget(hostentry) portlabel = ui.label(textmn=_("_Port") + ":") portentry = gtk.SpinButton(gtk.Adjustment(0 ,0 ,65535, 1),1) portentry.set_numeric(True) portlabel.set_mnemonic_widget(portentry) dirlabel = ui.label(textmn=_("_Music dir") + ":") direntry = gtk.FileChooserButton(_('Select a Music Directory')) direntry.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER) direntry.connect('selection-changed', self.prefs_direntry_changed, profiles) dirlabel.set_mnemonic_widget(direntry) passwordlabel = ui.label(textmn=_("Pa_ssword") + ":") passwordentry = ui.entry(password=True) passwordlabel.set_mnemonic_widget(passwordentry) passwordentry.set_tooltip_text(_("Leave blank if no password is required.")) autoconnect = gtk.CheckButton(_("_Autoconnect on start")) autoconnect.set_active(self.config.autoconnect) autoconnect.connect('toggled', self.prefs_config_widget_active, 'autoconnect') # Fill in entries with current profile: self.prefs_profile_chosen(profiles, nameentry, hostentry, portentry, passwordentry, direntry) # Update display if $MPD_HOST or $MPD_PORT is set: host, port, password = misc.mpd_env_vars() if host or port: using_mpd_env_vars = True if not host: host = "" if not port: port = 0 if not password: password = "" hostentry.set_text(str(host)) portentry.set_value(port) passwordentry.set_text(str(password)) nameentry.set_text(_("Using MPD_HOST/PORT")) for widget in [hostentry, portentry, passwordentry, nameentry, profiles, add_profile, remove_profile]: widget.set_sensitive(False) else: using_mpd_env_vars = False nameentry.connect('changed', self.prefs_nameentry_changed, profiles, remove_profile) hostentry.connect('changed', self.prefs_hostentry_changed, profiles) portentry.connect('value-changed', self.prefs_portentry_changed, profiles) passwordentry.connect('changed', self.prefs_passwordentry_changed, profiles) profiles.connect('changed', self.prefs_profile_chosen, nameentry, hostentry, portentry, passwordentry, direntry) add_profile.connect('clicked', self.prefs_add_profile, nameentry, profiles, remove_profile) remove_profile.connect('clicked', self.prefs_remove_profile, profiles, remove_profile) rows = [(namelabel, nameentry), (hostlabel, hostentry), (portlabel, portentry), (passwordlabel, passwordentry), (dirlabel, direntry)] connection_table = gtk.Table(len(rows), 2) connection_table.set_col_spacings(12) for i, (label, entry) in enumerate(rows): connection_table.attach(label, 0, 1, i, i+1, gtk.FILL, gtk.FILL) connection_table.attach(entry, 1, 2, i, i+1, gtk.FILL|gtk.EXPAND, gtk.FILL) connection_alignment = gtk.Alignment(0.5, 0.5, 1.0, 1.0) connection_alignment.set_padding(12, 12, 12, 12) connection_alignment.add(connection_table) connection_frame = gtk.Frame() connection_frame.set_label_widget(controlbox) connection_frame.add(connection_alignment) mpd_table = gtk.Table(2, 1) mpd_table.set_row_spacings(12) mpd_table.attach(connection_frame, 0, 1, 0, 1, gtk.FILL|gtk.EXPAND, gtk.FILL) mpd_table.attach(autoconnect, 0, 1, 1, 2, gtk.FILL|gtk.EXPAND, gtk.FILL) mpd_alignment = gtk.Alignment(0.5, 0.5, 1.0, 1.0) mpd_alignment.set_padding(12, 0, 12, 0) mpd_alignment.add(mpd_table) mpd_frame.add(mpd_alignment) mpd_tab = gtk.Alignment(0.5, 0.5, 1.0, 1.0) mpd_tab.set_padding(12, 12, 12, 12) mpd_tab.add(mpd_frame) # Extras tab if not self.scrobbler.imported(): self.config.as_enabled = False as_label = ui.label(markup='<b>' + _('Extras') + '</b>') extras_frame = gtk.Frame() extras_frame.set_label_widget(as_label) extras_frame.set_shadow_type(gtk.SHADOW_NONE) as_checkbox = gtk.CheckButton(_("_Audioscrobbling (Last.fm)")) as_checkbox.set_active(self.config.as_enabled) as_user_label = ui.label(textmn=_("_Username:"******"_Password:"******"Popup _notification on song changes")) display_notification.set_active(self.config.show_notification) time_names = ["%s %s" % (i , gettext.ngettext('second', 'seconds', int(i))) for i in popuptimes if i != _('Entire song')] time_names.append(_('Entire song')) notification_options = ui.combo(items=time_names, active=self.config.popup_option, changed_cb=self.prefs_notiftime_changed) notification_locs = ui.combo(items=self.popuplocations, active=self.config.traytips_notifications_location, changed_cb=self.prefs_notiflocation_changed) notifhbox = gtk.HBox(spacing=6) notifhbox.pack_end(notification_locs, False, False) notifhbox.pack_end(notification_options, False, False) display_notification.connect('toggled', prefs_notif_toggled, notifhbox) if not self.config.show_notification: notifhbox.set_sensitive(False) crossfadespin = gtk.SpinButton() crossfadespin.set_range(1, 30) crossfadespin.set_value(self.config.xfade) crossfadespin.set_numeric(True) crossfadespin.set_increments(1, 5) crossfadespin.connect('value-changed', prefs_crossfade_changed) crossfadelabel2 = ui.label(text=_("Fade length") + ":") crossfadelabel2 = ui.label(textmn=_("_Fade length") + ":") crossfadelabel2.set_mnemonic_widget(crossfadespin) crossfadelabel3 = ui.label(text=_("sec")) crossfadebox = gtk.HBox(spacing=12) crossfadebox.pack_end(crossfadelabel3, False, False) crossfadebox.pack_end(crossfadespin, False, False) crossfadebox.pack_end(crossfadelabel2, False, False) crossfadecheck = gtk.CheckButton(_("C_rossfade")) crossfadecheck.connect('toggled', self.prefs_crossfadecheck_toggled, crossfadespin, crossfadelabel2, crossfadelabel3) crossfadecheck.connect('toggled', prefs_crossfade_toggled, crossfadespin) crossfadecheck.set_active(self.config.xfade_enabled) crossfadecheck.toggled() # Force the toggled callback extras_widgets = (as_checkbox, as_entries, display_notification, notifhbox, crossfadecheck, crossfadebox) extras_table = gtk.Table(len(extras_widgets), 1) extras_table.set_col_spacings(12) extras_table.set_row_spacings(6) for i, widget in enumerate(extras_widgets): extras_table.attach(widget, 0, 1, i, i+1, gtk.FILL|gtk.EXPAND, gtk.FILL) extras_alignment = gtk.Alignment(0.5, 0.5, 1.0, 1.0) extras_alignment.set_padding(12, 0, 12, 0) extras_alignment.add(extras_table) extras_frame.add(extras_alignment) extras_tab = gtk.Alignment(0.5, 0.5, 1.0, 1.0) extras_tab.set_padding(12, 12, 12, 12) extras_tab.add(extras_frame) as_checkbox.connect('toggled', self.prefs_as_enabled_toggled, as_user_entry, as_pass_entry, as_user_label, as_pass_label) if not self.config.as_enabled or not self.scrobbler.imported(): for widget in (as_user_entry, as_pass_entry, as_user_label, as_pass_label): widget.set_sensitive(False) # Display tab displaylabel = ui.label(markup='<b>' + _('Display') + '</b>') display_frame = gtk.Frame() display_frame.set_label_widget(displaylabel) display_frame.set_shadow_type(gtk.SHADOW_NONE) display_art = gtk.CheckButton(_("_Album art")) display_art.set_active(self.config.show_covers) display_stylized_combo = ui.combo(items=[_("Standard"), _("Stylized")], active=self.config.covers_type, changed_cb=prefs_stylized_toggled) display_stylized_hbox = gtk.HBox(spacing=12) display_stylized_hbox.pack_end(display_stylized_combo, False, False) display_stylized_hbox.pack_end(ui.label(text=_("Artwork style:")), False, False) display_stylized_hbox.set_sensitive(self.config.show_covers) display_art_combo = ui.combo(items=[_("Local only"), _("Local and remote")], active=self.config.covers_pref) display_art_combo.connect('changed', self.prefs_config_widget_active, 'covers_pref') orderart_label = ui.label(text=_("Search locations:")) display_art_hbox = gtk.HBox(spacing=12) display_art_hbox.pack_end(display_art_combo, False, False) display_art_hbox.pack_end(orderart_label, False, False) display_art_hbox.set_sensitive(self.config.show_covers) art_paths = ["~/.covers/"] art_paths += ("%s/%s" % (_("SONG_DIR"), item) for item in ("cover.jpg", "album.jpg", "folder.jpg", _("custom"))) display_art_location = ui.combo(items=art_paths, active=self.config.art_location, changed_cb=self.prefs_art_location_changed) display_art_location_hbox = gtk.HBox(spacing=12) display_art_location_hbox.pack_end(display_art_location, False, False) display_art_location_hbox.pack_end(ui.label(text=_("Save art to:")), False, False) display_art_location_hbox.set_sensitive(self.config.show_covers) display_art.connect('toggled', prefs_art_toggled, display_art_hbox, display_art_location_hbox, display_stylized_hbox) display_playback = gtk.CheckButton(_("_Playback/volume buttons")) display_playback.set_active(self.config.show_playback) display_playback.connect('toggled', prefs_playback_toggled) display_progress = gtk.CheckButton(_("Pr_ogressbar")) display_progress.set_active(self.config.show_progress) display_progress.connect('toggled', prefs_progress_toggled) display_statusbar = gtk.CheckButton(_("_Statusbar")) display_statusbar.set_active(self.config.show_statusbar) display_statusbar.connect('toggled', prefs_statusbar_toggled) display_lyrics = gtk.CheckButton(_("Song Ly_rics")) display_lyrics.set_active(self.config.show_lyrics) savelyrics_label = ui.label(text=_("Save lyrics to:"), x=1) display_lyrics_location = ui.combo(items=["~/.lyrics/", _("SONG_DIR") + "/"], active=self.config.lyrics_location, changed_cb=self.prefs_lyrics_location_changed) display_lyrics_location_hbox = gtk.HBox(spacing=12) display_lyrics_location_hbox.pack_end(display_lyrics_location, False, False) display_lyrics_location_hbox.pack_end(savelyrics_label, False, False) display_lyrics_location_hbox.set_sensitive(self.config.show_lyrics) display_lyrics.connect('toggled', prefs_lyrics_toggled, display_lyrics_location_hbox) display_trayicon = gtk.CheckButton(_("System _tray icon")) display_trayicon.set_active(self.config.show_trayicon) display_trayicon.set_sensitive(trayicon_available) display_widgets = (display_playback, display_progress, display_statusbar, display_trayicon, display_lyrics, display_lyrics_location_hbox, display_art, display_stylized_hbox, display_art_hbox, display_art_location_hbox) display_table = gtk.Table(len(display_widgets), 1, False) for i, widget in enumerate(display_widgets): display_table.attach(widget, 0, 1, i, i+1, gtk.FILL|gtk.EXPAND, gtk.FILL) display_alignment = gtk.Alignment(0.5, 0.5, 1.0, 1.0) display_alignment.set_padding(12, 0, 12, 0) display_alignment.add(display_table) display_frame.add(display_alignment) display_tab = gtk.Alignment(0.5, 0.5, 1.0, 1.0) display_tab.set_padding(12, 12, 12, 12) display_tab.add(display_frame) # Behavior tab windowlabel = ui.label(markup='<b>'+_('Window Behavior')+'</b>') window_frame = gtk.Frame() window_frame.set_label_widget(windowlabel) window_frame.set_shadow_type(gtk.SHADOW_NONE) win_sticky = gtk.CheckButton(_("_Show window on all workspaces")) win_sticky.set_active(self.config.sticky) win_sticky.connect('toggled', self.prefs_config_widget_active, 'sticky') win_ontop = gtk.CheckButton(_("_Keep window above other windows")) win_ontop.set_active(self.config.ontop) win_ontop.connect('toggled', self.prefs_config_widget_active, 'ontop') win_decor = gtk.CheckButton(_("_Hide window titlebar")) win_decor.set_active(not self.config.decorated) win_decor.connect('toggled', lambda w: setattr(self.config, 'decorated', not w.get_active())) minimize = gtk.CheckButton(_("_Minimize to system tray on close/escape")) minimize.set_active(self.config.minimize_to_systray) minimize.set_tooltip_text(_("If enabled, closing Sonata will minimize it to the system tray. Note that it's currently impossible to detect if there actually is a system tray, so only check this if you have one.")) minimize.connect('toggled', self.prefs_config_widget_active, 'minimize_to_systray') display_trayicon.connect('toggled', prefs_trayicon_toggled, minimize) minimize.set_sensitive(trayicon_in_use) widgets = (win_sticky, win_ontop, win_decor, minimize) window_table = gtk.Table(len(widgets), 1) for i, widget in enumerate(widgets): window_table.attach(widget, 0, 1, i, i+1, gtk.FILL|gtk.EXPAND, gtk.FILL) window_alignment = gtk.Alignment() window_alignment.set_padding(12, 0, 12, 0) window_alignment.add(window_table) window_frame.add(window_alignment) misclabel = ui.label(markup='<b>' + _('Miscellaneous') + '</b>') misc_frame = gtk.Frame() misc_frame.set_label_widget(misclabel) misc_frame.set_shadow_type(gtk.SHADOW_NONE) update_start = gtk.CheckButton(_("_Update MPD library on start")) update_start.set_active(self.config.update_on_start) update_start.set_tooltip_text(_("If enabled, Sonata will automatically update your MPD library when it starts up.")) update_start.connect('toggled', self.prefs_config_widget_active, 'update_on_start') exit_stop = gtk.CheckButton(_("S_top playback on exit")) exit_stop.set_active(self.config.stop_on_exit) exit_stop.set_tooltip_text(_("MPD allows playback even when the client is not open. If enabled, Sonata will behave like a more conventional music player and, instead, stop playback upon exit.")) exit_stop.connect('toggled', self.prefs_config_widget_active, 'stop_on_exit') infofile_usage = gtk.CheckButton(_("_Write status file:")) infofile_usage.set_active(self.config.use_infofile) infofile_usage.set_tooltip_text(_("If enabled, Sonata will create a xmms-infopipe like file containing information about the current song. Many applications support the xmms-info file (Instant Messengers, IRC Clients...)")) infopath_options = ui.entry(text=self.config.infofile_path) infopath_options.set_tooltip_text(_("If enabled, Sonata will create a xmms-infopipe like file containing information about the current song. Many applications support the xmms-info file (Instant Messengers, IRC Clients...)")) if not self.config.use_infofile: infopath_options.set_sensitive(False) infofile_usage.connect('toggled', self.prefs_infofile_toggled, infopath_options) infofilebox = gtk.HBox(spacing=6) infofilebox.pack_start(infofile_usage, False, False) infofilebox.pack_start(infopath_options, True, True) widgets = (update_start, exit_stop, infofilebox) misc_table = gtk.Table(len(widgets), 1) for i, widget in enumerate(widgets): misc_table.attach(widget, 0, 1, i, i+1, gtk.FILL|gtk.EXPAND, gtk.FILL) misc_alignment = gtk.Alignment() misc_alignment.set_padding(12, 0, 12, 0) misc_alignment.add(misc_table) misc_frame.add(misc_alignment) behavior_table = gtk.Table(2, 1) behavior_table.set_row_spacings(12) behavior_table.attach(window_frame, 0, 1, 0, 1, gtk.FILL|gtk.EXPAND, gtk.FILL) behavior_table.attach(misc_frame, 0, 1, 1, 2, gtk.FILL|gtk.EXPAND, gtk.FILL) behavior_tab = gtk.Alignment() behavior_tab.set_padding(12, 12, 12, 12) behavior_tab.add(behavior_table) # Format tab formatlabel = ui.label(markup='<b>'+_('Song Formatting')+'</b>') format_frame = gtk.Frame() format_frame.set_label_widget(formatlabel) format_frame.set_shadow_type(gtk.SHADOW_NONE) rows = [(_("C_urrent playlist:"), self.config.currentformat), (_("_Library:"), self.config.libraryformat), (_("_Window title:"), self.config.titleformat), (_("Current _song line 1:"), self.config.currsongformat1), (_("Current s_ong line 2:"), self.config.currsongformat2)] format_labels = [] format_entries = [] for label_text, entry_text in rows: label = ui.label(textmn=label_text) entry = ui.entry(text=entry_text) label.set_mnemonic_widget(entry) format_labels.append(label) format_entries.append(entry) currentoptions = format_entries[0] libraryoptions = format_entries[1] titleoptions = format_entries[2] currsongoptions1 = format_entries[3] currsongoptions2 = format_entries[4] availableheading = ui.label(markup='<small>' + _('Available options') + ':</small>', y=0) availablevbox = gtk.VBox() availableformatbox = gtk.HBox() # XXX get these directly from the formatting function: formatcodes = [('A', _('Artist name')), ('B', _('Album name')), ('T', _('Track name')), ('N', _('Track number')), ('D', _('Disc number')), ('Y', _('Year')), ('G', _('Genre')), ('P', _('File path')), ('F', _('File name')), ('S', _('Stream name')), ('L', _('Song length')), ('E', _('Elapsed time (title only)')), ] for codes in [formatcodes[:(len(formatcodes)+1)/2], formatcodes[(len(formatcodes)+1)/2:]]: rows = '\n'.join('<tt>%' + code + '</tt> - ' + help for code, help in codes) markup = '<small>' + rows + '</small>' formattinghelp = ui.label(markup=markup, y=0) availableformatbox.pack_start(formattinghelp) availablevbox.pack_start(availableformatbox, False, False, 0) additionalinfo = ui.label(markup='<small><tt>{ }</tt> - ' + _('Info displayed only if all enclosed tags are defined') + '\n' + '<tt>|</tt> - ' + _('Creates columns in the current playlist') + '</small>', y=0) availablevbox.pack_start(additionalinfo, False, False, 4) num_rows = len(rows) + 2 format_table = gtk.Table(num_rows, 2) format_table.set_col_spacings(12) label_entries = enumerate(zip(format_labels, format_entries)) for i, (label, entry) in label_entries: format_table.attach(label, 0, 1, i, i+1, gtk.FILL) format_table.attach(entry, 1, 2, i, i+1) format_table.attach(availableheading, 0, 2, num_rows-2, num_rows-1, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 0, 6) format_table.attach(availablevbox, 0, 2, num_rows-1, num_rows) format_alignment = gtk.Alignment(0.5, 0.5, 1.0, 1.0) format_alignment.set_padding(12, 0, 12, 0) format_alignment.add(format_table) format_frame.add(format_alignment) format_tab = gtk.Alignment(0.5, 0.5, 1.0, 1.0) format_tab.set_padding(12, 12, 12, 12) format_tab.add(format_frame) # Plugins tab plugin_actions = ( ('plugin_about', gtk.STOCK_ABOUT, _('_About'), None, None, self.plugin_about), ('plugin_configure', gtk.STOCK_PREFERENCES, _('_Configure...'), None, None, self.plugin_configure), ) uiDescription = """ <ui> <popup name="pluginmenu"> <menuitem action="plugin_configure"/> <menuitem action="plugin_about"/> </popup> </ui> """ self.plugin_UIManager = gtk.UIManager() actionGroup = gtk.ActionGroup('PluginActions') actionGroup.add_actions(plugin_actions) self.plugin_UIManager.insert_action_group(actionGroup, 0) self.plugin_UIManager.add_ui_from_string(uiDescription) self.pluginview = ui.treeview() self.pluginview.set_headers_visible(True) self.pluginselection = self.pluginview.get_selection() self.pluginselection.set_mode(gtk.SELECTION_SINGLE) self.pluginview.set_rules_hint(True) self.pluginview.set_property('can-focus', False) pluginwindow = ui.scrollwindow(add=self.pluginview) plugindata = gtk.ListStore(bool, gtk.gdk.Pixbuf, str) self.pluginview.set_model(plugindata) self.pluginview.connect('button-press-event', self.plugin_click) plugincheckcell = gtk.CellRendererToggle() plugincheckcell.set_property('activatable', True) plugincheckcell.connect('toggled', self.plugin_toggled, (plugindata, 0)) pluginpixbufcell = gtk.CellRendererPixbuf() plugintextcell = gtk.CellRendererText() plugincol0 = gtk.TreeViewColumn() self.pluginview.append_column(plugincol0) plugincol0.pack_start(plugincheckcell, True) plugincol0.set_attributes(plugincheckcell, active=0) plugincol0.set_title(" " + _("Loaded") + " ") plugincol1 = gtk.TreeViewColumn() self.pluginview.append_column(plugincol1) plugincol1.pack_start(pluginpixbufcell, False) plugincol1.pack_start(plugintextcell, True) plugincol1.set_attributes(pluginpixbufcell, pixbuf=1) plugincol1.set_attributes(plugintextcell, markup=2) plugincol1.set_title(_("Description")) plugindata.clear() for plugin in pluginsystem.get_info(): pb = self.plugin_get_icon_pixbuf(plugin) plugin_text = "<b> " + plugin.longname + "</b> " + plugin.version_string plugin_text += "\n " + plugin.description enabled = True plugindata.append((enabled, pb, plugin_text)) # Set up table tables = [(_("MPD"), mpd_tab), (_("Display"), display_tab), (_("Behavior"), behavior_tab), (_("Format"), format_tab), (_("Extras"), extras_tab)] # XXX Plugins temporarily disabled #(_("Plugins"), pluginwindow)] for table_name, table in tables: tmplabel = ui.label(text=table_name) prefsnotebook.append_page(table, tmplabel) hbox.pack_start(prefsnotebook, False, False, 10) self.prefswindow.vbox.pack_start(hbox, False, False, 10) close_button = self.prefswindow.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE) self.prefswindow.show_all() prefsnotebook.set_current_page(self.last_tab) close_button.grab_focus() self.prefswindow.connect('response', prefs_window_response, prefsnotebook, direntry, currentoptions, libraryoptions, titleoptions, currsongoptions1, currsongoptions2, infopath_options, using_mpd_env_vars, self.prev_host, self.prev_port, self.prev_password) # Save previous connection properties to determine if we should try to # connect to MPD after prefs are closed: self.prev_host = self.config.host[self.config.profile_num] self.prev_port = self.config.port[self.config.profile_num] self.prev_password = self.config.password[self.config.profile_num]
def format_tab(self, cbs): """Construct and layout the format tab""" formatlabel = ui.label(markup='<b>'+_('Song Formatting')+'</b>') frame = gtk.Frame() frame.set_label_widget(formatlabel) frame.set_shadow_type(gtk.SHADOW_NONE) rows = [(_("C_urrent playlist:"), self.config.currentformat), (_("_Library:"), self.config.libraryformat), (_("_Window title:"), self.config.titleformat), (_("Current _song line 1:"), self.config.currsongformat1), (_("Current s_ong line 2:"), self.config.currsongformat2)] labels = [] entries = [] for label_text, entry_text in rows: label = ui.label(textmn=label_text) entry = ui.entry(text=entry_text) label.set_mnemonic_widget(entry) labels.append(label) entries.append(entry) entry_cbs = (cbs.currentoptions_changed, cbs.libraryoptions_changed, cbs.titleoptions_changed, cbs.currsongoptions1_changed, cbs.currsongoptions2_changed) for entry, cb, next in zip(entries, entry_cbs, entries[1:] + entries[:1]): entry.connect('focus_out_event', cb) entry.connect('activate', lambda _, n: n.grab_focus(), next) availableheading = ui.label(markup='<small>' + _('Available options') + ':</small>') availablevbox = gtk.VBox() availableformatbox = gtk.HBox() # XXX get these directly from the formatting function: formatcodes = [('A', _('Artist name')), ('B', _('Album name')), ('T', _('Track name')), ('N', _('Track number')), ('D', _('Disc number')), ('Y', _('Year')), ('G', _('Genre')), ('P', _('File path')), ('F', _('File name')), ('S', _('Stream name')), ('L', _('Song length')), ('E', _('Elapsed time (title only)'))] for codes in [formatcodes[:(len(formatcodes)+1)/2], formatcodes[(len(formatcodes)+1)/2:]]: rows = '\n'.join('<tt>%' + code + '</tt> - ' + help for code, help in codes) markup = '<small>' + rows + '</small>' formattinghelp = ui.label(markup=markup) availableformatbox.pack_start(formattinghelp) availablevbox.pack_start(availableformatbox, False, False, 0) additionalinfo = ui.label(markup='<small><tt>{ }</tt> - ' + _('Info displayed only if all enclosed tags are defined') + '\n<tt>|</tt> - ' + _('Creates columns in the current playlist') + '</small>') availablevbox.pack_start(additionalinfo, False, False, 4) num_rows = len(rows) + 2 table = gtk.Table(num_rows, 2) table.set_col_spacings(12) label_entries = enumerate(zip(labels, entries)) for i, (label, entry) in label_entries: table.attach(label, 0, 1, i, i+1, gtk.FILL) table.attach(entry, 1, 2, i, i+1) table.attach(availableheading, 0, 2, num_rows-2, num_rows-1, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 0, 6) table.attach(availablevbox, 0, 2, num_rows-1, num_rows) alignment = gtk.Alignment(0.5, 0.5, 1.0, 1.0) alignment.set_padding(12, 0, 12, 0) alignment.add(table) frame.add(alignment) tab = gtk.Alignment(0.5, 0.5, 1.0, 1.0) tab.set_padding(12, 12, 12, 12) tab.add(frame) return tab
def extras_tab(self, cbs): """Construct and layout the extras tab""" if not self.scrobbler.imported(): self.config.as_enabled = False extraslabel = ui.label(markup='<b>' + _('Extras') + '</b>') frame = gtk.Frame() frame.set_label_widget(extraslabel) frame.set_shadow_type(gtk.SHADOW_NONE) as_checkbox = gtk.CheckButton(_("_Audioscrobbling (Last.fm)")) as_checkbox.set_active(self.config.as_enabled) as_user_label = ui.label(textmn=_("_Username:"******"_Password:"******"Popup _notification on song changes")) display_notification.set_active(self.config.show_notification) time_names = ["%s %s" % (i , gettext.ngettext('second', 'seconds', int(i))) for i in cbs.popuptimes if i != _('Entire song')] time_names.append(_('Entire song')) notification_options = ui.combo(items=time_names, active=self.config.popup_option, changed_cb=self._notiftime_changed) notification_locs = ui.combo(items=cbs.popuplocations, active=self.config.traytips_notifications_location, changed_cb=self._notiflocation_changed) notifhbox = gtk.HBox(spacing=6) notifhbox.pack_end(notification_locs, False, False) notifhbox.pack_end(notification_options, False, False) display_notification.connect('toggled', cbs.notif_toggled, notifhbox) if not self.config.show_notification: notifhbox.set_sensitive(False) crossfadespin = gtk.SpinButton() crossfadespin.set_range(1, 30) crossfadespin.set_value(self.config.xfade) crossfadespin.set_numeric(True) crossfadespin.set_increments(1, 5) crossfadespin.connect('value-changed', cbs.crossfade_changed) crossfadelabel2 = ui.label(textmn=_("_Fade length:")) crossfadelabel2.set_mnemonic_widget(crossfadespin) crossfadelabel3 = ui.label(text=_("sec")) crossfadebox = gtk.HBox(spacing=12) crossfadebox.pack_end(crossfadelabel3, False, False) crossfadebox.pack_end(crossfadespin, False, False) crossfadebox.pack_end(crossfadelabel2, False, False) crossfadecheck = gtk.CheckButton(_("C_rossfade")) crossfadecheck.connect('toggled', self._crossfadecheck_toggled, crossfadespin, crossfadelabel2, crossfadelabel3) crossfadecheck.connect('toggled', cbs.crossfade_toggled, crossfadespin) crossfadecheck.set_active(self.config.xfade_enabled) crossfadecheck.toggled() # Force the toggled callback widgets = (as_checkbox, as_entries, display_notification, notifhbox, crossfadecheck, crossfadebox) table = gtk.Table(len(widgets), 1) table.set_col_spacings(12) table.set_row_spacings(6) for i, widget in enumerate(widgets): table.attach(widget, 0, 1, i, i+1, gtk.FILL|gtk.EXPAND, gtk.FILL) alignment = gtk.Alignment(0.5, 0.5, 1.0, 1.0) alignment.set_padding(12, 0, 12, 0) alignment.add(table) frame.add(alignment) tab = gtk.Alignment(0.5, 0.5, 1.0, 1.0) tab.set_padding(12, 12, 12, 12) tab.add(frame) as_checkbox.connect('toggled', self._as_enabled_toggled, as_user_entry, as_pass_entry, as_user_label, as_pass_label) if not self.config.as_enabled or not self.scrobbler.imported(): for widget in (as_user_entry, as_pass_entry, as_user_label, as_pass_label): widget.set_sensitive(False) return tab
def display_tab(self, cbs): """Construct and layout the display tab""" displaylabel = ui.label(markup='<b>' + _('Display') + '</b>') frame = gtk.Frame() frame.set_label_widget(displaylabel) frame.set_shadow_type(gtk.SHADOW_NONE) art = gtk.CheckButton(_("_Album art")) art.set_active(self.config.show_covers) stylized_combo = ui.combo(items=[_("Standard"), _("Stylized")], active=self.config.covers_type, changed_cb=cbs.stylized_toggled) stylized_hbox = gtk.HBox(spacing=12) stylized_hbox.pack_end(stylized_combo, False, False) stylized_hbox.pack_end(ui.label( text=_("Artwork style:")), False, False) stylized_hbox.set_sensitive(self.config.show_covers) art_combo = ui.combo(items=[_("Local only"), _("Local and remote")], active=self.config.covers_pref) art_combo.connect('changed', self._config_widget_active, 'covers_pref') orderart_label = ui.label(text=_("Search locations:")) art_hbox = gtk.HBox(spacing=12) art_hbox.pack_end(art_combo, False, False) art_hbox.pack_end(orderart_label, False, False) art_hbox.set_sensitive(self.config.show_covers) art_paths = ["~/.covers/"] art_paths += ("%s/%s" % (_("SONG_DIR"), item) for item in ("cover.jpg", "album.jpg", "folder.jpg", _("custom"))) art_location = ui.combo(items=art_paths, active=self.config.art_location, changed_cb=self._art_location_changed) art_location_hbox = gtk.HBox(spacing=12) art_location_hbox.pack_end(art_location, False, False) art_location_hbox.pack_end(ui.label(text=_("Save art to:")), False, False) art_location_hbox.set_sensitive(self.config.show_covers) art.connect('toggled', cbs.art_toggled, art_hbox, art_location_hbox, stylized_hbox) playback = gtk.CheckButton(_("_Playback/volume buttons")) playback.set_active(self.config.show_playback) playback.connect('toggled', cbs.playback_toggled) progress = gtk.CheckButton(_("Pr_ogressbar")) progress.set_active(self.config.show_progress) progress.connect('toggled', cbs.progress_toggled) statusbar = gtk.CheckButton(_("_Statusbar")) statusbar.set_active(self.config.show_statusbar) statusbar.connect('toggled', cbs.statusbar_toggled) lyrics = gtk.CheckButton(_("Song Ly_rics")) lyrics.set_active(self.config.show_lyrics) savelyrics_label = ui.label(text=_("Save lyrics to:"), x=1) lyrics_location = ui.combo( items=["~/.lyrics/", _("SONG_DIR") + "/"], active=self.config.lyrics_location, changed_cb=self._lyrics_location_changed) lyrics_location_hbox = gtk.HBox(spacing=12) lyrics_location_hbox.pack_end(lyrics_location, False, False) lyrics_location_hbox.pack_end(savelyrics_label, False, False) lyrics_location_hbox.set_sensitive(self.config.show_lyrics) lyrics.connect('toggled', cbs.lyrics_toggled, lyrics_location_hbox) trayicon = gtk.CheckButton(_("System _tray icon")) self.display_trayicon = trayicon trayicon.set_active(self.config.show_trayicon) trayicon.set_sensitive(cbs.trayicon_available) widgets = (playback, progress, statusbar, trayicon, lyrics, lyrics_location_hbox, art, stylized_hbox, art_hbox, art_location_hbox) table = gtk.Table(len(widgets), 1, False) for i, widget in enumerate(widgets): table.attach(widget, 0, 1, i, i+1, gtk.FILL|gtk.EXPAND, gtk.FILL) alignment = gtk.Alignment(0.5, 0.5, 1.0, 1.0) alignment.set_padding(12, 0, 12, 0) alignment.add(table) frame.add(alignment) tab = gtk.Alignment(0.5, 0.5, 1.0, 1.0) tab.set_padding(12, 12, 12, 12) tab.add(frame) return tab
def behavior_tab(self, cbs): """Construct and layout the behavior tab""" windowlabel = ui.label(markup='<b>'+_('Window Behavior')+'</b>') frame = gtk.Frame() frame.set_label_widget(windowlabel) frame.set_shadow_type(gtk.SHADOW_NONE) sticky = gtk.CheckButton(_("_Show window on all workspaces")) sticky.set_active(self.config.sticky) sticky.connect('toggled', cbs.sticky_toggled) ontop = gtk.CheckButton(_("_Keep window above other windows")) ontop.set_active(self.config.ontop) ontop.connect('toggled', cbs.ontop_toggled) decor = gtk.CheckButton(_("_Hide window titlebar")) decor.set_active(not self.config.decorated) decor.connect('toggled', cbs.decorated_toggled) minimize = gtk.CheckButton(_("_Minimize to system tray on close/escape")) minimize.set_active(self.config.minimize_to_systray) minimize.set_tooltip_text(_("If enabled, closing Sonata will minimize it to the system tray. Note that it's currently impossible to detect if there actually is a system tray, so only check this if you have one.")) minimize.connect('toggled', self._config_widget_active, 'minimize_to_systray') self.display_trayicon.connect('toggled', cbs.trayicon_toggled, minimize) minimize.set_sensitive(cbs.trayicon_in_use) widgets = (sticky, ontop, decor, minimize) table = gtk.Table(len(widgets), 1) for i, widget in enumerate(widgets): table.attach(widget, 0, 1, i, i+1, gtk.FILL|gtk.EXPAND, gtk.FILL) alignment = gtk.Alignment() alignment.set_padding(12, 0, 12, 0) alignment.add(table) frame.add(alignment) misclabel = ui.label(markup='<b>' + _('Miscellaneous') + '</b>') misc_frame = gtk.Frame() misc_frame.set_label_widget(misclabel) misc_frame.set_shadow_type(gtk.SHADOW_NONE) update_start = gtk.CheckButton(_("_Update MPD library on start")) update_start.set_active(self.config.update_on_start) update_start.set_tooltip_text(_("If enabled, Sonata will automatically update your MPD library when it starts up.")) update_start.connect('toggled', self._config_widget_active, 'update_on_start') exit_stop = gtk.CheckButton(_("S_top playback on exit")) exit_stop.set_active(self.config.stop_on_exit) exit_stop.set_tooltip_text(_("MPD allows playback even when the client is not open. If enabled, Sonata will behave like a more conventional music player and, instead, stop playback upon exit.")) exit_stop.connect('toggled', self._config_widget_active, 'stop_on_exit') infofile_usage = gtk.CheckButton(_("_Write status file:")) infofile_usage.set_active(self.config.use_infofile) infofile_usage.set_tooltip_text(_("If enabled, Sonata will create a xmms-infopipe like file containing information about the current song. Many applications support the xmms-info file (Instant Messengers, IRC Clients...)")) infopath_options = ui.entry(text=self.config.infofile_path) infopath_options.set_tooltip_text(_("If enabled, Sonata will create a xmms-infopipe like file containing information about the current song. Many applications support the xmms-info file (Instant Messengers, IRC Clients...)")) infopath_options.connect('focus_out_event', cbs.infofile_changed) infopath_options.connect('activate', cbs.infofile_changed, None) if not self.config.use_infofile: infopath_options.set_sensitive(False) infofile_usage.connect('toggled', self._infofile_toggled, infopath_options) infofilebox = gtk.HBox(spacing=6) infofilebox.pack_start(infofile_usage, False, False) infofilebox.pack_start(infopath_options, True, True) widgets = (update_start, exit_stop, infofilebox) misc_table = gtk.Table(len(widgets), 1) for i, widget in enumerate(widgets): misc_table.attach(widget, 0, 1, i, i+1, gtk.FILL|gtk.EXPAND, gtk.FILL) misc_alignment = gtk.Alignment() misc_alignment.set_padding(12, 0, 12, 0) misc_alignment.add(misc_table) misc_frame.add(misc_alignment) table = gtk.Table(2, 1) table.set_row_spacings(12) table.attach(frame, 0, 1, 0, 1, gtk.FILL|gtk.EXPAND, gtk.FILL) table.attach(misc_frame, 0, 1, 1, 2, gtk.FILL|gtk.EXPAND, gtk.FILL) tab = gtk.Alignment() tab.set_padding(12, 12, 12, 12) tab.add(table) return tab
def extras_tab(self, cbs): """Construct and layout the extras tab""" if not self.scrobbler.imported(): self.config.as_enabled = False extraslabel = ui.label(markup='<b>' + _('Extras') + '</b>') frame = gtk.Frame() frame.set_label_widget(extraslabel) frame.set_shadow_type(gtk.SHADOW_NONE) as_checkbox = gtk.CheckButton(_("_Audioscrobbling (Last.fm)")) as_checkbox.set_active(self.config.as_enabled) as_user_label = ui.label(textmn=_("_Username:"******"_Password:"******"Popup _notification on song changes")) display_notification.set_active(self.config.show_notification) time_names = ["%s %s" % (i , gettext.ngettext('second', 'seconds', int(i))) for i in cbs.popuptimes if i != _('Entire song')] time_names.append(_('Entire song')) notification_options = ui.combo(items=time_names, active=self.config.popup_option, changed_cb=self._notiftime_changed) notification_locs = ui.combo(items=cbs.popuplocations, active=self.config.traytips_notifications_location, changed_cb=self._notiflocation_changed) notifhbox = gtk.HBox(spacing=6) notifhbox.pack_end(notification_locs, False, False) notifhbox.pack_end(notification_options, False, False) display_notification.connect('toggled', cbs.notif_toggled, notifhbox) if not self.config.show_notification: notifhbox.set_sensitive(False) crossfadespin = gtk.SpinButton() crossfadespin.set_range(1, 30) crossfadespin.set_value(self.config.xfade) crossfadespin.set_numeric(True) crossfadespin.set_increments(1, 5) crossfadespin.connect('value-changed', cbs.crossfade_changed) crossfadelabel2 = ui.label(text=_("Fade length") + ":") crossfadelabel2 = ui.label(textmn=_("_Fade length") + ":") crossfadelabel2.set_mnemonic_widget(crossfadespin) crossfadelabel3 = ui.label(text=_("sec")) crossfadebox = gtk.HBox(spacing=12) crossfadebox.pack_end(crossfadelabel3, False, False) crossfadebox.pack_end(crossfadespin, False, False) crossfadebox.pack_end(crossfadelabel2, False, False) crossfadecheck = gtk.CheckButton(_("C_rossfade")) crossfadecheck.connect('toggled', self._crossfadecheck_toggled, crossfadespin, crossfadelabel2, crossfadelabel3) crossfadecheck.connect('toggled', cbs.crossfade_toggled, crossfadespin) crossfadecheck.set_active(self.config.xfade_enabled) crossfadecheck.toggled() # Force the toggled callback widgets = (as_checkbox, as_entries, display_notification, notifhbox, crossfadecheck, crossfadebox) table = gtk.Table(len(widgets), 1) table.set_col_spacings(12) table.set_row_spacings(6) for i, widget in enumerate(widgets): table.attach(widget, 0, 1, i, i+1, gtk.FILL|gtk.EXPAND, gtk.FILL) alignment = gtk.Alignment(0.5, 0.5, 1.0, 1.0) alignment.set_padding(12, 0, 12, 0) alignment.add(table) frame.add(alignment) tab = gtk.Alignment(0.5, 0.5, 1.0, 1.0) tab.set_padding(12, 12, 12, 12) tab.add(frame) as_checkbox.connect('toggled', self._as_enabled_toggled, as_user_entry, as_pass_entry, as_user_label, as_pass_label) if not self.config.as_enabled or not self.scrobbler.imported(): for widget in (as_user_entry, as_pass_entry, as_user_label, as_pass_label): widget.set_sensitive(False) return tab
def on_tags_edit(self, files, temp_mpdpaths, music_dir): """Display the editing dialog""" # Try loading module global tagpy if tagpy is None: try: import tagpy except ImportError: ui.show_msg(self.window, _("Taglib and/or tagpy not found, tag editing support disabled."), _("Edit Tags"), 'editTagsError', gtk.BUTTONS_CLOSE, response_cb=ui.dialog_destroy) ui.change_cursor(None) return # Set default tag encoding to utf8.. fixes some reported bugs. import tagpy.id3v2 as id3v2 id3v2.FrameFactory.instance().setDefaultTextEncoding(tagpy.StringType.UTF8) # Make sure tagpy is at least 0.91 if hasattr(tagpy.Tag.title, '__call__'): ui.show_msg(self.window, _("Tagpy version < 0.91. Please upgrade to a newer version, tag editing support disabled."), _("Edit Tags"), 'editTagsError', gtk.BUTTONS_CLOSE, response_cb=ui.dialog_destroy) ui.change_cursor(None) return if not os.path.isdir(misc.file_from_utf8(music_dir)): ui.show_msg(self.window, _("The path %s does not exist. Please specify a valid music directory in preferences.") % music_dir, _("Edit Tags"), 'editTagsError', gtk.BUTTONS_CLOSE, response_cb=ui.dialog_destroy) ui.change_cursor(None) return # XXX file list was created here if len(files) == 0: ui.change_cursor(None) return # Initialize: self.tagnum = -1 tags = [{'title':'', 'artist':'', 'album':'', 'year':'', 'track':'', 'genre':'', 'comment':'', 'title-changed':False, 'artist-changed':False, 'album-changed':False, 'year-changed':False, 'track-changed':False, 'genre-changed':False, 'comment-changed':False, 'fullpath':misc.file_from_utf8(filename), 'mpdpath':path} for filename, path in zip(files, temp_mpdpaths)] if not os.path.exists(tags[0]['fullpath']): ui.change_cursor(None) ui.show_msg(self.window, _("File '%s' not found. Please specify a valid music directory in preferences.") % tags[0]['fullpath'], _("Edit Tags"), 'editTagsError', gtk.BUTTONS_CLOSE, response_cb=ui.dialog_destroy) return if not self.tags_next_tag(tags): ui.change_cursor(None) ui.show_msg(self.window, _("No music files with editable tags found."), _("Edit Tags"), 'editTagsError', gtk.BUTTONS_CLOSE, response_cb=ui.dialog_destroy) return editwindow = ui.dialog(parent=self.window, flags=gtk.DIALOG_MODAL, role='editTags', resizable=False, separator=False) editwindow.set_size_request(375, -1) table = gtk.Table(9, 2, False) table.set_row_spacings(2) self.filelabel = ui.label(select=True, wrap=True) filehbox = gtk.HBox() sonataicon = ui.image(stock='sonata', stocksize=gtk.ICON_SIZE_DND, x=1) expandbutton = ui.button(" ") self.set_expandbutton_state(expandbutton) expandvbox = gtk.VBox() expandvbox.pack_start(ui.label(), True, True) expandvbox.pack_start(expandbutton, False, False) expandvbox.pack_start(ui.label(), True, True) expandbutton.connect('clicked', self.toggle_path) blanklabel = ui.label(w=5, h=12) filehbox.pack_start(sonataicon, False, False, 2) filehbox.pack_start(self.filelabel, True, True, 2) filehbox.pack_start(expandvbox, False, False, 2) filehbox.pack_start(blanklabel, False, False, 2) titlelabel, titleentry, titlebutton, titlehbox = self._create_label_entry_button_hbox(_("Title:")) artistlabel, artistentry, artistbutton, artisthbox = self._create_label_entry_button_hbox(_("Artist:")) albumlabel, albumentry, albumbutton, albumhbox = self._create_label_entry_button_hbox(_("Album:")) yearlabel, yearentry, yearbutton, yearhbox = self._create_label_entry_button_hbox(_("Year:")) yearentry.set_size_request(50,-1) tracklabel, trackentry, trackbutton, trackhbox = self._create_label_entry_button_hbox(" " + _("Track:"), True) trackentry.set_size_request(50,-1) yearandtrackhbox = gtk.HBox() yearandtrackhbox.pack_start(yearhbox, True, True, 0) yearandtrackhbox.pack_start(trackhbox, True, True, 0) yearentry.connect("insert_text", self.tags_win_entry_constraint, True) trackentry.connect("insert_text", self.tags_win_entry_constraint, False) genrelabel = ui.label(text=_("Genre:"), x=1) genrecombo = ui.comboentry(items=self.tags_win_genres(), wrap=2) genreentry = genrecombo.get_child() genrehbox = gtk.HBox() genrebutton = ui.button() genrebuttonvbox = self.tags_win_create_apply_all_button(genrebutton, genreentry) genrehbox.pack_start(genrelabel, False, False, 2) genrehbox.pack_start(genrecombo, True, True, 2) genrehbox.pack_start(genrebuttonvbox, False, False, 2) commentlabel, commententry, commentbutton, commenthbox = self._create_label_entry_button_hbox(_("Comment:")) ui.set_widths_equal([titlelabel, artistlabel, albumlabel, yearlabel, genrelabel, commentlabel, sonataicon]) genrecombo.set_size_request(-1, titleentry.size_request()[1]) tablewidgets = [ui.label(), filehbox, ui.label(), titlehbox, artisthbox, albumhbox, yearandtrackhbox, genrehbox, commenthbox, ui.label()] for i, widget in enumerate(tablewidgets): table.attach(widget, 1, 2, i+1, i+2, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 2, 0) editwindow.vbox.pack_start(table) saveall_button = None if len(files) > 1: # Only show save all button if more than one song being edited. saveall_button = ui.button(text=_("Save _All")) editwindow.action_area.pack_start(saveall_button) editwindow.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT) editwindow.add_button(gtk.STOCK_SAVE, gtk.RESPONSE_ACCEPT) editwindow.connect('delete_event', self.tags_win_hide, tags) entries = [titleentry, artistentry, albumentry, yearentry, trackentry, genreentry, commententry] buttons = [titlebutton, artistbutton, albumbutton, yearbutton, trackbutton, genrebutton, commentbutton] entries_names = ["title", "artist", "album", "year", "track", "genre", "comment"] editwindow.connect('response', self.tags_win_response, tags, entries, entries_names) if saveall_button: saveall_button.connect('clicked', self.tags_win_save_all, editwindow, tags, entries, entries_names) for button, name, entry in zip(buttons, entries_names, entries): entry.connect('changed', self.tags_win_entry_changed) button.connect('clicked', self.tags_win_apply_all, name, tags, entry) self.tags_win_update(editwindow, tags, entries, entries_names) ui.change_cursor(None) self.filelabel.set_size_request(editwindow.size_request()[0] - titlelabel.size_request()[0] - 70, -1) editwindow.show_all()
def on_tags_edit(self, files, temp_mpdpaths, music_dir): """Display the editing dialog""" # Try loading module global tagpy if tagpy is None: try: import tagpy except ImportError: ui.show_msg( self.window, _("Taglib and/or tagpy not found, tag editing support disabled." ), _("Edit Tags"), 'editTagsError', gtk.BUTTONS_CLOSE, response_cb=ui.dialog_destroy) ui.change_cursor(None) return # Set default tag encoding to utf8.. fixes some reported bugs. import tagpy.id3v2 as id3v2 id3v2.FrameFactory.instance().setDefaultTextEncoding( tagpy.StringType.UTF8) # Make sure tagpy is at least 0.91 if hasattr(tagpy.Tag.title, '__call__'): ui.show_msg( self.window, _("Tagpy version < 0.91. Please upgrade to a newer version, tag editing support disabled." ), _("Edit Tags"), 'editTagsError', gtk.BUTTONS_CLOSE, response_cb=ui.dialog_destroy) ui.change_cursor(None) return if not os.path.isdir(misc.file_from_utf8(music_dir)): ui.show_msg( self.window, _("The path") + " " + music_dir + " " + _("does not exist. Please specify a valid music directory in preferences." ), _("Edit Tags"), 'editTagsError', gtk.BUTTONS_CLOSE, response_cb=ui.dialog_destroy) ui.change_cursor(None) return # XXX file list was created here if len(files) == 0: ui.change_cursor(None) return # Initialize: self.tagnum = -1 tags = [{ 'title': '', 'artist': '', 'album': '', 'year': '', 'track': '', 'genre': '', 'comment': '', 'title-changed': False, 'artist-changed': False, 'album-changed': False, 'year-changed': False, 'track-changed': False, 'genre-changed': False, 'comment-changed': False, 'fullpath': misc.file_from_utf8(filename), 'mpdpath': path } for filename, path in zip(files, temp_mpdpaths)] if not os.path.exists(tags[0]['fullpath']): ui.change_cursor(None) ui.show_msg( self.window, _("File ") + "\"" + tags[0]['fullpath'] + "\"" + _(" not found. Please specify a valid music directory in preferences." ), _("Edit Tags"), 'editTagsError', gtk.BUTTONS_CLOSE, response_cb=ui.dialog_destroy) return if not self.tags_next_tag(tags): ui.change_cursor(None) ui.show_msg(self.window, _("No music files with editable tags found."), _("Edit Tags"), 'editTagsError', gtk.BUTTONS_CLOSE, response_cb=ui.dialog_destroy) return editwindow = ui.dialog(parent=self.window, flags=gtk.DIALOG_MODAL, role='editTags', resizable=False, separator=False) editwindow.set_size_request(375, -1) table = gtk.Table(9, 2, False) table.set_row_spacings(2) self.filelabel = ui.label(select=True, wrap=True) filehbox = gtk.HBox() sonataicon = ui.image(stock='sonata', stocksize=gtk.ICON_SIZE_DND, x=1) expandbutton = ui.button(" ") self.set_expandbutton_state(expandbutton) expandvbox = gtk.VBox() expandvbox.pack_start(ui.label(), True, True) expandvbox.pack_start(expandbutton, False, False) expandvbox.pack_start(ui.label(), True, True) expandbutton.connect('clicked', self.toggle_path) blanklabel = ui.label(w=5, h=12) filehbox.pack_start(sonataicon, False, False, 2) filehbox.pack_start(self.filelabel, True, True, 2) filehbox.pack_start(expandvbox, False, False, 2) filehbox.pack_start(blanklabel, False, False, 2) titlelabel, titleentry, titlebutton, titlehbox = self._create_label_entry_button_hbox( _("Title")) artistlabel, artistentry, artistbutton, artisthbox = self._create_label_entry_button_hbox( _("Artist")) albumlabel, albumentry, albumbutton, albumhbox = self._create_label_entry_button_hbox( _("Album")) yearlabel, yearentry, yearbutton, yearhbox = self._create_label_entry_button_hbox( _("Year")) yearentry.set_size_request(50, -1) tracklabel, trackentry, trackbutton, trackhbox = self._create_label_entry_button_hbox( " " + _("Track"), True) trackentry.set_size_request(50, -1) yearandtrackhbox = gtk.HBox() yearandtrackhbox.pack_start(yearhbox, True, True, 0) yearandtrackhbox.pack_start(trackhbox, True, True, 0) yearentry.connect("insert_text", self.tags_win_entry_constraint, True) trackentry.connect("insert_text", self.tags_win_entry_constraint, False) genrelabel = ui.label(text=_("Genre") + ":", x=1) genrecombo = ui.comboentry(items=self.tags_win_genres(), wrap=2) genreentry = genrecombo.get_child() genrehbox = gtk.HBox() genrebutton = ui.button() genrebuttonvbox = self.tags_win_create_apply_all_button( genrebutton, genreentry) genrehbox.pack_start(genrelabel, False, False, 2) genrehbox.pack_start(genrecombo, True, True, 2) genrehbox.pack_start(genrebuttonvbox, False, False, 2) commentlabel, commententry, commentbutton, commenthbox = self._create_label_entry_button_hbox( _("Comment")) ui.set_widths_equal([ titlelabel, artistlabel, albumlabel, yearlabel, genrelabel, commentlabel, sonataicon ]) genrecombo.set_size_request(-1, titleentry.size_request()[1]) tablewidgets = [ ui.label(), filehbox, ui.label(), titlehbox, artisthbox, albumhbox, yearandtrackhbox, genrehbox, commenthbox, ui.label() ] for i, widget in enumerate(tablewidgets): table.attach(widget, 1, 2, i + 1, i + 2, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 2, 0) editwindow.vbox.pack_start(table) saveall_button = None if len(files) > 1: # Only show save all button if more than one song being edited. saveall_button = ui.button(text=_("Save _All")) editwindow.action_area.pack_start(saveall_button) editwindow.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT) editwindow.add_button(gtk.STOCK_SAVE, gtk.RESPONSE_ACCEPT) editwindow.connect('delete_event', self.tags_win_hide, tags) entries = [ titleentry, artistentry, albumentry, yearentry, trackentry, genreentry, commententry ] buttons = [ titlebutton, artistbutton, albumbutton, yearbutton, trackbutton, genrebutton, commentbutton ] entries_names = [ "title", "artist", "album", "year", "track", "genre", "comment" ] editwindow.connect('response', self.tags_win_response, tags, entries, entries_names) if saveall_button: saveall_button.connect('clicked', self.tags_win_save_all, editwindow, tags, entries, entries_names) for button, name, entry in zip(buttons, entries_names, entries): entry.connect('changed', self.tags_win_entry_changed) button.connect('clicked', self.tags_win_apply_all, name, tags, entry) self.tags_win_update(editwindow, tags, entries, entries_names) ui.change_cursor(None) self.filelabel.set_size_request( editwindow.size_request()[0] - titlelabel.size_request()[0] - 70, -1) editwindow.show_all()
def about_shortcuts(self, _button): # define the shortcuts and their descriptions # these are all gettextable mainshortcuts = \ [["F1", _("About Sonata")], ["F5", _("Preferences")], ["F11", _("Fullscreen Artwork Mode")], ["Alt-[1-5]", _("Switch to [1st-5th] tab")], ["Alt-C", _("Connect to MPD")], ["Alt-D", _("Disconnect from MPD")], ["Alt-R", _("Randomize current playlist")], ["Alt-Down", _("Expand player")], ["Alt-Left", _("Switch to previous tab")], ["Alt-Right", _("Switch to next tab")], ["Alt-Up", _("Collapse player")], ["Ctrl-H", _("Search library")], ["Ctrl-Q", _("Quit")], ["Ctrl-Shift-U", _("Update entire library")], ["Menu", _("Display popup menu")], ["Escape", _("Minimize to system tray (if enabled)")]] playbackshortcuts = \ [["Ctrl-Left", _("Previous track")], ["Ctrl-Right", _("Next track")], ["Ctrl-P", _("Play/Pause")], ["Ctrl-S", _("Stop")], ["Ctrl-Minus", _("Lower the volume")], ["Ctrl-Plus", _("Raise the volume")]] currentshortcuts = \ [["Enter/Space", _("Play selected song")], ["Delete", _("Remove selected song(s)")], ["Ctrl-I", _("Center currently playing song")], ["Ctrl-T", _("Edit selected song's tags")], ["Ctrl-Shift-S", _("Save to new playlist")], ["Ctrl-Delete", _("Clear list")], ["Alt-R", _("Randomize list")]] libraryshortcuts = \ [["Enter/Space", _("Add selected song(s) or enter directory")], ["Backspace", _("Go to parent directory")], ["Ctrl-D", _("Add selected item(s)")], ["Ctrl-R", _("Replace with selected item(s)")], ["Ctrl-T", _("Edit selected song's tags")], ["Ctrl-Shift-D", _("Add selected item(s) and play")], ["Ctrl-Shift-R", _("Replace with selected item(s) and play")], ["Ctrl-U", _("Update selected item(s)/path(s)")]] playlistshortcuts = \ [["Enter/Space", _("Add selected playlist(s)")], ["Delete", _("Remove selected playlist(s)")], ["Ctrl-D", _("Add selected playlist(s)")], ["Ctrl-R", _("Replace with selected playlist(s)")], ["Ctrl-Shift-D", _("Add selected playlist(s) and play")], ["Ctrl-Shift-R", _(('Replace with selected ' 'playlist(s) and play'))]] streamshortcuts = \ [["Enter/Space", _("Add selected stream(s)")], ["Delete", _("Remove selected stream(s)")], ["Ctrl-D", _("Add selected stream(s)")], ["Ctrl-R", _("Replace with selected stream(s)")], ["Ctrl-Shift-D", _("Add selected stream(s) and play")], ["Ctrl-Shift-R", _(('Replace with selected ' 'stream(s) and play'))]] infoshortcuts = \ [["Ctrl-T", _("Edit playing song's tags")]] # define the main array- this adds headings to each section of # shortcuts that will be displayed shortcuts = [[_("Main Shortcuts"), mainshortcuts], [_("Playback Shortcuts"), playbackshortcuts], [_("Current Shortcuts"), currentshortcuts], [_("Library Shortcuts"), libraryshortcuts], [_("Playlist Shortcuts"), playlistshortcuts], [_("Stream Shortcuts"), streamshortcuts], [_("Info Shortcuts"), infoshortcuts]] dialog = ui.dialog(title=_("Shortcuts"), parent=self.about_dialog, flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, buttons=(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE), role='shortcuts', default=gtk.RESPONSE_CLOSE, h=320) # each pair is a [ heading, shortcutlist ] vbox = gtk.VBox() for pair in shortcuts: titlelabel = ui.label(markup="<b>%s</b>" % pair[0]) vbox.pack_start(titlelabel, False, False, 2) # print the items of [ shortcut, desc ] for item in pair[1]: tmphbox = gtk.HBox() tmplabel = ui.label(markup="<b>%s:</b>" % item[0], y=0) tmpdesc = ui.label(text=item[1], wrap=True, y=0) tmphbox.pack_start(tmplabel, False, False, 2) tmphbox.pack_start(tmpdesc, True, True, 2) vbox.pack_start(tmphbox, False, False, 2) vbox.pack_start(ui.label(text=" "), False, False, 2) scrollbox = ui.scrollwindow(policy_x=gtk.POLICY_NEVER, addvp=vbox) dialog.vbox.pack_start(scrollbox, True, True, 2) dialog.show_all() dialog.run() dialog.destroy()
def behavior_tab(self, cbs): """Construct and layout the behavior tab""" windowlabel = ui.label(markup='<b>'+_('Window Behavior')+'</b>') frame = gtk.Frame() frame.set_label_widget(windowlabel) frame.set_shadow_type(gtk.SHADOW_NONE) sticky = gtk.CheckButton(_("_Show window on all workspaces")) sticky.set_active(self.config.sticky) sticky.connect('toggled', cbs.sticky_toggled) ontop = gtk.CheckButton(_("_Keep window above other windows")) ontop.set_active(self.config.ontop) ontop.connect('toggled', cbs.ontop_toggled) decor = gtk.CheckButton(_("_Hide window titlebar")) decor.set_active(not self.config.decorated) decor.connect('toggled', cbs.decorated_toggled, self.prefswindow) minimize = gtk.CheckButton(_("_Minimize to system tray on close/escape")) minimize.set_active(self.config.minimize_to_systray) minimize.set_tooltip_text(_("If enabled, closing Sonata will minimize it to the system tray. Note that it's currently impossible to detect if there actually is a system tray, so only check this if you have one.")) minimize.connect('toggled', self._config_widget_active, 'minimize_to_systray') self.display_trayicon.connect('toggled', cbs.trayicon_toggled, minimize) minimize.set_sensitive(cbs.trayicon_in_use) widgets = (sticky, ontop, decor, minimize) table = gtk.Table(len(widgets), 1) for i, widget in enumerate(widgets): table.attach(widget, 0, 1, i, i+1, gtk.FILL|gtk.EXPAND, gtk.FILL) alignment = gtk.Alignment() alignment.set_padding(12, 0, 12, 0) alignment.add(table) frame.add(alignment) misclabel = ui.label(markup='<b>' + _('Miscellaneous') + '</b>') misc_frame = gtk.Frame() misc_frame.set_label_widget(misclabel) misc_frame.set_shadow_type(gtk.SHADOW_NONE) update_start = gtk.CheckButton(_("_Update MPD library on start")) update_start.set_active(self.config.update_on_start) update_start.set_tooltip_text(_("If enabled, Sonata will automatically update your MPD library when it starts up.")) update_start.connect('toggled', self._config_widget_active, 'update_on_start') exit_stop = gtk.CheckButton(_("S_top playback on exit")) exit_stop.set_active(self.config.stop_on_exit) exit_stop.set_tooltip_text(_("MPD allows playback even when the client is not open. If enabled, Sonata will behave like a more conventional music player and, instead, stop playback upon exit.")) exit_stop.connect('toggled', self._config_widget_active, 'stop_on_exit') infofile_usage = gtk.CheckButton(_("_Write status file:")) infofile_usage.set_active(self.config.use_infofile) infofile_usage.set_tooltip_text(_("If enabled, Sonata will create a xmms-infopipe like file containing information about the current song. Many applications support the xmms-info file (Instant Messengers, IRC Clients...)")) infopath_options = ui.entry(text=self.config.infofile_path) infopath_options.set_tooltip_text(_("If enabled, Sonata will create a xmms-infopipe like file containing information about the current song. Many applications support the xmms-info file (Instant Messengers, IRC Clients...)")) infopath_options.connect('focus_out_event', cbs.infofile_changed) infopath_options.connect('activate', cbs.infofile_changed, None) if not self.config.use_infofile: infopath_options.set_sensitive(False) infofile_usage.connect('toggled', self._infofile_toggled, infopath_options) infofilebox = gtk.HBox(spacing=6) infofilebox.pack_start(infofile_usage, False, False) infofilebox.pack_start(infopath_options, True, True) widgets = (update_start, exit_stop, infofilebox) misc_table = gtk.Table(len(widgets), 1) for i, widget in enumerate(widgets): misc_table.attach(widget, 0, 1, i, i+1, gtk.FILL|gtk.EXPAND, gtk.FILL) misc_alignment = gtk.Alignment() misc_alignment.set_padding(12, 0, 12, 0) misc_alignment.add(misc_table) misc_frame.add(misc_alignment) table = gtk.Table(2, 1) table.set_row_spacings(12) table.attach(frame, 0, 1, 0, 1, gtk.FILL|gtk.EXPAND, gtk.FILL) table.attach(misc_frame, 0, 1, 1, 2, gtk.FILL|gtk.EXPAND, gtk.FILL) tab = gtk.Alignment() tab.set_padding(12, 12, 12, 12) tab.add(table) return tab
def mpd_tab(self, cbs=None): """Construct and layout the MPD tab""" mpdlabel = ui.label(markup='<b>' + _('MPD Connection') + '</b>') frame = gtk.Frame() frame.set_label_widget(mpdlabel) frame.set_shadow_type(gtk.SHADOW_NONE) controlbox = gtk.HBox() profiles = ui.combo() add_profile = ui.button(img=ui.image(stock=gtk.STOCK_ADD)) remove_profile = ui.button(img=ui.image(stock=gtk.STOCK_REMOVE)) self._populate_profile_combo(profiles, self.config.profile_num, remove_profile) controlbox.pack_start(profiles, False, False, 2) controlbox.pack_start(remove_profile, False, False, 2) controlbox.pack_start(add_profile, False, False, 2) namelabel = ui.label(textmn=_("_Name:")) nameentry = ui.entry() namelabel.set_mnemonic_widget(nameentry) hostlabel = ui.label(textmn=_("_Host:")) hostentry = ui.entry() hostlabel.set_mnemonic_widget(hostentry) portlabel = ui.label(textmn=_("_Port:")) portentry = gtk.SpinButton(gtk.Adjustment(0 ,0 ,65535, 1),1) portentry.set_numeric(True) portlabel.set_mnemonic_widget(portentry) dirlabel = ui.label(textmn=_("_Music dir:")) direntry = gtk.FileChooserButton(_('Select a Music Directory')) self.direntry = direntry direntry.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER) direntry.connect('selection-changed', self._direntry_changed, profiles) dirlabel.set_mnemonic_widget(direntry) passwordlabel = ui.label(textmn=_("Pa_ssword:")) passwordentry = ui.entry(password=True) passwordlabel.set_mnemonic_widget(passwordentry) passwordentry.set_tooltip_text(_("Leave blank if no password is required.")) autoconnect = gtk.CheckButton(_("_Autoconnect on start")) autoconnect.set_active(self.config.autoconnect) autoconnect.connect('toggled', self._config_widget_active, 'autoconnect') # Fill in entries with current profile: self._profile_chosen(profiles, nameentry, hostentry, portentry, passwordentry, direntry) # Update display if $MPD_HOST or $MPD_PORT is set: host, port, password = misc.mpd_env_vars() if host or port: self.using_mpd_env_vars = True if not host: host = "" if not port: port = 0 if not password: password = "" hostentry.set_text(str(host)) portentry.set_value(port) passwordentry.set_text(str(password)) nameentry.set_text(_("Using MPD_HOST/PORT")) for widget in [hostentry, portentry, passwordentry, nameentry, profiles, add_profile, remove_profile]: widget.set_sensitive(False) else: self.using_mpd_env_vars = False nameentry.connect('changed', self._nameentry_changed, profiles, remove_profile) hostentry.connect('changed', self._hostentry_changed, profiles) portentry.connect('value-changed', self._portentry_changed, profiles) passwordentry.connect('changed', self._passwordentry_changed, profiles) profiles.connect('changed', self._profile_chosen, nameentry, hostentry, portentry, passwordentry, direntry) add_profile.connect('clicked', self._add_profile, nameentry, profiles, remove_profile) remove_profile.connect('clicked', self._remove_profile, profiles, remove_profile) rows = [(namelabel, nameentry), (hostlabel, hostentry), (portlabel, portentry), (passwordlabel, passwordentry), (dirlabel, direntry)] connection_table = gtk.Table(len(rows), 2) connection_table.set_col_spacings(12) for i, (label, entry) in enumerate(rows): connection_table.attach(label, 0, 1, i, i+1, gtk.FILL, gtk.FILL) connection_table.attach(entry, 1, 2, i, i+1, gtk.FILL|gtk.EXPAND, gtk.FILL) connection_alignment = gtk.Alignment(0.5, 0.5, 1.0, 1.0) connection_alignment.set_padding(12, 12, 12, 12) connection_alignment.add(connection_table) connection_frame = gtk.Frame() connection_frame.set_label_widget(controlbox) connection_frame.add(connection_alignment) table = gtk.Table(2, 1) table.set_row_spacings(12) table.attach(connection_frame, 0, 1, 0, 1, gtk.FILL|gtk.EXPAND, gtk.FILL) table.attach(autoconnect, 0, 1, 1, 2, gtk.FILL|gtk.EXPAND, gtk.FILL) alignment = gtk.Alignment(0.5, 0.5, 1.0, 1.0) alignment.set_padding(12, 0, 12, 0) alignment.add(table) frame.add(alignment) tab = gtk.Alignment(0.5, 0.5, 1.0, 1.0) tab.set_padding(12, 12, 12, 12) tab.add(frame) return tab
def on_prefs_real(self, parent_window, popuptimes, as_imported, as_import, as_init, as_reauth, trayicon_available, trayicon_in_use, reconnect, renotify, reinfofile, prefs_notif_toggled, prefs_stylized_toggled, prefs_art_toggled, prefs_playback_toggled, prefs_progress_toggled, prefs_statusbar_toggled, prefs_lyrics_toggled, prefs_trayicon_toggled, prefs_window_response): """Display the preferences dialog""" self.window = parent_window self.as_imported = as_imported self.as_import = as_import self.as_init = as_init self.as_reauth = as_reauth self.reconnect = reconnect self.renotify = renotify self.reinfofile = reinfofile prefswindow = ui.dialog(title=_("Preferences"), parent=self.window, flags=gtk.DIALOG_DESTROY_WITH_PARENT, role='preferences', resizable=False, separator=False) hbox = gtk.HBox() prefsnotebook = gtk.Notebook() # MPD tab mpdlabel = ui.label(markup='<b>' + _('MPD Connection') + '</b>', y=1) controlbox = gtk.HBox() profiles = ui.combo() add_profile = ui.button(img=ui.image(stock=gtk.STOCK_ADD)) remove_profile = ui.button(img=ui.image(stock=gtk.STOCK_REMOVE)) self.prefs_populate_profile_combo(profiles, self.profile_num, remove_profile) controlbox.pack_start(profiles, False, False, 2) controlbox.pack_start(remove_profile, False, False, 2) controlbox.pack_start(add_profile, False, False, 2) namebox = gtk.HBox() namelabel = ui.label(text=_("Name") + ":") namebox.pack_start(namelabel, False, False, 0) nameentry = ui.entry() namebox.pack_start(nameentry, True, True, 10) hostbox = gtk.HBox() hostlabel = ui.label(text=_("Host") + ":") hostbox.pack_start(hostlabel, False, False, 0) hostentry = ui.entry() hostbox.pack_start(hostentry, True, True, 10) portbox = gtk.HBox() portlabel = ui.label(text=_("Port") + ":") portbox.pack_start(portlabel, False, False, 0) portentry = ui.entry() portbox.pack_start(portentry, True, True, 10) dirbox = gtk.HBox() dirlabel = ui.label(text=_("Music dir") + ":") dirbox.pack_start(dirlabel, False, False, 0) direntry = ui.entry() direntry.connect('changed', self.prefs_direntry_changed, profiles) dirbox.pack_start(direntry, True, True, 10) passwordbox = gtk.HBox() passwordlabel = ui.label(text=_("Password") + ":") passwordbox.pack_start(passwordlabel, False, False, 0) passwordentry = ui.entry(password=True) passwordentry.set_tooltip_text(_("Leave blank if no password is required.")) passwordbox.pack_start(passwordentry, True, True, 10) mpd_labels = [namelabel, hostlabel, portlabel, passwordlabel, dirlabel] ui.set_widths_equal(mpd_labels) autoconnect = gtk.CheckButton(_("Autoconnect on start")) autoconnect.set_active(self.autoconnect) # Fill in entries with current profile: self.prefs_profile_chosen(profiles, nameentry, hostentry, portentry, passwordentry, direntry) # Update display if $MPD_HOST or $MPD_PORT is set: host, port, password = misc.mpd_env_vars() if host or port: using_mpd_env_vars = True if not host: host = "" if not port: port = "" if not password: password = "" hostentry.set_text(str(host)) portentry.set_text(str(port)) passwordentry.set_text(str(password)) nameentry.set_text(_("Using MPD_HOST/PORT")) for widget in [hostentry, portentry, passwordentry, nameentry, profiles, add_profile, remove_profile]: widget.set_sensitive(False) else: using_mpd_env_vars = False # remove_profile is properly set in populate_profile_combo: for widget in [hostentry, portentry, passwordentry, nameentry, profiles, add_profile]: widget.set_sensitive(True) nameentry.connect('changed', self.prefs_nameentry_changed, profiles, remove_profile) hostentry.connect('changed', self.prefs_hostentry_changed, profiles) portentry.connect('changed', self.prefs_portentry_changed, profiles) passwordentry.connect('changed', self.prefs_passwordentry_changed, profiles) profiles.connect('changed', self.prefs_profile_chosen, nameentry, hostentry, portentry, passwordentry, direntry) add_profile.connect('clicked', self.prefs_add_profile, nameentry, profiles, remove_profile) remove_profile.connect('clicked', self.prefs_remove_profile, profiles, remove_profile) mpd_frame = gtk.Frame() table = gtk.Table(6, 2, False) table.set_col_spacings(3) table.attach(ui.label(), 1, 3, 1, 2, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 10, 0) table.attach(namebox, 1, 3, 2, 3, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 10, 0) table.attach(hostbox, 1, 3, 3, 4, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 10, 0) table.attach(portbox, 1, 3, 4, 5, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 10, 0) table.attach(passwordbox, 1, 3, 5, 6, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 10, 0) table.attach(dirbox, 1, 3, 6, 7, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 10, 0) table.attach(ui.label(), 1, 3, 7, 8, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 10, 0) mpd_frame.add(table) mpd_frame.set_label_widget(controlbox) mpd_table = gtk.Table(9, 2, False) mpd_table.set_col_spacings(3) mpd_table.attach(ui.label(), 1, 3, 1, 2, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 10, 0) mpd_table.attach(mpdlabel, 1, 3, 2, 3, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0) mpd_table.attach(ui.label(), 1, 3, 3, 4, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 10, 0) mpd_table.attach(mpd_frame, 1, 3, 4, 10, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) mpd_table.attach(ui.label(), 1, 3, 10, 11, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) mpd_table.attach(autoconnect, 1, 3, 11, 12, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) mpd_table.attach(ui.label(), 1, 3, 12, 13, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) mpd_table.attach(ui.label(), 1, 3, 13, 14, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) mpd_table.attach(ui.label(), 1, 3, 14, 15, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) # Extras tab if not as_imported: self.as_enabled = False as_label = ui.label(markup='<b>' + _('Extras') + '</b>') as_frame = gtk.Frame() as_frame.set_label_widget(as_label) as_frame.set_shadow_type(gtk.SHADOW_NONE) as_frame.set_border_width(15) as_vbox = gtk.VBox() as_vbox.set_border_width(15) as_checkbox = gtk.CheckButton(_("Enable Audioscrobbler")) as_checkbox.set_active(self.as_enabled) as_vbox.pack_start(as_checkbox, False) as_table = gtk.Table(2, 2) as_table.set_col_spacings(3) as_user_label = ui.label(text=" " + _("Username:"******" " + _("Password:"******"Popup notification on song changes")) display_notification.set_active(self.show_notification) notifhbox = gtk.HBox() notif_blank = ui.label(x=1) notifhbox.pack_start(notif_blank) time_names = [] for i in popuptimes: if i != _('Entire song'): time_names.append(i + ' ' + gettext.ngettext('second', 'seconds', int(i))) else: time_names.append(i) notification_options = ui.combo(items=time_names, active=self.popup_option, changed_cb=self.prefs_notiftime_changed) notification_locs = ui.combo(items=self.popuplocations, active=self.traytips_notifications_location, changed_cb=self.prefs_notiflocation_changed) display_notification.connect('toggled', prefs_notif_toggled, notifhbox) notifhbox.pack_start(notification_options, False, False, 2) notifhbox.pack_start(notification_locs, False, False, 2) if not self.show_notification: notifhbox.set_sensitive(False) crossfadecheck = gtk.CheckButton(_("Enable Crossfade")) crossfadespin = gtk.SpinButton() crossfadespin.set_digits(0) crossfadespin.set_range(1, 30) crossfadespin.set_value(self.xfade) crossfadespin.set_numeric(True) crossfadespin.set_increments(1, 5) crossfadespin.set_size_request(70, -1) crossfadelabel2 = ui.label(text=_("Fade length") + ":", x=1) crossfadelabel3 = ui.label(text=_("sec")) if not self.xfade_enabled: crossfadespin.set_sensitive(False) crossfadelabel2.set_sensitive(False) crossfadelabel3.set_sensitive(False) crossfadecheck.set_active(False) else: crossfadespin.set_sensitive(True) crossfadelabel2.set_sensitive(True) crossfadelabel3.set_sensitive(True) crossfadecheck.set_active(True) crossfadebox = gtk.HBox() crossfadebox.pack_start(crossfadelabel2) crossfadebox.pack_start(crossfadespin, False, False, 5) crossfadebox.pack_start(crossfadelabel3, False, False, 0) crossfadecheck.connect('toggled', self.prefs_crossfadecheck_toggled, crossfadespin, crossfadelabel2, crossfadelabel3) as_table.attach(as_user_label, 0, 1, 0, 1) as_table.attach(as_user_entry, 1, 2, 0, 1) as_table.attach(as_pass_label, 0, 1, 1, 2) as_table.attach(as_pass_entry, 1, 2, 1, 2) as_table.attach(ui.label(), 0, 2, 2, 3) as_table.attach(display_notification, 0, 2, 3, 4) as_table.attach(notifhbox, 0, 2, 4, 5) as_table.attach(ui.label(), 0, 2, 5, 6) as_table.attach(crossfadecheck, 0, 2, 6, 7) as_table.attach(crossfadebox, 0, 2, 7, 8) as_table.attach(ui.label(), 0, 2, 8, 9) as_vbox.pack_start(as_table, False) as_frame.add(as_vbox) as_checkbox.connect('toggled', self.prefs_as_enabled_toggled, as_user_entry, as_pass_entry, as_user_label, as_pass_label) if not self.as_enabled or not as_imported: as_user_entry.set_sensitive(False) as_pass_entry.set_sensitive(False) as_user_label.set_sensitive(False) as_pass_label.set_sensitive(False) # Display tab table2 = gtk.Table(7, 2, False) displaylabel = ui.label(markup='<b>' + _('Display') + '</b>', y=1) display_art_hbox = gtk.HBox() display_art = gtk.CheckButton(_("Enable album art")) display_art.set_active(self.show_covers) display_stylized_combo = ui.combo(items=[_("Standard"), _("Stylized")], active=self.covers_type, changed_cb=prefs_stylized_toggled) display_stylized_hbox = gtk.HBox() display_stylized_hbox.pack_start(ui.label(text=_("Artwork style:"), x=1)) display_stylized_hbox.pack_start(display_stylized_combo, False, False, 5) display_stylized_hbox.set_sensitive(self.show_covers) display_art_combo = ui.combo(items=[_("Local only"), _("Local and remote")], active=self.covers_pref) orderart_label = ui.label(text=_("Search locations:"), x=1) display_art_hbox.pack_start(orderart_label) display_art_hbox.pack_start(display_art_combo, False, False, 5) display_art_hbox.set_sensitive(self.show_covers) display_art_location_hbox = gtk.HBox() display_art_location_hbox.pack_start(ui.label(text=_("Save art to:"), x=1)) art_paths = ["~/.covers/"] for item in ["/cover.jpg", "/album.jpg", "/folder.jpg", "/" + _("custom")]: art_paths.append("../" + _("file_path") + item) display_art_location = ui.combo(items=art_paths, active=self.art_location, changed_cb=self.prefs_art_location_changed) display_art_location_hbox.pack_start(display_art_location, False, False, 5) display_art_location_hbox.set_sensitive(self.show_covers) display_art.connect('toggled', prefs_art_toggled, display_art_hbox, display_art_location_hbox, display_stylized_hbox) display_playback = gtk.CheckButton(_("Enable playback/volume buttons")) display_playback.set_active(self.show_playback) display_playback.connect('toggled', prefs_playback_toggled) display_progress = gtk.CheckButton(_("Enable progressbar")) display_progress.set_active(self.show_progress) display_progress.connect('toggled', prefs_progress_toggled) display_statusbar = gtk.CheckButton(_("Enable statusbar")) display_statusbar.set_active(self.show_statusbar) display_statusbar.connect('toggled', prefs_statusbar_toggled) display_lyrics = gtk.CheckButton(_("Enable lyrics")) display_lyrics.set_active(self.show_lyrics) display_lyrics_location_hbox = gtk.HBox() savelyrics_label = ui.label(text=_("Save lyrics to:"), x=1) display_lyrics_location_hbox.pack_start(savelyrics_label) display_lyrics_location = ui.combo(items=["~/.lyrics/", "../" + _("file_path") + "/"], active=self.lyrics_location, changed_cb=self.prefs_lyrics_location_changed) display_lyrics_location_hbox.pack_start(display_lyrics_location, False, False, 5) display_lyrics_location_hbox.set_sensitive(self.show_lyrics) display_lyrics.connect('toggled', prefs_lyrics_toggled, display_lyrics_location_hbox) display_trayicon = gtk.CheckButton(_("Enable system tray icon")) display_trayicon.set_active(self.show_trayicon) display_trayicon.set_sensitive(trayicon_available) table2.attach(ui.label(), 1, 3, 1, 2, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0) table2.attach(displaylabel, 1, 3, 2, 3, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0) table2.attach(ui.label(), 1, 3, 3, 4, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0) table2.attach(display_playback, 1, 3, 4, 5, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) table2.attach(display_progress, 1, 3, 5, 6, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) table2.attach(display_statusbar, 1, 3, 6, 7, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) table2.attach(display_trayicon, 1, 3, 7, 8, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) table2.attach(display_lyrics, 1, 3, 8, 9, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) table2.attach(display_lyrics_location_hbox, 1, 3, 9, 10, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) table2.attach(display_art, 1, 3, 10, 11, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) table2.attach(display_stylized_hbox, 1, 3, 11, 12, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) table2.attach(display_art_hbox, 1, 3, 12, 13, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) table2.attach(display_art_location_hbox, 1, 3, 13, 14, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) table2.attach(ui.label(), 1, 3, 14, 15, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 75, 0) # Behavior tab table3 = gtk.Table() behaviorlabel = ui.label(markup='<b>' + _('Window Behavior') + '</b>', y=1) win_sticky = gtk.CheckButton(_("Show window on all workspaces")) win_sticky.set_active(self.sticky) win_ontop = gtk.CheckButton(_("Keep window above other windows")) win_ontop.set_active(self.ontop) update_start = gtk.CheckButton(_("Update MPD library on start")) update_start.set_active(self.update_on_start) update_start.set_tooltip_text(_("If enabled, Sonata will automatically update your MPD library when it starts up.")) exit_stop = gtk.CheckButton(_("Stop playback on exit")) exit_stop.set_active(self.stop_on_exit) exit_stop.set_tooltip_text(_("MPD allows playback even when the client is not open. If enabled, Sonata will behave like a more conventional music player and, instead, stop playback upon exit.")) minimize = gtk.CheckButton(_("Minimize to system tray on close/escape")) minimize.set_active(self.minimize_to_systray) minimize.set_tooltip_text(_("If enabled, closing Sonata will minimize it to the system tray. Note that it's currently impossible to detect if there actually is a system tray, so only check this if you have one.")) display_trayicon.connect('toggled', prefs_trayicon_toggled, minimize) minimize.set_sensitive(trayicon_in_use) infofilebox = gtk.HBox() infofile_usage = gtk.CheckButton(_("Write status file:")) infofile_usage.set_active(self.use_infofile) infofile_usage.set_tooltip_text(_("If enabled, Sonata will create a xmms-infopipe like file containing information about the current song. Many applications support the xmms-info file (Instant Messengers, IRC Clients...)")) infopath_options = ui.entry(text=self.infofile_path) infopath_options.set_tooltip_text(_("If enabled, Sonata will create a xmms-infopipe like file containing information about the current song. Many applications support the xmms-info file (Instant Messengers, IRC Clients...)")) if not self.use_infofile: infopath_options.set_sensitive(False) infofile_usage.connect('toggled', self.prefs_infofile_toggled, infopath_options) infofilebox.pack_start(infofile_usage, False, False, 0) infofilebox.pack_start(infopath_options, True, True, 5) behaviorlabel2 = ui.label(markup='<b>' + _('Miscellaneous') + '</b>', y=1) table3.attach(ui.label(), 1, 3, 1, 2, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0) table3.attach(behaviorlabel, 1, 3, 2, 3, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0) table3.attach(ui.label(), 1, 3, 3, 4, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0) table3.attach(win_sticky, 1, 3, 4, 5, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) table3.attach(win_ontop, 1, 3, 5, 6, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) table3.attach(minimize, 1, 3, 6, 7, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) table3.attach(ui.label(), 1, 3, 7, 8, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0) table3.attach(behaviorlabel2, 1, 3, 8, 9, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0) table3.attach(ui.label(), 1, 3, 9, 10, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0) table3.attach(update_start, 1, 3, 10, 11, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) table3.attach(exit_stop, 1, 3, 11, 12, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) table3.attach(infofilebox, 1, 3, 12, 13, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) table3.attach(ui.label(), 1, 3, 13, 14, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) table3.attach(ui.label(), 1, 3, 14, 15, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) table3.attach(ui.label(), 1, 3, 15, 16, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) table3.attach(ui.label(), 1, 3, 16, 17, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) table3.attach(ui.label(), 1, 3, 17, 18, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) table3.attach(ui.label(), 1, 3, 18, 19, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) # Format tab table4 = gtk.Table(9, 2, False) table4.set_col_spacings(3) formatlabel = ui.label(markup='<b>' + _('Song Formatting') + '</b>', y=1) currentformatbox = gtk.HBox() currentlabel = ui.label(text=_("Current playlist:")) currentoptions = ui.entry(text=self.currentformat) currentformatbox.pack_start(currentlabel, False, False, 0) currentformatbox.pack_start(currentoptions, False, False, 10) libraryformatbox = gtk.HBox() librarylabel = ui.label(text=_("Library:")) libraryoptions = ui.entry(text=self.libraryformat) libraryformatbox.pack_start(librarylabel, False, False, 0) libraryformatbox.pack_start(libraryoptions, False, False, 10) titleformatbox = gtk.HBox() titlelabel = ui.label(text=_("Window title:")) titleoptions = ui.entry(text=self.titleformat) titleoptions.set_text(self.titleformat) titleformatbox.pack_start(titlelabel, False, False, 0) titleformatbox.pack_start(titleoptions, False, False, 10) currsongformatbox1 = gtk.HBox() currsonglabel1 = ui.label(text=_("Current song line 1:")) currsongoptions1 = ui.entry(text=self.currsongformat1) currsongformatbox1.pack_start(currsonglabel1, False, False, 0) currsongformatbox1.pack_start(currsongoptions1, False, False, 10) currsongformatbox2 = gtk.HBox() currsonglabel2 = ui.label(text=_("Current song line 2:")) currsongoptions2 = ui.entry(text=self.currsongformat2) currsongformatbox2.pack_start(currsonglabel2, False, False, 0) currsongformatbox2.pack_start(currsongoptions2, False, False, 10) formatlabels = [currentlabel, librarylabel, titlelabel, currsonglabel1, currsonglabel2] for label in formatlabels: label.set_alignment(0, 0.5) ui.set_widths_equal(formatlabels) availableheading = ui.label(markup='<small>' + _('Available options') + ':</small>', y=0) availablevbox = gtk.VBox() availableformatbox = gtk.HBox() availableformatting = ui.label(markup='<small><span font_family="Monospace">%A</span> - ' + _('Artist name') + '\n<span font_family="Monospace">%B</span> - ' + _('Album name') + '\n<span font_family="Monospace">%T</span> - ' + _('Track name') + '\n<span font_family="Monospace">%N</span> - ' + _('Track number') + '\n<span font_family="Monospace">%D</span> - ' + _('Disc Number') + '\n<span font_family="Monospace">%Y</span> - ' + _('Year') + '</small>', y=0) availableformatting2 = ui.label(markup='<small><span font_family="Monospace">%G</span> - ' + _('Genre') + '\n<span font_family="Monospace">%F</span> - ' + _('File name') + '\n<span font_family="Monospace">%S</span> - ' + _('Stream name') + '\n<span font_family="Monospace">%L</span> - ' + _('Song length') + '\n<span font_family="Monospace">%E</span> - ' + _('Elapsed time (title only)') + '</small>', y=0) availableformatbox.pack_start(availableformatting) availableformatbox.pack_start(availableformatting2) availablevbox.pack_start(availableformatbox, False, False, 0) additionalinfo = ui.label(markup='<small>{ } - ' + _('Info displayed only if all enclosed tags are defined') + '\n' + '| - ' + _('Creates columns in the current playlist') + '</small>', y=0) availablevbox.pack_start(additionalinfo, False, False, 4) table4.attach(ui.label(), 1, 3, 1, 2, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0) table4.attach(formatlabel, 1, 3, 2, 3, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0) table4.attach(ui.label(), 1, 3, 3, 4, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0) table4.attach(currentformatbox, 1, 3, 4, 5, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) table4.attach(libraryformatbox, 1, 3, 5, 6, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) table4.attach(titleformatbox, 1, 3, 6, 7, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) table4.attach(currsongformatbox1, 1, 3, 7, 8, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) table4.attach(currsongformatbox2, 1, 3, 8, 9, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) table4.attach(ui.label(), 1, 3, 9, 10, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) table4.attach(availableheading, 1, 3, 10, 11, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) table4.attach(availablevbox, 1, 3, 11, 12, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 45, 0) table4.attach(ui.label(), 1, 3, 12, 13, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0) table_names = [[_("_MPD"), mpd_table], [_("_Display"), table2], [_("_Behavior"), table3], [_("_Format"), table4], [_("_Extras"), as_frame]] for table_name in table_names: tmplabel = ui.label(textmn=table_name[0]) prefsnotebook.append_page(table_name[1], tmplabel) hbox.pack_start(prefsnotebook, False, False, 10) prefswindow.vbox.pack_start(hbox, False, False, 10) close_button = prefswindow.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE) prefswindow.show_all() close_button.grab_focus() prefswindow.connect('response', prefs_window_response, prefsnotebook, exit_stop, win_ontop, display_art_combo, win_sticky, direntry, minimize, update_start, autoconnect, currentoptions, libraryoptions, titleoptions, currsongoptions1, currsongoptions2, crossfadecheck, crossfadespin, infopath_options, using_mpd_env_vars, self.prev_host, self.prev_port, self.prev_password) # Save previous connection properties to determine if we should try to # connect to MPD after prefs are closed: self.prev_host = self.host[self.profile_num] self.prev_port = self.port[self.profile_num] self.prev_password = self.password[self.profile_num] prefswindow.show()
def widgets_initialize(self, info_scrollwindow): vert_spacing = 1 horiz_spacing = 2 margin = 5 outter_hbox = gtk.HBox() outter_vbox = gtk.VBox() # Song info info_song = ui.expander(markup="<b>" + _("Song Info") + "</b>", expand=self.config.info_song_expanded, can_focus=False) info_song.connect("activate", self.info_expanded, "song") inner_hbox = gtk.HBox() inner_hbox.pack_start(self.info_imagebox, False, False, horiz_spacing) self.info_tagbox = gtk.VBox() labels_left = [] self.info_type = {} self.info_labels = [] self.info_boxes_in_more = [] labels_type = [ 'title', 'artist', 'album', 'date', 'track', 'genre', 'file', 'bitrate' ] labels_text = [ _("Title"), _("Artist"), _("Album"), _("Date"), _("Track"), _("Genre"), _("File"), _("Bitrate") ] labels_link = [False, True, True, False, False, False, False, False] labels_tooltip = [ "", _("Launch artist in Wikipedia"), _("Launch album in Wikipedia"), "", "", "", "", "" ] labels_in_more = [False, False, False, False, False, False, True, True] for i in range(len(labels_text)): self.info_type[labels_text[i]] = i tmphbox = gtk.HBox() if labels_in_more[i]: self.info_boxes_in_more += [tmphbox] tmplabel = ui.label(markup="<b>" + labels_text[i] + ":</b>", y=0) if i == 0: self.info_left_label = tmplabel if not labels_link[i]: tmplabel2 = ui.label(wrap=True, y=0, select=True) else: # Using set_selectable overrides the hover cursor that sonata # tries to set for the links, and I can't figure out how to # stop that. So we'll disable set_selectable for these two # labels until it's figured out. tmplabel2 = ui.label(wrap=True, y=0, select=False) if labels_link[i]: tmpevbox = ui.eventbox(add=tmplabel2) self.info_apply_link_signals(tmpevbox, labels_type[i], labels_tooltip[i]) tmphbox.pack_start(tmplabel, False, False, horiz_spacing) if labels_link[i]: tmphbox.pack_start(tmpevbox, False, False, horiz_spacing) else: tmphbox.pack_start(tmplabel2, False, False, horiz_spacing) self.info_labels += [tmplabel2] labels_left += [tmplabel] self.info_tagbox.pack_start(tmphbox, False, False, vert_spacing) ui.set_widths_equal(labels_left) mischbox = gtk.HBox() self.info_morelabel = ui.label(y=0) moreevbox = ui.eventbox(add=self.info_morelabel) self.info_apply_link_signals(moreevbox, 'more', _("Toggle extra tags")) self.info_editlabel = ui.label(y=0) editevbox = ui.eventbox(add=self.info_editlabel) self.info_apply_link_signals(editevbox, 'edit', _("Edit song tags")) mischbox.pack_start(moreevbox, False, False, horiz_spacing) mischbox.pack_start(editevbox, False, False, horiz_spacing) self.info_tagbox.pack_start(mischbox, False, False, vert_spacing) inner_hbox.pack_start(self.info_tagbox, False, False, horiz_spacing) info_song.add(inner_hbox) outter_vbox.pack_start(info_song, False, False, margin) # Lyrics self.info_lyrics = ui.expander(markup="<b>" + _("Lyrics") + "</b>", expand=self.config.info_lyrics_expanded, can_focus=False) self.info_lyrics.connect("activate", self.info_expanded, "lyrics") lyricsbox = gtk.VBox() lyricsbox_top = gtk.HBox() self.lyricsText = ui.label(markup=" ", y=0, select=True, wrap=True) lyricsbox_top.pack_start(self.lyricsText, True, True, horiz_spacing) lyricsbox.pack_start(lyricsbox_top, True, True, vert_spacing) lyricsbox_bottom = gtk.HBox() self.info_searchlabel = ui.label(y=0) self.info_editlyricslabel = ui.label(y=0) searchevbox = ui.eventbox(add=self.info_searchlabel) editlyricsevbox = ui.eventbox(add=self.info_editlyricslabel) self.info_apply_link_signals(searchevbox, 'search', _("Search Lyricwiki.org for lyrics")) self.info_apply_link_signals(editlyricsevbox, 'editlyrics', _("Edit lyrics at Lyricwiki.org")) lyricsbox_bottom.pack_start(searchevbox, False, False, horiz_spacing) lyricsbox_bottom.pack_start(editlyricsevbox, False, False, horiz_spacing) lyricsbox.pack_start(lyricsbox_bottom, False, False, vert_spacing) self.info_lyrics.add(lyricsbox) outter_vbox.pack_start(self.info_lyrics, False, False, margin) # Album info info_album = ui.expander(markup="<b>" + _("Album Info") + "</b>", expand=self.config.info_album_expanded, can_focus=False) info_album.connect("activate", self.info_expanded, "album") albumbox = gtk.VBox() albumbox_top = gtk.HBox() self.albumText = ui.label(markup=" ", y=0, select=True, wrap=True) albumbox_top.pack_start(self.albumText, False, False, horiz_spacing) albumbox.pack_start(albumbox_top, False, False, vert_spacing) info_album.add(albumbox) outter_vbox.pack_start(info_album, False, False, margin) # Finish.. if not self.config.show_lyrics: ui.hide(self.info_lyrics) if not self.config.show_covers: ui.hide(self.info_imagebox) # self.config.info_song_more will be overridden on on_link_click, so # store it in a temporary var.. temp = self.config.info_song_more self.on_link_click(moreevbox, None, 'more') self.config.info_song_more = temp if self.config.info_song_more: self.on_link_click(moreevbox, None, 'more') outter_hbox.pack_start(outter_vbox, False, False, margin) info_scrollwindow.add_with_viewport(outter_hbox)
def format_tab(self, cbs): """Construct and layout the format tab""" formatlabel = ui.label(markup='<b>'+_('Song Formatting')+'</b>') frame = gtk.Frame() frame.set_label_widget(formatlabel) frame.set_shadow_type(gtk.SHADOW_NONE) rows = [(_("C_urrent playlist:"), self.config.currentformat), (_("_Library:"), self.config.libraryformat), (_("_Window title:"), self.config.titleformat), (_("Current _song line 1:"), self.config.currsongformat1), (_("Current s_ong line 2:"), self.config.currsongformat2)] labels = [] entries = [] for label_text, entry_text in rows: label = ui.label(textmn=label_text) entry = ui.entry(text=entry_text) label.set_mnemonic_widget(entry) labels.append(label) entries.append(entry) entry_cbs = (cbs.currentoptions_changed, cbs.libraryoptions_changed, cbs.titleoptions_changed, cbs.currsongoptions1_changed, cbs.currsongoptions2_changed) for entry, cb, next in zip(entries, entry_cbs, entries[1:] + entries[:1]): entry.connect('focus_out_event', cb) entry.connect('activate', lambda _, n: n.grab_focus(), next) availableheading = ui.label(markup='<small>' + _('Available options') + ':</small>') availablevbox = gtk.VBox() availableformatbox = gtk.HBox() formatcodes = formatting.formatcodes for codes in [formatcodes[:(len(formatcodes)+1)/2], formatcodes[(len(formatcodes)+1)/2:]]: rows = '\n'.join('<tt>%%%s</tt> - %s' % (code.code, code.description) for code in codes) markup = '<small>' + rows + '</small>' formattinghelp = ui.label(markup=markup) availableformatbox.pack_start(formattinghelp) availablevbox.pack_start(availableformatbox, False, False, 0) additionalinfo = ui.label(markup='<small><tt>{ }</tt> - ' + _('Info displayed only if all enclosed tags are defined') + '\n<tt>|</tt> - ' + _('Creates columns in the current playlist') + '</small>') availablevbox.pack_start(additionalinfo, False, False, 4) num_rows = len(rows) + 2 table = gtk.Table(num_rows, 2) table.set_col_spacings(12) label_entries = enumerate(zip(labels, entries)) for i, (label, entry) in label_entries: table.attach(label, 0, 1, i, i+1, gtk.FILL) table.attach(entry, 1, 2, i, i+1) table.attach(availableheading, 0, 2, num_rows-2, num_rows-1, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 0, 6) table.attach(availablevbox, 0, 2, num_rows-1, num_rows) alignment = gtk.Alignment(0.5, 0.5, 1.0, 1.0) alignment.set_padding(12, 0, 12, 0) alignment.add(table) frame.add(alignment) tab = gtk.Alignment(0.5, 0.5, 1.0, 1.0) tab.set_padding(12, 12, 12, 12) tab.add(frame) return tab
def __init__(self, config, find_path, is_lang_rtl, info_imagebox_get_size_request, schedule_gc_collect, target_image_filename, imagelist_append, remotefilelist_append, notebook_get_allocation, allow_art_search, status_is_play_or_pause, album_filename, get_current_song_text): self.config = config self.album_filename = album_filename # constants from main self.is_lang_rtl = is_lang_rtl # callbacks to main XXX refactor to clear this list self.info_imagebox_get_size_request = info_imagebox_get_size_request self.schedule_gc_collect = schedule_gc_collect self.target_image_filename = target_image_filename self.imagelist_append = imagelist_append self.remotefilelist_append = remotefilelist_append self.notebook_get_allocation = notebook_get_allocation self.allow_art_search = allow_art_search self.status_is_play_or_pause = status_is_play_or_pause self.get_current_song_text = get_current_song_text # local pixbufs, image file names self.sonatacd = find_path('sonatacd.png') self.sonatacd_large = find_path('sonatacd_large.png') self.casepb = gtk.gdk.pixbuf_new_from_file( find_path('sonata-case.png')) self.albumpb = None self.currentpb = None # local UI widgets provided to main by getter methods self.albumimage = ui.image() self.albumimage.set_from_file(self.sonatacd) self.trayalbumimage1 = ui.image(w=51, h=77, x=1) self.trayalbumeventbox = ui.eventbox(w=59, h=90, add=self.trayalbumimage1, state=gtk.STATE_SELECTED, visible=True) self.trayalbumimage2 = ui.image(w=26, h=77) self.fullscreenalbumimage = ui.image(w=consts.FULLSCREEN_COVER_SIZE, h=consts.FULLSCREEN_COVER_SIZE, x=1) self.fullscreenalbumlabel = ui.label(x=0.5) self.fullscreenalbumlabel2 = ui.label(x=0.5) self.fullscreen_cover_art_reset_image() self.fullscreen_cover_art_reset_text() self.info_image = ui.image(y=0) self.info_image.set_from_file(self.sonatacd_large) # local version of Main.songinfo mirrored by update_songinfo self.songinfo = None # local state self.lastalbumart = None self.single_img_in_dir = None self.misc_img_in_dir = None self.stop_art_update = False self.downloading_image = False self.lib_art_cond = None # local artwork, cache for library self.lib_model = None self.lib_art_rows_local = [] self.lib_art_rows_remote = [] self.lib_art_pb_size = 0 self.cache = {} self.artwork_load_cache()
def __init__(self, config, client, TAB_CURRENT, on_current_button_press, parse_formatting_colnames, parse_formatting, connected, sonata_loaded, songinfo, update_statusbar, iterate_now, libsearchfilter_get_style, new_tab): self.config = config self.client = client self.on_current_button_press = on_current_button_press self.parse_formatting_colnames = parse_formatting_colnames self.parse_formatting = parse_formatting self.connected = connected self.sonata_loaded = sonata_loaded self.songinfo = songinfo self.update_statusbar = update_statusbar self.iterate_now = iterate_now self.libsearchfilter_get_style = libsearchfilter_get_style self.currentdata = None self.filterbox_visible = False self.current_update_skip = False self.filter_row_mapping = [ ] # Mapping between filter rows and self.currentdata rows self.columnformat = None self.columns = None self.current_songs = None self.filterbox_cmd_buf = None self.filterbox_cond = None self.filterbox_source = None self.column_sorted = (None, gtk.SORT_DESCENDING ) # TreeViewColumn, order self.total_time = 0 self.edit_style_orig = None self.resizing_columns = None self.prev_boldrow = -1 self.prevtodo = None self.plpos = None self.playlist_pos_before_filter = None self.sel_rows = None # Current tab self.current = ui.treeview(reorder=True, search=False, headers=True) self.current_selection = self.current.get_selection() self.expanderwindow = ui.scrollwindow(shadow=gtk.SHADOW_IN, add=self.current) self.filterpattern = ui.entry() self.filterbox = gtk.HBox() self.filterbox.pack_start(ui.label(text=_("Filter") + ":"), False, False, 5) self.filterbox.pack_start(self.filterpattern, True, True, 5) filterclosebutton = ui.button(img=ui.image(stock=gtk.STOCK_CLOSE), relief=gtk.RELIEF_NONE) self.filterbox.pack_start(filterclosebutton, False, False, 0) self.filterbox.set_no_show_all(True) self.vbox_current = gtk.VBox() self.vbox_current.pack_start(self.expanderwindow, True, True) self.vbox_current.pack_start(self.filterbox, False, False, 5) self.tab = new_tab(self.vbox_current, gtk.STOCK_CDROM, TAB_CURRENT, self.current) self.current.connect('drag_data_received', self.on_dnd) self.current.connect('row_activated', self.on_current_click) self.current.connect('button_press_event', self.on_current_button_press) self.current.connect('drag-begin', self.on_current_drag_begin) self.current.connect_after('drag-begin', self.dnd_after_current_drag_begin) self.current.connect('button_release_event', self.on_current_button_release) self.filter_changed_handler = self.filterpattern.connect( 'changed', self.searchfilter_feed_loop) self.filterpattern.connect('activate', self.searchfilter_on_enter) self.filterpattern.connect('key-press-event', self.searchfilter_key_pressed) filterclosebutton.connect('clicked', self.searchfilter_toggle) # Set up current view self.initialize_columns() self.current_selection.set_mode(gtk.SELECTION_MULTIPLE) target_reorder = ('MY_TREE_MODEL_ROW', gtk.TARGET_SAME_WIDGET, 0) target_file_managers = ('text/uri-list', 0, 0) self.current.enable_model_drag_source( gtk.gdk.BUTTON1_MASK, [target_reorder, target_file_managers], gtk.gdk.ACTION_COPY | gtk.gdk.ACTION_DEFAULT) self.current.enable_model_drag_dest( [target_reorder, target_file_managers], gtk.gdk.ACTION_MOVE | gtk.gdk.ACTION_DEFAULT) self.current.connect('drag-data-get', self.dnd_get_data_for_file_managers)
def widgets_initialize(self, info_scrollwindow): vert_spacing = 1 horiz_spacing = 2 margin = 5 outter_hbox = gtk.HBox() outter_vbox = gtk.VBox() # Song info info_song = ui.expander(markup="<b>" + _("Song Info") + "</b>", expand=self.config.info_song_expanded, can_focus=False) info_song.connect("activate", self.info_expanded, "song") inner_hbox = gtk.HBox() inner_hbox.pack_start(self.info_imagebox, False, False, horiz_spacing) self.info_tagbox = gtk.VBox() labels_left = [] self.info_type = {} self.info_labels = [] self.info_boxes_in_more = [] labels_type = ['title', 'artist', 'album', 'date', 'track', 'genre', 'file', 'bitrate'] labels_text = [_("Title"), _("Artist"), _("Album"), _("Date"), _("Track"), _("Genre"), _("File"), _("Bitrate")] labels_link = [False, True, True, False, False, False, False, False] labels_tooltip = ["", _("Launch artist in Wikipedia"), _("Launch album in Wikipedia"), "", "", "", "", ""] labels_in_more = [False, False, False, False, False, False, True, True] for i in range(len(labels_text)): self.info_type[labels_text[i]] = i tmphbox = gtk.HBox() if labels_in_more[i]: self.info_boxes_in_more += [tmphbox] tmplabel = ui.label(markup="<b>" + labels_text[i] + ":</b>", y=0) if i == 0: self.info_left_label = tmplabel if not labels_link[i]: tmplabel2 = ui.label(wrap=True, y=0, select=True) else: # Using set_selectable overrides the hover cursor that sonata # tries to set for the links, and I can't figure out how to # stop that. So we'll disable set_selectable for these two # labels until it's figured out. tmplabel2 = ui.label(wrap=True, y=0, select=False) if labels_link[i]: tmpevbox = ui.eventbox(add=tmplabel2) self.info_apply_link_signals(tmpevbox, labels_type[i], labels_tooltip[i]) tmphbox.pack_start(tmplabel, False, False, horiz_spacing) if labels_link[i]: tmphbox.pack_start(tmpevbox, False, False, horiz_spacing) else: tmphbox.pack_start(tmplabel2, False, False, horiz_spacing) self.info_labels += [tmplabel2] labels_left += [tmplabel] self.info_tagbox.pack_start(tmphbox, False, False, vert_spacing) ui.set_widths_equal(labels_left) mischbox = gtk.HBox() self.info_morelabel = ui.label(y=0) moreevbox = ui.eventbox(add=self.info_morelabel) self.info_apply_link_signals(moreevbox, 'more', _("Toggle extra tags")) self.info_editlabel = ui.label(y=0) editevbox = ui.eventbox(add=self.info_editlabel) self.info_apply_link_signals(editevbox, 'edit', _("Edit song tags")) mischbox.pack_start(moreevbox, False, False, horiz_spacing) mischbox.pack_start(editevbox, False, False, horiz_spacing) self.info_tagbox.pack_start(mischbox, False, False, vert_spacing) inner_hbox.pack_start(self.info_tagbox, False, False, horiz_spacing) info_song.add(inner_hbox) outter_vbox.pack_start(info_song, False, False, margin) # Lyrics self.info_lyrics = ui.expander(markup="<b>" + _("Lyrics") + "</b>", expand=self.config.info_lyrics_expanded, can_focus=False) self.info_lyrics.connect("activate", self.info_expanded, "lyrics") lyricsbox = gtk.VBox() lyricsbox_top = gtk.HBox() self.lyricsText = ui.label(markup=" ", y=0, select=True, wrap=True) lyricsbox_top.pack_start(self.lyricsText, True, True, horiz_spacing) lyricsbox.pack_start(lyricsbox_top, True, True, vert_spacing) lyricsbox_bottom = gtk.HBox() self.info_searchlabel = ui.label(y=0) self.info_editlyricslabel = ui.label(y=0) searchevbox = ui.eventbox(add=self.info_searchlabel) editlyricsevbox = ui.eventbox(add=self.info_editlyricslabel) self.info_apply_link_signals(searchevbox, 'search', _("Search Lyricwiki.org for lyrics")) self.info_apply_link_signals(editlyricsevbox, 'editlyrics', _("Edit lyrics at Lyricwiki.org")) lyricsbox_bottom.pack_start(searchevbox, False, False, horiz_spacing) lyricsbox_bottom.pack_start(editlyricsevbox, False, False, horiz_spacing) lyricsbox.pack_start(lyricsbox_bottom, False, False, vert_spacing) self.info_lyrics.add(lyricsbox) outter_vbox.pack_start(self.info_lyrics, False, False, margin) # Album info info_album = ui.expander(markup="<b>" + _("Album Info") + "</b>", expand=self.config.info_album_expanded, can_focus=False) info_album.connect("activate", self.info_expanded, "album") albumbox = gtk.VBox() albumbox_top = gtk.HBox() self.albumText = ui.label(markup=" ", y=0, select=True, wrap=True) albumbox_top.pack_start(self.albumText, False, False, horiz_spacing) albumbox.pack_start(albumbox_top, False, False, vert_spacing) info_album.add(albumbox) outter_vbox.pack_start(info_album, False, False, margin) # Finish.. if not self.config.show_lyrics: ui.hide(self.info_lyrics) if not self.config.show_covers: ui.hide(self.info_imagebox) # self.config.info_song_more will be overridden on on_link_click, so # store it in a temporary var.. temp = self.config.info_song_more self.on_link_click(moreevbox, None, 'more') self.config.info_song_more = temp if self.config.info_song_more: self.on_link_click(moreevbox, None, 'more') outter_hbox.pack_start(outter_vbox, False, False, margin) info_scrollwindow.add_with_viewport(outter_hbox)
def widgets_initialize(self, info_scrollwindow): vert_spacing = 1 horiz_spacing = 2 margin = 5 outter_hbox = gtk.HBox() outter_vbox = gtk.VBox() # Song info info_song = ui.expander( markup="<b>" + _("Song Info") + "</b>", expand=self.config.info_song_expanded, can_focus=False ) info_song.connect("activate", self.info_expanded, "song") inner_hbox = gtk.HBox() inner_hbox.pack_start(self.info_imagebox, False, False, horiz_spacing) self.info_tagbox = gtk.VBox() labels_left = [] self.info_type = {} self.info_labels = [] self.info_boxes_in_more = [] labels = [ (_("Title"), "title", False, "", False), (_("Artist"), "artist", True, _("Launch artist in Wikipedia"), False), (_("Album"), "album", True, _("Launch album in Wikipedia"), False), (_("Date"), "date", False, "", False), (_("Track"), "track", False, "", False), (_("Genre"), "genre", False, "", False), (_("File"), "file", False, "", True), (_("Bitrate"), "bitrate", False, "", True), ] for i, (text, name, link, tooltip, in_more) in enumerate(labels): self.info_type[name] = i tmphbox = gtk.HBox() if in_more: self.info_boxes_in_more += [tmphbox] tmplabel = ui.label(markup="<b>%s:</b>" % text, y=0) if i == 0: self.info_left_label = tmplabel # Using set_selectable overrides the hover cursor that # sonata tries to set for the links, and I can't figure # out how to stop that. So we'll disable set_selectable # for those labels until it's figured out. tmplabel2 = ui.label(wrap=True, y=0, select=not link) if link: tmpevbox = ui.eventbox(add=tmplabel2) self.info_apply_link_signals(tmpevbox, name, tooltip) tmphbox.pack_start(tmplabel, False, False, horiz_spacing) to_pack = tmpevbox if link else tmplabel2 tmphbox.pack_start(to_pack, False, False, horiz_spacing) self.info_labels += [tmplabel2] labels_left += [tmplabel] self.info_tagbox.pack_start(tmphbox, False, False, vert_spacing) ui.set_widths_equal(labels_left) mischbox = gtk.HBox() self.info_morelabel = ui.label(y=0) moreevbox = ui.eventbox(add=self.info_morelabel) self.info_apply_link_signals(moreevbox, "more", _("Toggle extra tags")) self.info_editlabel = ui.label(y=0) editevbox = ui.eventbox(add=self.info_editlabel) self.info_apply_link_signals(editevbox, "edit", _("Edit song tags")) mischbox.pack_start(moreevbox, False, False, horiz_spacing) mischbox.pack_start(editevbox, False, False, horiz_spacing) self.info_tagbox.pack_start(mischbox, False, False, vert_spacing) inner_hbox.pack_start(self.info_tagbox, False, False, horiz_spacing) info_song.add(inner_hbox) outter_vbox.pack_start(info_song, False, False, margin) # Lyrics self.info_lyrics = ui.expander( markup="<b>" + _("Lyrics") + "</b>", expand=self.config.info_lyrics_expanded, can_focus=False ) self.info_lyrics.connect("activate", self.info_expanded, "lyrics") lyricsbox = gtk.VBox() lyricsbox_top = gtk.HBox() self.lyricsText = ui.label(markup=" ", y=0, select=True, wrap=True) lyricsbox_top.pack_start(self.lyricsText, True, True, horiz_spacing) lyricsbox.pack_start(lyricsbox_top, True, True, vert_spacing) lyricsbox_bottom = gtk.HBox() self.info_searchlabel = ui.label(y=0) self.info_editlyricslabel = ui.label(y=0) searchevbox = ui.eventbox(add=self.info_searchlabel) editlyricsevbox = ui.eventbox(add=self.info_editlyricslabel) self.info_apply_link_signals(searchevbox, "search", _("Search Lyricwiki.org for lyrics")) self.info_apply_link_signals(editlyricsevbox, "editlyrics", _("Edit lyrics at Lyricwiki.org")) lyricsbox_bottom.pack_start(searchevbox, False, False, horiz_spacing) lyricsbox_bottom.pack_start(editlyricsevbox, False, False, horiz_spacing) lyricsbox.pack_start(lyricsbox_bottom, False, False, vert_spacing) self.info_lyrics.add(lyricsbox) outter_vbox.pack_start(self.info_lyrics, False, False, margin) # Album info info_album = ui.expander( markup="<b>" + _("Album Info") + "</b>", expand=self.config.info_album_expanded, can_focus=False ) info_album.connect("activate", self.info_expanded, "album") albumbox = gtk.VBox() albumbox_top = gtk.HBox() self.albumText = ui.label(markup=" ", y=0, select=True, wrap=True) albumbox_top.pack_start(self.albumText, False, False, horiz_spacing) albumbox.pack_start(albumbox_top, False, False, vert_spacing) info_album.add(albumbox) outter_vbox.pack_start(info_album, False, False, margin) # Finish.. if not self.config.show_lyrics: ui.hide(self.info_lyrics) if not self.config.show_covers: ui.hide(self.info_imagebox) # self.config.info_song_more will be overridden on on_link_click, so # store it in a temporary var.. temp = self.config.info_song_more self.on_link_click(moreevbox, None, "more") self.config.info_song_more = temp if self.config.info_song_more: self.on_link_click(moreevbox, None, "more") outter_hbox.pack_start(outter_vbox, False, False, margin) info_scrollwindow.add_with_viewport(outter_hbox)
def __init__(self, config, client, artwork, TAB_LIBRARY, album_filename, settings_save, filtering_entry_make_red, filtering_entry_revert_color, filter_key_pressed, on_add_item, parse_formatting, connected, on_library_button_press, on_library_search_text_click): self.artwork = artwork self.config = config self.client = client self.librarymenu = None # cyclic dependency, set later self.TAB_LIBRARY = TAB_LIBRARY self.album_filename = album_filename self.settings_save = settings_save self.filtering_entry_make_red = filtering_entry_make_red self.filtering_entry_revert_color = filtering_entry_revert_color self.filter_key_pressed = filter_key_pressed self.on_add_item = on_add_item self.parse_formatting = parse_formatting self.connected = connected self.on_library_button_press = on_library_button_press self.on_library_search_text_click = on_library_search_text_click self.NOTAG = _("Untagged") self.VAstr = _("Various Artists") self.search_terms = [_('Artist'), _('Title'), _('Album'), _('Genre'), _('Filename'), _('Everything')] self.search_terms_mpd = ['artist', 'title', 'album', 'genre', 'file', 'any'] self.libfilterbox_cmd_buf = None self.libfilterbox_cond = None self.libfilterbox_source = None self.prevlibtodo_base = None self.prevlibtodo_base_results = None self.prevlibtodo = None self.save_timeout = None self.libsearch_last_tooltip = None self.lib_view_filesystem_cache = None self.lib_view_artist_cache = None self.lib_view_genre_cache = None self.lib_view_album_cache = None self.lib_list_genres = None self.lib_list_artists = None self.lib_list_albums = None self.lib_list_years = None self.view_caches_reset() self.libraryvbox = gtk.VBox() self.library = ui.treeview() self.library_selection = self.library.get_selection() expanderwindow2 = ui.scrollwindow(add=self.library) self.searchbox = gtk.HBox() self.searchcombo = ui.combo(items=self.search_terms) self.searchtext = ui.entry() self.searchbutton = ui.button(text=_('_End Search'), img=ui.image(stock=gtk.STOCK_CLOSE), h=self.searchcombo.size_request()[1]) self.searchbutton.set_no_show_all(True) self.searchbutton.hide() self.libraryview = ui.button(relief=gtk.RELIEF_NONE) self.libraryview.set_tooltip_text(_("Library browsing view")) self.library_view_assign_image() self.searchbox.pack_start(self.libraryview, False, False, 1) self.searchbox.pack_start(gtk.VSeparator(), False, False, 0) self.searchbox.pack_start(self.searchcombo, False, False, 2) self.searchbox.pack_start(self.searchtext, True, True, 2) self.searchbox.pack_start(self.searchbutton, False, False, 2) self.libraryvbox.pack_start(expanderwindow2, True, True, 2) self.libraryvbox.pack_start(self.searchbox, False, False, 2) libraryhbox = gtk.HBox() libraryhbox.pack_start(ui.image(stock=gtk.STOCK_HARDDISK), False, False, 2) libraryhbox.pack_start(ui.label(text=self.TAB_LIBRARY), False, False, 2) self.libraryevbox = ui.eventbox(add=libraryhbox) self.libraryevbox.show_all() # Assign some pixbufs for use in self.library self.openpb = self.library.render_icon(gtk.STOCK_OPEN, gtk.ICON_SIZE_LARGE_TOOLBAR) self.harddiskpb = self.library.render_icon(gtk.STOCK_HARDDISK, gtk.ICON_SIZE_LARGE_TOOLBAR) self.albumpb = gtk.gdk.pixbuf_new_from_file_at_size(album_filename, consts.LIB_COVER_SIZE, consts.LIB_COVER_SIZE) self.genrepb = self.library.render_icon('gtk-orientation-portrait', gtk.ICON_SIZE_LARGE_TOOLBAR) self.artistpb = self.library.render_icon('artist', gtk.ICON_SIZE_LARGE_TOOLBAR) self.sonatapb = self.library.render_icon('sonata', gtk.ICON_SIZE_MENU) self.library.connect('row_activated', self.on_library_row_activated) self.library.connect('button_press_event', self.on_library_button_press) self.library.connect('key-press-event', self.on_library_key_press) self.library.connect('query-tooltip', self.on_library_query_tooltip) expanderwindow2.connect('scroll-event', self.on_library_scrolled) self.libraryview.connect('clicked', self.library_view_popup) self.searchtext.connect('button_press_event', self.on_library_search_text_click) self.searchtext.connect('key-press-event', self.libsearchfilter_key_pressed) self.searchtext.connect('activate', self.libsearchfilter_on_enter) self.searchbutton.connect('clicked', self.on_search_end) self.libfilter_changed_handler = self.searchtext.connect('changed', self.libsearchfilter_feed_loop) searchcombo_changed_handler = self.searchcombo.connect('changed', self.on_library_search_combo_change) # Initialize library data and widget self.libraryposition = {} self.libraryselectedpath = {} self.searchcombo.handler_block(searchcombo_changed_handler) self.searchcombo.set_active(self.config.last_search_num) self.searchcombo.handler_unblock(searchcombo_changed_handler) self.librarydata = gtk.ListStore(gtk.gdk.Pixbuf, str, str) self.library.set_model(self.librarydata) self.library.set_search_column(2) self.librarycell = gtk.CellRendererText() self.librarycell.set_property("ellipsize", pango.ELLIPSIZE_END) self.libraryimg = gtk.CellRendererPixbuf() self.librarycolumn = gtk.TreeViewColumn() self.librarycolumn.pack_start(self.libraryimg, False) self.librarycolumn.pack_start(self.librarycell, True) self.librarycolumn.set_attributes(self.libraryimg, pixbuf=0) self.librarycolumn.set_attributes(self.librarycell, markup=2) self.librarycolumn.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE) self.library.append_column(self.librarycolumn) self.library_selection.set_mode(gtk.SELECTION_MULTIPLE)
def mpd_tab(self, cbs=None): """Construct and layout the MPD tab""" mpdlabel = ui.label(markup='<b>' + _('MPD Connection') + '</b>') frame = gtk.Frame() frame.set_label_widget(mpdlabel) frame.set_shadow_type(gtk.SHADOW_NONE) controlbox = gtk.HBox() profiles = ui.combo() add_profile = ui.button(img=ui.image(stock=gtk.STOCK_ADD)) remove_profile = ui.button(img=ui.image(stock=gtk.STOCK_REMOVE)) self._populate_profile_combo(profiles, self.config.profile_num, remove_profile) controlbox.pack_start(profiles, False, False, 2) controlbox.pack_start(remove_profile, False, False, 2) controlbox.pack_start(add_profile, False, False, 2) namelabel = ui.label(textmn=_("_Name") + ":") nameentry = ui.entry() namelabel.set_mnemonic_widget(nameentry) hostlabel = ui.label(textmn=_("_Host") + ":") hostentry = ui.entry() hostlabel.set_mnemonic_widget(hostentry) portlabel = ui.label(textmn=_("_Port") + ":") portentry = gtk.SpinButton(gtk.Adjustment(0 ,0 ,65535, 1),1) portentry.set_numeric(True) portlabel.set_mnemonic_widget(portentry) dirlabel = ui.label(textmn=_("_Music dir") + ":") direntry = gtk.FileChooserButton(_('Select a Music Directory')) self.direntry = direntry direntry.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER) direntry.connect('selection-changed', self._direntry_changed, profiles) dirlabel.set_mnemonic_widget(direntry) passwordlabel = ui.label(textmn=_("Pa_ssword") + ":") passwordentry = ui.entry(password=True) passwordlabel.set_mnemonic_widget(passwordentry) passwordentry.set_tooltip_text(_("Leave blank if no password is required.")) autoconnect = gtk.CheckButton(_("_Autoconnect on start")) autoconnect.set_active(self.config.autoconnect) autoconnect.connect('toggled', self._config_widget_active, 'autoconnect') # Fill in entries with current profile: self._profile_chosen(profiles, nameentry, hostentry, portentry, passwordentry, direntry) # Update display if $MPD_HOST or $MPD_PORT is set: host, port, password = misc.mpd_env_vars() if host or port: self.using_mpd_env_vars = True if not host: host = "" if not port: port = 0 if not password: password = "" hostentry.set_text(str(host)) portentry.set_value(port) passwordentry.set_text(str(password)) nameentry.set_text(_("Using MPD_HOST/PORT")) for widget in [hostentry, portentry, passwordentry, nameentry, profiles, add_profile, remove_profile]: widget.set_sensitive(False) else: self.using_mpd_env_vars = False nameentry.connect('changed', self._nameentry_changed, profiles, remove_profile) hostentry.connect('changed', self._hostentry_changed, profiles) portentry.connect('value-changed', self._portentry_changed, profiles) passwordentry.connect('changed', self._passwordentry_changed, profiles) profiles.connect('changed', self._profile_chosen, nameentry, hostentry, portentry, passwordentry, direntry) add_profile.connect('clicked', self._add_profile, nameentry, profiles, remove_profile) remove_profile.connect('clicked', self._remove_profile, profiles, remove_profile) rows = [(namelabel, nameentry), (hostlabel, hostentry), (portlabel, portentry), (passwordlabel, passwordentry), (dirlabel, direntry)] connection_table = gtk.Table(len(rows), 2) connection_table.set_col_spacings(12) for i, (label, entry) in enumerate(rows): connection_table.attach(label, 0, 1, i, i+1, gtk.FILL, gtk.FILL) connection_table.attach(entry, 1, 2, i, i+1, gtk.FILL|gtk.EXPAND, gtk.FILL) connection_alignment = gtk.Alignment(0.5, 0.5, 1.0, 1.0) connection_alignment.set_padding(12, 12, 12, 12) connection_alignment.add(connection_table) connection_frame = gtk.Frame() connection_frame.set_label_widget(controlbox) connection_frame.add(connection_alignment) table = gtk.Table(2, 1) table.set_row_spacings(12) table.attach(connection_frame, 0, 1, 0, 1, gtk.FILL|gtk.EXPAND, gtk.FILL) table.attach(autoconnect, 0, 1, 1, 2, gtk.FILL|gtk.EXPAND, gtk.FILL) alignment = gtk.Alignment(0.5, 0.5, 1.0, 1.0) alignment.set_padding(12, 0, 12, 0) alignment.add(table) frame.add(alignment) tab = gtk.Alignment(0.5, 0.5, 1.0, 1.0) tab.set_padding(12, 12, 12, 12) tab.add(frame) return tab
def on_prefs_real(self, parent_window, popuptimes, as_imported, as_import, as_init, as_reauth, trayicon_available, trayicon_in_use, reconnect, renotify, reinfofile, prefs_notif_toggled, prefs_stylized_toggled, prefs_art_toggled, prefs_playback_toggled, prefs_progress_toggled, prefs_statusbar_toggled, prefs_lyrics_toggled, prefs_trayicon_toggled, prefs_window_response): """Display the preferences dialog""" self.window = parent_window self.as_imported = as_imported self.as_import = as_import self.as_init = as_init self.as_reauth = as_reauth self.reconnect = reconnect self.renotify = renotify self.reinfofile = reinfofile prefswindow = ui.dialog(title=_("Preferences"), parent=self.window, flags=gtk.DIALOG_DESTROY_WITH_PARENT, role='preferences', resizable=False, separator=False) hbox = gtk.HBox() prefsnotebook = gtk.Notebook() # MPD tab mpdlabel = ui.label(markup='<b>' + _('MPD Connection') + '</b>', y=1) controlbox = gtk.HBox() profiles = ui.combo() add_profile = ui.button(img=ui.image(stock=gtk.STOCK_ADD)) remove_profile = ui.button(img=ui.image(stock=gtk.STOCK_REMOVE)) self.prefs_populate_profile_combo(profiles, self.profile_num, remove_profile) controlbox.pack_start(profiles, False, False, 2) controlbox.pack_start(remove_profile, False, False, 2) controlbox.pack_start(add_profile, False, False, 2) namebox = gtk.HBox() namelabel = ui.label(text=_("Name") + ":") namebox.pack_start(namelabel, False, False, 0) nameentry = ui.entry() namebox.pack_start(nameentry, True, True, 10) hostbox = gtk.HBox() hostlabel = ui.label(text=_("Host") + ":") hostbox.pack_start(hostlabel, False, False, 0) hostentry = ui.entry() hostbox.pack_start(hostentry, True, True, 10) portbox = gtk.HBox() portlabel = ui.label(text=_("Port") + ":") portbox.pack_start(portlabel, False, False, 0) portentry = ui.entry() portbox.pack_start(portentry, True, True, 10) dirbox = gtk.HBox() dirlabel = ui.label(text=_("Music dir") + ":") dirbox.pack_start(dirlabel, False, False, 0) direntry = ui.entry() direntry.connect('changed', self.prefs_direntry_changed, profiles) dirbox.pack_start(direntry, True, True, 10) passwordbox = gtk.HBox() passwordlabel = ui.label(text=_("Password") + ":") passwordbox.pack_start(passwordlabel, False, False, 0) passwordentry = ui.entry(password=True) passwordentry.set_tooltip_text( _("Leave blank if no password is required.")) passwordbox.pack_start(passwordentry, True, True, 10) mpd_labels = [namelabel, hostlabel, portlabel, passwordlabel, dirlabel] ui.set_widths_equal(mpd_labels) autoconnect = gtk.CheckButton(_("Autoconnect on start")) autoconnect.set_active(self.autoconnect) # Fill in entries with current profile: self.prefs_profile_chosen(profiles, nameentry, hostentry, portentry, passwordentry, direntry) # Update display if $MPD_HOST or $MPD_PORT is set: host, port, password = misc.mpd_env_vars() if host or port: using_mpd_env_vars = True if not host: host = "" if not port: port = "" if not password: password = "" hostentry.set_text(str(host)) portentry.set_text(str(port)) passwordentry.set_text(str(password)) nameentry.set_text(_("Using MPD_HOST/PORT")) for widget in [ hostentry, portentry, passwordentry, nameentry, profiles, add_profile, remove_profile ]: widget.set_sensitive(False) else: using_mpd_env_vars = False # remove_profile is properly set in populate_profile_combo: for widget in [ hostentry, portentry, passwordentry, nameentry, profiles, add_profile ]: widget.set_sensitive(True) nameentry.connect('changed', self.prefs_nameentry_changed, profiles, remove_profile) hostentry.connect('changed', self.prefs_hostentry_changed, profiles) portentry.connect('changed', self.prefs_portentry_changed, profiles) passwordentry.connect('changed', self.prefs_passwordentry_changed, profiles) profiles.connect('changed', self.prefs_profile_chosen, nameentry, hostentry, portentry, passwordentry, direntry) add_profile.connect('clicked', self.prefs_add_profile, nameentry, profiles, remove_profile) remove_profile.connect('clicked', self.prefs_remove_profile, profiles, remove_profile) mpd_frame = gtk.Frame() table = gtk.Table(6, 2, False) table.set_col_spacings(3) table.attach(ui.label(), 1, 3, 1, 2, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 10, 0) table.attach(namebox, 1, 3, 2, 3, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 10, 0) table.attach(hostbox, 1, 3, 3, 4, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 10, 0) table.attach(portbox, 1, 3, 4, 5, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 10, 0) table.attach(passwordbox, 1, 3, 5, 6, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 10, 0) table.attach(dirbox, 1, 3, 6, 7, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 10, 0) table.attach(ui.label(), 1, 3, 7, 8, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 10, 0) mpd_frame.add(table) mpd_frame.set_label_widget(controlbox) mpd_table = gtk.Table(9, 2, False) mpd_table.set_col_spacings(3) mpd_table.attach(ui.label(), 1, 3, 1, 2, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 10, 0) mpd_table.attach(mpdlabel, 1, 3, 2, 3, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 15, 0) mpd_table.attach(ui.label(), 1, 3, 3, 4, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 10, 0) mpd_table.attach(mpd_frame, 1, 3, 4, 10, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) mpd_table.attach(ui.label(), 1, 3, 10, 11, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) mpd_table.attach(autoconnect, 1, 3, 11, 12, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) mpd_table.attach(ui.label(), 1, 3, 12, 13, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) mpd_table.attach(ui.label(), 1, 3, 13, 14, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) mpd_table.attach(ui.label(), 1, 3, 14, 15, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) # Extras tab if not as_imported: self.as_enabled = False as_label = ui.label(markup='<b>' + _('Extras') + '</b>') as_frame = gtk.Frame() as_frame.set_label_widget(as_label) as_frame.set_shadow_type(gtk.SHADOW_NONE) as_frame.set_border_width(15) as_vbox = gtk.VBox() as_vbox.set_border_width(15) as_checkbox = gtk.CheckButton(_("Enable Audioscrobbler")) as_checkbox.set_active(self.as_enabled) as_vbox.pack_start(as_checkbox, False) as_table = gtk.Table(2, 2) as_table.set_col_spacings(3) as_user_label = ui.label(text=" " + _("Username:"******" " + _("Password:"******"Popup notification on song changes")) display_notification.set_active(self.show_notification) notifhbox = gtk.HBox() notif_blank = ui.label(x=1) notifhbox.pack_start(notif_blank) time_names = [] for i in popuptimes: if i != _('Entire song'): time_names.append( i + ' ' + gettext.ngettext('second', 'seconds', int(i))) else: time_names.append(i) notification_options = ui.combo( items=time_names, active=self.popup_option, changed_cb=self.prefs_notiftime_changed) notification_locs = ui.combo( items=self.popuplocations, active=self.traytips_notifications_location, changed_cb=self.prefs_notiflocation_changed) display_notification.connect('toggled', prefs_notif_toggled, notifhbox) notifhbox.pack_start(notification_options, False, False, 2) notifhbox.pack_start(notification_locs, False, False, 2) if not self.show_notification: notifhbox.set_sensitive(False) crossfadecheck = gtk.CheckButton(_("Enable Crossfade")) crossfadespin = gtk.SpinButton() crossfadespin.set_digits(0) crossfadespin.set_range(1, 30) crossfadespin.set_value(self.xfade) crossfadespin.set_numeric(True) crossfadespin.set_increments(1, 5) crossfadespin.set_size_request(70, -1) crossfadelabel2 = ui.label(text=_("Fade length") + ":", x=1) crossfadelabel3 = ui.label(text=_("sec")) if not self.xfade_enabled: crossfadespin.set_sensitive(False) crossfadelabel2.set_sensitive(False) crossfadelabel3.set_sensitive(False) crossfadecheck.set_active(False) else: crossfadespin.set_sensitive(True) crossfadelabel2.set_sensitive(True) crossfadelabel3.set_sensitive(True) crossfadecheck.set_active(True) crossfadebox = gtk.HBox() crossfadebox.pack_start(crossfadelabel2) crossfadebox.pack_start(crossfadespin, False, False, 5) crossfadebox.pack_start(crossfadelabel3, False, False, 0) crossfadecheck.connect('toggled', self.prefs_crossfadecheck_toggled, crossfadespin, crossfadelabel2, crossfadelabel3) as_table.attach(as_user_label, 0, 1, 0, 1) as_table.attach(as_user_entry, 1, 2, 0, 1) as_table.attach(as_pass_label, 0, 1, 1, 2) as_table.attach(as_pass_entry, 1, 2, 1, 2) as_table.attach(ui.label(), 0, 2, 2, 3) as_table.attach(display_notification, 0, 2, 3, 4) as_table.attach(notifhbox, 0, 2, 4, 5) as_table.attach(ui.label(), 0, 2, 5, 6) as_table.attach(crossfadecheck, 0, 2, 6, 7) as_table.attach(crossfadebox, 0, 2, 7, 8) as_table.attach(ui.label(), 0, 2, 8, 9) as_vbox.pack_start(as_table, False) as_frame.add(as_vbox) as_checkbox.connect('toggled', self.prefs_as_enabled_toggled, as_user_entry, as_pass_entry, as_user_label, as_pass_label) if not self.as_enabled or not as_imported: as_user_entry.set_sensitive(False) as_pass_entry.set_sensitive(False) as_user_label.set_sensitive(False) as_pass_label.set_sensitive(False) # Display tab table2 = gtk.Table(7, 2, False) displaylabel = ui.label(markup='<b>' + _('Display') + '</b>', y=1) display_art_hbox = gtk.HBox() display_art = gtk.CheckButton(_("Enable album art")) display_art.set_active(self.show_covers) display_stylized_combo = ui.combo(items=[_("Standard"), _("Stylized")], active=self.covers_type, changed_cb=prefs_stylized_toggled) display_stylized_hbox = gtk.HBox() display_stylized_hbox.pack_start( ui.label(text=_("Artwork style:"), x=1)) display_stylized_hbox.pack_start(display_stylized_combo, False, False, 5) display_stylized_hbox.set_sensitive(self.show_covers) display_art_combo = ui.combo( items=[_("Local only"), _("Local and remote")], active=self.covers_pref) orderart_label = ui.label(text=_("Search locations:"), x=1) display_art_hbox.pack_start(orderart_label) display_art_hbox.pack_start(display_art_combo, False, False, 5) display_art_hbox.set_sensitive(self.show_covers) display_art_location_hbox = gtk.HBox() display_art_location_hbox.pack_start( ui.label(text=_("Save art to:"), x=1)) art_paths = ["~/.covers/"] for item in [ "/cover.jpg", "/album.jpg", "/folder.jpg", "/" + _("custom") ]: art_paths.append("../" + _("file_path") + item) display_art_location = ui.combo( items=art_paths, active=self.art_location, changed_cb=self.prefs_art_location_changed) display_art_location_hbox.pack_start(display_art_location, False, False, 5) display_art_location_hbox.set_sensitive(self.show_covers) display_art.connect('toggled', prefs_art_toggled, display_art_hbox, display_art_location_hbox, display_stylized_hbox) display_playback = gtk.CheckButton(_("Enable playback/volume buttons")) display_playback.set_active(self.show_playback) display_playback.connect('toggled', prefs_playback_toggled) display_progress = gtk.CheckButton(_("Enable progressbar")) display_progress.set_active(self.show_progress) display_progress.connect('toggled', prefs_progress_toggled) display_statusbar = gtk.CheckButton(_("Enable statusbar")) display_statusbar.set_active(self.show_statusbar) display_statusbar.connect('toggled', prefs_statusbar_toggled) display_lyrics = gtk.CheckButton(_("Enable lyrics")) display_lyrics.set_active(self.show_lyrics) display_lyrics_location_hbox = gtk.HBox() savelyrics_label = ui.label(text=_("Save lyrics to:"), x=1) display_lyrics_location_hbox.pack_start(savelyrics_label) display_lyrics_location = ui.combo( items=["~/.lyrics/", "../" + _("file_path") + "/"], active=self.lyrics_location, changed_cb=self.prefs_lyrics_location_changed) display_lyrics_location_hbox.pack_start(display_lyrics_location, False, False, 5) display_lyrics_location_hbox.set_sensitive(self.show_lyrics) display_lyrics.connect('toggled', prefs_lyrics_toggled, display_lyrics_location_hbox) display_trayicon = gtk.CheckButton(_("Enable system tray icon")) display_trayicon.set_active(self.show_trayicon) display_trayicon.set_sensitive(trayicon_available) table2.attach(ui.label(), 1, 3, 1, 2, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 15, 0) table2.attach(displaylabel, 1, 3, 2, 3, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 15, 0) table2.attach(ui.label(), 1, 3, 3, 4, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 15, 0) table2.attach(display_playback, 1, 3, 4, 5, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) table2.attach(display_progress, 1, 3, 5, 6, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) table2.attach(display_statusbar, 1, 3, 6, 7, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) table2.attach(display_trayicon, 1, 3, 7, 8, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) table2.attach(display_lyrics, 1, 3, 8, 9, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) table2.attach(display_lyrics_location_hbox, 1, 3, 9, 10, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) table2.attach(display_art, 1, 3, 10, 11, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) table2.attach(display_stylized_hbox, 1, 3, 11, 12, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) table2.attach(display_art_hbox, 1, 3, 12, 13, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) table2.attach(display_art_location_hbox, 1, 3, 13, 14, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) table2.attach(ui.label(), 1, 3, 14, 15, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 75, 0) # Behavior tab table3 = gtk.Table() behaviorlabel = ui.label(markup='<b>' + _('Window Behavior') + '</b>', y=1) win_sticky = gtk.CheckButton(_("Show window on all workspaces")) win_sticky.set_active(self.sticky) win_ontop = gtk.CheckButton(_("Keep window above other windows")) win_ontop.set_active(self.ontop) update_start = gtk.CheckButton(_("Update MPD library on start")) update_start.set_active(self.update_on_start) update_start.set_tooltip_text( _("If enabled, Sonata will automatically update your MPD library when it starts up." )) exit_stop = gtk.CheckButton(_("Stop playback on exit")) exit_stop.set_active(self.stop_on_exit) exit_stop.set_tooltip_text( _("MPD allows playback even when the client is not open. If enabled, Sonata will behave like a more conventional music player and, instead, stop playback upon exit." )) minimize = gtk.CheckButton( _("Minimize to system tray on close/escape")) minimize.set_active(self.minimize_to_systray) minimize.set_tooltip_text( _("If enabled, closing Sonata will minimize it to the system tray. Note that it's currently impossible to detect if there actually is a system tray, so only check this if you have one." )) display_trayicon.connect('toggled', prefs_trayicon_toggled, minimize) minimize.set_sensitive(trayicon_in_use) infofilebox = gtk.HBox() infofile_usage = gtk.CheckButton(_("Write status file:")) infofile_usage.set_active(self.use_infofile) infofile_usage.set_tooltip_text( _("If enabled, Sonata will create a xmms-infopipe like file containing information about the current song. Many applications support the xmms-info file (Instant Messengers, IRC Clients...)" )) infopath_options = ui.entry(text=self.infofile_path) infopath_options.set_tooltip_text( _("If enabled, Sonata will create a xmms-infopipe like file containing information about the current song. Many applications support the xmms-info file (Instant Messengers, IRC Clients...)" )) if not self.use_infofile: infopath_options.set_sensitive(False) infofile_usage.connect('toggled', self.prefs_infofile_toggled, infopath_options) infofilebox.pack_start(infofile_usage, False, False, 0) infofilebox.pack_start(infopath_options, True, True, 5) behaviorlabel2 = ui.label(markup='<b>' + _('Miscellaneous') + '</b>', y=1) table3.attach(ui.label(), 1, 3, 1, 2, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 15, 0) table3.attach(behaviorlabel, 1, 3, 2, 3, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 15, 0) table3.attach(ui.label(), 1, 3, 3, 4, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 15, 0) table3.attach(win_sticky, 1, 3, 4, 5, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) table3.attach(win_ontop, 1, 3, 5, 6, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) table3.attach(minimize, 1, 3, 6, 7, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) table3.attach(ui.label(), 1, 3, 7, 8, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 15, 0) table3.attach(behaviorlabel2, 1, 3, 8, 9, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 15, 0) table3.attach(ui.label(), 1, 3, 9, 10, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 15, 0) table3.attach(update_start, 1, 3, 10, 11, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) table3.attach(exit_stop, 1, 3, 11, 12, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) table3.attach(infofilebox, 1, 3, 12, 13, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) table3.attach(ui.label(), 1, 3, 13, 14, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) table3.attach(ui.label(), 1, 3, 14, 15, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) table3.attach(ui.label(), 1, 3, 15, 16, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) table3.attach(ui.label(), 1, 3, 16, 17, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) table3.attach(ui.label(), 1, 3, 17, 18, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) table3.attach(ui.label(), 1, 3, 18, 19, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) # Format tab table4 = gtk.Table(9, 2, False) table4.set_col_spacings(3) formatlabel = ui.label(markup='<b>' + _('Song Formatting') + '</b>', y=1) currentformatbox = gtk.HBox() currentlabel = ui.label(text=_("Current playlist:")) currentoptions = ui.entry(text=self.currentformat) currentformatbox.pack_start(currentlabel, False, False, 0) currentformatbox.pack_start(currentoptions, False, False, 10) libraryformatbox = gtk.HBox() librarylabel = ui.label(text=_("Library:")) libraryoptions = ui.entry(text=self.libraryformat) libraryformatbox.pack_start(librarylabel, False, False, 0) libraryformatbox.pack_start(libraryoptions, False, False, 10) titleformatbox = gtk.HBox() titlelabel = ui.label(text=_("Window title:")) titleoptions = ui.entry(text=self.titleformat) titleoptions.set_text(self.titleformat) titleformatbox.pack_start(titlelabel, False, False, 0) titleformatbox.pack_start(titleoptions, False, False, 10) currsongformatbox1 = gtk.HBox() currsonglabel1 = ui.label(text=_("Current song line 1:")) currsongoptions1 = ui.entry(text=self.currsongformat1) currsongformatbox1.pack_start(currsonglabel1, False, False, 0) currsongformatbox1.pack_start(currsongoptions1, False, False, 10) currsongformatbox2 = gtk.HBox() currsonglabel2 = ui.label(text=_("Current song line 2:")) currsongoptions2 = ui.entry(text=self.currsongformat2) currsongformatbox2.pack_start(currsonglabel2, False, False, 0) currsongformatbox2.pack_start(currsongoptions2, False, False, 10) formatlabels = [ currentlabel, librarylabel, titlelabel, currsonglabel1, currsonglabel2 ] for label in formatlabels: label.set_alignment(0, 0.5) ui.set_widths_equal(formatlabels) availableheading = ui.label(markup='<small>' + _('Available options') + ':</small>', y=0) availablevbox = gtk.VBox() availableformatbox = gtk.HBox() availableformatting = ui.label( markup='<small><span font_family="Monospace">%A</span> - ' + _('Artist name') + '\n<span font_family="Monospace">%B</span> - ' + _('Album name') + '\n<span font_family="Monospace">%T</span> - ' + _('Track name') + '\n<span font_family="Monospace">%N</span> - ' + _('Track number') + '\n<span font_family="Monospace">%D</span> - ' + _('Disc Number') + '\n<span font_family="Monospace">%Y</span> - ' + _('Year') + '</small>', y=0) availableformatting2 = ui.label( markup='<small><span font_family="Monospace">%G</span> - ' + _('Genre') + '\n<span font_family="Monospace">%F</span> - ' + _('File name') + '\n<span font_family="Monospace">%S</span> - ' + _('Stream name') + '\n<span font_family="Monospace">%L</span> - ' + _('Song length') + '\n<span font_family="Monospace">%E</span> - ' + _('Elapsed time (title only)') + '</small>', y=0) availableformatbox.pack_start(availableformatting) availableformatbox.pack_start(availableformatting2) availablevbox.pack_start(availableformatbox, False, False, 0) additionalinfo = ui.label( markup='<small>{ } - ' + _('Info displayed only if all enclosed tags are defined') + '\n' + '| - ' + _('Creates columns in the current playlist') + '</small>', y=0) availablevbox.pack_start(additionalinfo, False, False, 4) table4.attach(ui.label(), 1, 3, 1, 2, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 15, 0) table4.attach(formatlabel, 1, 3, 2, 3, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 15, 0) table4.attach(ui.label(), 1, 3, 3, 4, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 15, 0) table4.attach(currentformatbox, 1, 3, 4, 5, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) table4.attach(libraryformatbox, 1, 3, 5, 6, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) table4.attach(titleformatbox, 1, 3, 6, 7, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) table4.attach(currsongformatbox1, 1, 3, 7, 8, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) table4.attach(currsongformatbox2, 1, 3, 8, 9, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) table4.attach(ui.label(), 1, 3, 9, 10, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) table4.attach(availableheading, 1, 3, 10, 11, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) table4.attach(availablevbox, 1, 3, 11, 12, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 45, 0) table4.attach(ui.label(), 1, 3, 12, 13, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 30, 0) table_names = [[_("_MPD"), mpd_table], [_("_Display"), table2], [_("_Behavior"), table3], [_("_Format"), table4], [_("_Extras"), as_frame]] for table_name in table_names: tmplabel = ui.label(textmn=table_name[0]) prefsnotebook.append_page(table_name[1], tmplabel) hbox.pack_start(prefsnotebook, False, False, 10) prefswindow.vbox.pack_start(hbox, False, False, 10) close_button = prefswindow.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE) prefswindow.show_all() close_button.grab_focus() prefswindow.connect('response', prefs_window_response, prefsnotebook, exit_stop, win_ontop, display_art_combo, win_sticky, direntry, minimize, update_start, autoconnect, currentoptions, libraryoptions, titleoptions, currsongoptions1, currsongoptions2, crossfadecheck, crossfadespin, infopath_options, using_mpd_env_vars, self.prev_host, self.prev_port, self.prev_password) # Save previous connection properties to determine if we should try to # connect to MPD after prefs are closed: self.prev_host = self.host[self.profile_num] self.prev_port = self.port[self.profile_num] self.prev_password = self.password[self.profile_num] prefswindow.show()