def __init__(self, albums, parent): super(RGDialog, self).__init__(title=_('ReplayGain Analyzer'), parent=parent, buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_SAVE, Gtk.ResponseType.OK)) self.set_default_size(500, 350) self.set_border_width(6) swin = Gtk.ScrolledWindow() swin.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) swin.set_shadow_type(Gtk.ShadowType.IN) self.vbox.pack_start(swin, True, True, 0) view = HintedTreeView() swin.add(view) def icon_cdf(column, cell, model, iter_, *args): item = model[iter_][0] if item.error: cell.set_property('stock-id', Gtk.STOCK_DIALOG_ERROR) else: cell.set_property('stock-id', None) column = Gtk.TreeViewColumn() column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) icon_render = Gtk.CellRendererPixbuf() column.pack_start(icon_render, True) column.set_cell_data_func(icon_render, icon_cdf) view.append_column(column) def track_cdf(column, cell, model, iter_, *args): item = model[iter_][0] cell.set_property('text', item.title) column = Gtk.TreeViewColumn(_("Track")) column.set_expand(True) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) track_render = Gtk.CellRendererText() track_render.set_property('ellipsize', Pango.EllipsizeMode.END) column.pack_start(track_render, True) column.set_cell_data_func(track_render, track_cdf) view.append_column(column) def progress_cdf(column, cell, model, iter_, *args): item = model[iter_][0] cell.set_property('value', int(item.progress * 100)) column = Gtk.TreeViewColumn(_("Progress")) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) progress_render = Gtk.CellRendererProgress() column.pack_start(progress_render, True) column.set_cell_data_func(progress_render, progress_cdf) view.append_column(column) def gain_cdf(column, cell, model, iter_, *args): item = model[iter_][0] if item.gain is None or not item.done: cell.set_property('text', "-") else: cell.set_property('text', "%.2f db" % item.gain) column = Gtk.TreeViewColumn(_("Gain")) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) gain_renderer = Gtk.CellRendererText() column.pack_start(gain_renderer, True) column.set_cell_data_func(gain_renderer, gain_cdf) view.append_column(column) def peak_cdf(column, cell, model, iter_, *args): item = model[iter_][0] if item.gain is None or not item.done: cell.set_property('text', "-") else: cell.set_property('text', "%.2f" % item.peak) column = Gtk.TreeViewColumn(_("Peak")) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) peak_renderer = Gtk.CellRendererText() column.pack_start(peak_renderer, True) column.set_cell_data_func(peak_renderer, peak_cdf) view.append_column(column) # create as many pipelines as threads self.pipes = [] for i in xrange(get_num_threads()): self.pipes.append(ReplayGainPipeline()) self._timeout = None self._sigs = {} self._done = [] self._todo = list([RGAlbum.from_songs(a) for a in albums]) self._count = len(self._todo) # fill the view self.model = model = Gtk.TreeStore(object) insert = model.insert for album in reversed(self._todo): base = insert(None, 0, row=[album]) for song in reversed(album.songs): insert(base, 0, row=[song]) view.set_model(model) if len(self._todo) == 1: view.expand_all() self.connect("destroy", self.__destroy) self.connect('response', self.__response)
def __init__(self, albums, parent, process_mode): super().__init__(title=_('ReplayGain Analyzer'), parent=parent) self.add_button(_("_Cancel"), Gtk.ResponseType.CANCEL) self.add_icon_button(_("_Save"), Icons.DOCUMENT_SAVE, Gtk.ResponseType.OK) self.process_mode = process_mode self.set_default_size(600, 400) self.set_border_width(6) hbox = Gtk.HBox(spacing=6) info = Gtk.Label() hbox.pack_start(info, True, True, 0) self.vbox.pack_start(hbox, False, False, 6) swin = Gtk.ScrolledWindow() swin.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) swin.set_shadow_type(Gtk.ShadowType.IN) self.vbox.pack_start(swin, True, True, 0) view = HintedTreeView() swin.add(view) def icon_cdf(column, cell, model, iter_, *args): item = model[iter_][0] if item.error: cell.set_property('icon-name', Icons.DIALOG_ERROR) else: cell.set_property('icon-name', Icons.NONE) column = Gtk.TreeViewColumn() column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) icon_render = Gtk.CellRendererPixbuf() column.pack_start(icon_render, True) column.set_cell_data_func(icon_render, icon_cdf) view.append_column(column) def track_cdf(column, cell, model, iter_, *args): item = model[iter_][0] cell.set_property('text', item.title) cell.set_sensitive(model[iter_][1]) # Translators: Combined track number/title column heading column = Gtk.TreeViewColumn(C_("track/title", "Track")) column.set_expand(True) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) track_render = Gtk.CellRendererText() track_render.set_property('ellipsize', Pango.EllipsizeMode.END) column.pack_start(track_render, True) column.set_cell_data_func(track_render, track_cdf) view.append_column(column) def progress_cdf(column, cell, model, iter_, *args): item = model[iter_][0] cell.set_property('value', int(item.progress * 100)) cell.set_sensitive(model[iter_][1]) column = Gtk.TreeViewColumn(_("Progress")) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) progress_render = Gtk.CellRendererProgress() column.pack_start(progress_render, True) column.set_cell_data_func(progress_render, progress_cdf) view.append_column(column) def gain_cdf(column, cell, model, iter_, *args): item = model[iter_][0] if item.gain is None or not item.done: cell.set_property('text', "-") else: cell.set_property('text', "%.2f db" % item.gain) cell.set_sensitive(model[iter_][1]) column = Gtk.TreeViewColumn(_("Gain")) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) gain_renderer = Gtk.CellRendererText() column.pack_start(gain_renderer, True) column.set_cell_data_func(gain_renderer, gain_cdf) view.append_column(column) def peak_cdf(column, cell, model, iter_, *args): item = model[iter_][0] if item.gain is None or not item.done: cell.set_property('text', "-") else: cell.set_property('text', "%.2f" % item.peak) cell.set_sensitive(model[iter_][1]) column = Gtk.TreeViewColumn(_("Peak")) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) peak_renderer = Gtk.CellRendererText() column.pack_start(peak_renderer, True) column.set_cell_data_func(peak_renderer, peak_cdf) view.append_column(column) self.create_pipelines() self._timeout = None self._sigs = {} self._done = [] self.__fill_view(view, albums) num_to_process = sum(int(rga.should_process) for rga in self._todo) template = ngettext( "There is <b>%(to-process)s</b> album to update (of %(all)s)", "There are <b>%(to-process)s</b> albums to update (of %(all)s)", num_to_process) info.set_markup( template % { "to-process": format_int_locale(num_to_process), "all": format_int_locale(len(self._todo)), }) self.connect("destroy", self.__destroy) self.connect('response', self.__response)
def __init__(self, albums, parent, process_mode): super(RGDialog, self).__init__( title=_('ReplayGain Analyzer'), parent=parent) self.add_button(_("_Cancel"), Gtk.ResponseType.CANCEL) self.add_icon_button(_("_Save"), Icons.DOCUMENT_SAVE, Gtk.ResponseType.OK) self.process_mode = process_mode self.set_default_size(600, 400) self.set_border_width(6) hbox = Gtk.HBox(spacing=6) info = Gtk.Label() hbox.pack_start(info, True, True, 0) self.vbox.pack_start(hbox, False, False, 6) swin = Gtk.ScrolledWindow() swin.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) swin.set_shadow_type(Gtk.ShadowType.IN) self.vbox.pack_start(swin, True, True, 0) view = HintedTreeView() swin.add(view) def icon_cdf(column, cell, model, iter_, *args): item = model[iter_][0] if item.error: cell.set_property('icon-name', Icons.DIALOG_ERROR) else: cell.set_property('icon-name', Icons.NONE) column = Gtk.TreeViewColumn() column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) icon_render = Gtk.CellRendererPixbuf() column.pack_start(icon_render, True) column.set_cell_data_func(icon_render, icon_cdf) view.append_column(column) def track_cdf(column, cell, model, iter_, *args): item = model[iter_][0] cell.set_property('text', item.title) cell.set_sensitive(model[iter_][1]) column = Gtk.TreeViewColumn(_("Track")) column.set_expand(True) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) track_render = Gtk.CellRendererText() track_render.set_property('ellipsize', Pango.EllipsizeMode.END) column.pack_start(track_render, True) column.set_cell_data_func(track_render, track_cdf) view.append_column(column) def progress_cdf(column, cell, model, iter_, *args): item = model[iter_][0] cell.set_property('value', int(item.progress * 100)) cell.set_sensitive(model[iter_][1]) column = Gtk.TreeViewColumn(_("Progress")) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) progress_render = Gtk.CellRendererProgress() column.pack_start(progress_render, True) column.set_cell_data_func(progress_render, progress_cdf) view.append_column(column) def gain_cdf(column, cell, model, iter_, *args): item = model[iter_][0] if item.gain is None or not item.done: cell.set_property('text', "-") else: cell.set_property('text', "%.2f db" % item.gain) cell.set_sensitive(model[iter_][1]) column = Gtk.TreeViewColumn(_("Gain")) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) gain_renderer = Gtk.CellRendererText() column.pack_start(gain_renderer, True) column.set_cell_data_func(gain_renderer, gain_cdf) view.append_column(column) def peak_cdf(column, cell, model, iter_, *args): item = model[iter_][0] if item.gain is None or not item.done: cell.set_property('text', "-") else: cell.set_property('text', "%.2f" % item.peak) cell.set_sensitive(model[iter_][1]) column = Gtk.TreeViewColumn(_("Peak")) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) peak_renderer = Gtk.CellRendererText() column.pack_start(peak_renderer, True) column.set_cell_data_func(peak_renderer, peak_cdf) view.append_column(column) self.create_pipelines() self._timeout = None self._sigs = {} self._done = [] self.__fill_view(view, albums) num_to_process = sum(int(rga.should_process) for rga in self._todo) template = ngettext( "There is <b>%(to-process)s</b> album to update (of %(all)s)", "There are <b>%(to-process)s</b> albums to update (of %(all)s)", num_to_process) info.set_markup(template % { "to-process": format_int_locale(num_to_process), "all": format_int_locale(len(self._todo)), }) self.connect("destroy", self.__destroy) self.connect('response', self.__response)
def __init__(self, prop, library): super().__init__(spacing=6) self.title = _("Track Numbers") self.set_border_width(12) label_start = Gtk.Label(label=_("Start fro_m:"), halign=Gtk.Align.END) label_start.set_use_underline(True) spin_start = Gtk.SpinButton() spin_start.set_range(0, 999) spin_start.set_increments(1, 10) spin_start.set_value(1) label_start.set_mnemonic_widget(spin_start) label_total = Gtk.Label(label=_("_Total tracks:"), halign=Gtk.Align.END) label_total.set_use_underline(True) spin_total = Gtk.SpinButton() spin_total.set_range(0, 999) spin_total.set_increments(1, 10) label_total.set_mnemonic_widget(spin_total) preview = qltk.Button(_("_Preview"), Icons.VIEW_REFRESH) grid = Gtk.Grid(row_spacing=4, column_spacing=4) grid.add(label_start) grid.attach_next_to(spin_start, label_start, Gtk.PositionType.RIGHT, 1, 1) grid.attach_next_to(label_total, label_start, Gtk.PositionType.BOTTOM, 1, 1) grid.attach_next_to(spin_total, label_total, Gtk.PositionType.RIGHT, 1, 1) grid.attach_next_to(Align(preview, halign=Gtk.Align.END), spin_start, Gtk.PositionType.RIGHT, 1, 1) preview.props.hexpand = True model = ObjectStore() view = HintedTreeView(model=model) self.pack_start(grid, False, True, 0) render = Gtk.CellRendererText() column = TreeViewColumn(title=_('File')) column.pack_start(render, True) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) def cell_data_file(column, cell, model, iter_, data): entry = model.get_value(iter_) cell.set_property("text", entry.name) column.set_cell_data_func(render, cell_data_file) view.append_column(column) render = Gtk.CellRendererText() render.set_property('editable', True) column = TreeViewColumn(title=_('Track')) column.pack_start(render, True) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) def cell_data_track(column, cell, model, iter_, data): entry = model.get_value(iter_) cell.set_property("text", entry.tracknumber) column.set_cell_data_func(render, cell_data_track) view.append_column(column) view.set_reorderable(True) w = Gtk.ScrolledWindow() w.set_shadow_type(Gtk.ShadowType.IN) w.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) w.add(view) self.pack_start(w, True, True, 0) bbox = Gtk.HButtonBox() bbox.set_spacing(6) bbox.set_layout(Gtk.ButtonBoxStyle.END) save = Button(_("_Save"), Icons.DOCUMENT_SAVE) self.save = save connect_obj(save, 'clicked', self.__save_files, prop, model, library) revert = Button(_("_Revert"), Icons.DOCUMENT_REVERT) self.revert = revert bbox.pack_start(revert, True, True, 0) bbox.pack_start(save, True, True, 0) self.pack_start(bbox, False, True, 0) preview_args = [spin_start, spin_total, model, save, revert] preview.connect('clicked', self.__preview_tracks, *preview_args) connect_obj(revert, 'clicked', self.__update, None, *preview_args[1:]) spin_total.connect('value-changed', self.__preview_tracks, *preview_args) spin_start.connect('value-changed', self.__preview_tracks, *preview_args) connect_obj(view, 'drag-end', self.__class__.__preview_tracks, self, *preview_args) render.connect('edited', self.__row_edited, model, preview, save) connect_obj(prop, 'changed', self.__class__.__update, self, spin_total, model, save, revert) for child in self.get_children(): child.show_all()
def __init__(self, prop, library): super(TrackNumbers, self).__init__(spacing=6) self.title = _("Track Numbers") self.set_border_width(12) hbox2 = Gtk.HBox(spacing=12) hbox_start = Gtk.HBox(spacing=3) label_start = Gtk.Label(label=_("Start fro_m:")) label_start.set_use_underline(True) spin_start = Gtk.SpinButton() spin_start.set_range(0, 999) spin_start.set_increments(1, 10) spin_start.set_value(1) label_start.set_mnemonic_widget(spin_start) hbox_start.pack_start(label_start, True, True, 0) hbox_start.pack_start(spin_start, True, True, 0) hbox_total = Gtk.HBox(spacing=3) label_total = Gtk.Label(label=_("_Total tracks:")) label_total.set_use_underline(True) spin_total = Gtk.SpinButton() spin_total.set_range(0, 999) spin_total.set_increments(1, 10) label_total.set_mnemonic_widget(spin_total) hbox_total.pack_start(label_total, True, True, 0) hbox_total.pack_start(spin_total, True, True, 0) preview = qltk.Button(_("_Preview"), Icons.VIEW_REFRESH) hbox2.pack_start(hbox_start, True, False, 0) hbox2.pack_start(hbox_total, True, False, 0) hbox2.pack_start(preview, False, True, 0) model = ObjectStore() view = HintedTreeView(model=model) self.pack_start(hbox2, False, True, 0) render = Gtk.CellRendererText() column = TreeViewColumn(title=_('File')) column.pack_start(render, True) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) def cell_data_file(column, cell, model, iter_, data): entry = model.get_value(iter_) cell.set_property("text", entry.name) column.set_cell_data_func(render, cell_data_file) view.append_column(column) render = Gtk.CellRendererText() render.set_property('editable', True) column = TreeViewColumn(title=_('Track')) column.pack_start(render, True) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) def cell_data_track(column, cell, model, iter_, data): entry = model.get_value(iter_) cell.set_property("text", entry.tracknumber) column.set_cell_data_func(render, cell_data_track) view.append_column(column) view.set_reorderable(True) w = Gtk.ScrolledWindow() w.set_shadow_type(Gtk.ShadowType.IN) w.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) w.add(view) self.pack_start(w, True, True, 0) bbox = Gtk.HButtonBox() bbox.set_spacing(6) bbox.set_layout(Gtk.ButtonBoxStyle.END) save = Button(_("_Save"), Icons.DOCUMENT_SAVE) self.save = save connect_obj(save, 'clicked', self.__save_files, prop, model, library) revert = Button(_("_Revert"), Icons.DOCUMENT_REVERT) self.revert = revert bbox.pack_start(revert, True, True, 0) bbox.pack_start(save, True, True, 0) self.pack_start(bbox, False, True, 0) preview_args = [spin_start, spin_total, model, save, revert] preview.connect('clicked', self.__preview_tracks, *preview_args) connect_obj(revert, 'clicked', self.__update, None, *preview_args[1:]) spin_total.connect( 'value-changed', self.__preview_tracks, *preview_args) spin_start.connect( 'value-changed', self.__preview_tracks, *preview_args) connect_obj(view, 'drag-end', self.__class__.__preview_tracks, self, *preview_args) render.connect('edited', self.__row_edited, model, preview, save) connect_obj(prop, 'changed', self.__class__.__update, self, spin_total, model, save, revert) for child in self.get_children(): child.show_all()
def __init__(self, title, values=None): super(TagListEditor, self).__init__() self.use_header_bar() self.data = values or [] self.set_border_width(12) self.set_title(title) self.set_default_size(self._WIDTH, self._HEIGHT) vbox = Gtk.VBox(spacing=12) hbox = Gtk.HBox(spacing=12) # Set up the model for this widget self.model = Gtk.ListStore(str) self.__fill_values() # Main view view = self.view = HintedTreeView(model=self.model) view.set_fixed_height_mode(True) view.set_headers_visible(False) sw = Gtk.ScrolledWindow() sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) sw.set_shadow_type(Gtk.ShadowType.IN) sw.add(view) sw.set_size_request(-1, max(sw.size_request().height, 100)) hbox.pack_start(sw, True, True, 0) self.__setup_column(view) # Context menu menu = Gtk.Menu() remove_item = MenuItem(_("_Remove"), Icons.LIST_REMOVE) menu.append(remove_item) menu.show_all() view.connect('popup-menu', self.__popup, menu) connect_obj(remove_item, 'activate', self.__remove, view) # Add and Remove buttons vbbox = Gtk.VButtonBox() vbbox.set_layout(Gtk.ButtonBoxStyle.START) vbbox.set_spacing(6) add = Button(_("_Add"), Icons.LIST_ADD) add.connect("clicked", self.__add) vbbox.pack_start(add, False, True, 0) remove = Button(_("_Remove"), Icons.LIST_REMOVE) remove.connect("clicked", self.__remove) vbbox.pack_start(remove, False, True, 0) hbox.pack_start(vbbox, False, True, 0) vbox.pack_start(hbox, True, True, 0) # Close buttons bbox = Gtk.HButtonBox() self.remove_but = Button(_("_Remove"), Icons.LIST_REMOVE) self.remove_but.set_sensitive(False) close = Button(_("_Close"), Icons.WINDOW_CLOSE) connect_obj(close, 'clicked', qltk.Window.destroy, self) bbox.set_layout(Gtk.ButtonBoxStyle.END) if not self.has_close_button(): bbox.pack_start(close, True, True, 0) vbox.pack_start(bbox, False, True, 0) # Finish up self.add(vbox) self.get_child().show_all()
def __init__(self, library, songs, parent=None): super(SongProperties, self).__init__(dialog=False) self.set_transient_for(qltk.get_top_parent(parent)) default_width = 600 config_suffix = "" if len(songs) <= 1: default_width -= 200 config_suffix += "single" self.set_default_size(default_width, 400) self.enable_window_tracking("quodlibet_properties", size_suffix=config_suffix) self.auto_save_on_change = config.getboolean('editing', 'auto_save_changes', False) paned = Gtk.HPaned() notebook = qltk.Notebook() pages = [] pages.extend([ Ctr(self, library) for Ctr in [EditTags, TagsFromPath, RenameFiles] ]) if len(songs) > 1: pages.append(TrackNumbers(self, library)) for page in pages: page.show() notebook.append_page(page) self.set_border_width(12) fbasemodel = Gtk.ListStore(object, str) fmodel = Gtk.TreeModelSort(model=fbasemodel) fview = HintedTreeView(fmodel) fview.connect('button-press-event', self.__pre_selection_changed) fview.set_rules_hint(True) selection = fview.get_selection() selection.set_mode(Gtk.SelectionMode.MULTIPLE) self.__save = None if len(songs) > 1: render = Gtk.CellRendererText() c1 = Gtk.TreeViewColumn(_('File'), render, text=1) render.set_property('ellipsize', Pango.EllipsizeMode.END) c1.set_sort_column_id(1) fview.append_column(c1) sw = Gtk.ScrolledWindow() sw.add(fview) sw.set_shadow_type(Gtk.ShadowType.IN) sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) sw.show_all() paned.pack1(sw, shrink=False, resize=True) # Invisible selections behave a little strangely. So, when # handling this selection, there's a lot of if len(model) == 1 # checks that "hardcode" the first row being selected. for song in songs: fbasemodel.append(row=[song, fsdecode(song("~basename"))]) self.connect_object('changed', SongProperties.__set_title, self) selection.select_all() paned.pack2(notebook, shrink=False, resize=True) csig = selection.connect('changed', self.__selection_changed) s1 = library.connect('changed', self.__refresh, fbasemodel, fview) s2 = library.connect('removed', self.__remove, fbasemodel, selection, csig) self.connect_object('destroy', library.disconnect, s1) self.connect_object('destroy', library.disconnect, s2) self.connect_object('changed', self.set_pending, None) self.emit('changed', songs) self.add(paned) paned.set_position(175) notebook.show() paned.show()
def __init__(self, library, songs, parent=None): super(SongProperties, self).__init__(dialog=False) self.set_transient_for(qltk.get_top_parent(parent)) default_width = 600 config_suffix = "" if len(songs) <= 1: default_width -= 200 config_suffix += "single" self.set_default_size(default_width, 400) self.enable_window_tracking("quodlibet_properties", size_suffix=config_suffix) self.auto_save_on_change = config.getboolean( 'editing', 'auto_save_changes', False) paned = ConfigRPaned("memory", "quodlibet_properties_pos", 0.4) notebook = qltk.Notebook() notebook.props.scrollable = True pages = [] pages.extend([Ctr(self, library) for Ctr in [EditTags, TagsFromPath, RenameFiles]]) if len(songs) > 1: pages.append(TrackNumbers(self, library)) for page in pages: page.show() notebook.append_page(page) fbasemodel = ObjectStore() fmodel = ObjectModelSort(model=fbasemodel) fview = HintedTreeView(model=fmodel) fview.connect('button-press-event', self.__pre_selection_changed) fview.set_rules_hint(True) selection = fview.get_selection() selection.set_mode(Gtk.SelectionMode.MULTIPLE) self.__save = None render = Gtk.CellRendererText() c1 = Gtk.TreeViewColumn(_('File'), render) if fview.supports_hints(): render.set_property('ellipsize', Pango.EllipsizeMode.END) render.set_property('xpad', 3) def cell_data(column, cell, model, iter_, data): entry = model.get_value(iter_) cell.set_property('text', entry.name) c1.set_cell_data_func(render, cell_data) def sort_func(model, a, b, data): a = model.get_value(a) b = model.get_value(b) return cmp(a.name, b.name) fmodel.set_sort_func(100, sort_func) c1.set_sort_column_id(100) fview.append_column(c1) sw = ScrolledWindow() sw.add(fview) sw.set_shadow_type(Gtk.ShadowType.IN) sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) # only show the list if there are is more than one song if len(songs) > 1: sw.show_all() paned.pack1(sw, shrink=False, resize=True) for song in songs: fbasemodel.append(row=[_ListEntry(song)]) self.connect("changed", self.__on_changed) selection.select_all() paned.pack2(notebook, shrink=False, resize=True) csig = selection.connect('changed', self.__selection_changed) connect_destroy(library, 'changed', self.__on_library_changed, fbasemodel, fview) connect_destroy(library, 'removed', self.__on_library_removed, fbasemodel, selection, csig) self.emit('changed', songs) self.add(paned) paned.set_position(175) notebook.show() paned.show()
def PluginPreferences(self, parent): # Check if the queries file exists if not os.path.exists(self.path_query): return self._no_queries_frame() # Read saved searches from file self.queries = {} with open(self.path_query, 'r', encoding='utf-8') as query_file: for query_string in query_file: name = next(query_file).strip() self.queries[name] = Query(query_string.strip()) if not self.queries: # query_file is empty return self._no_queries_frame() main_vbox = Gtk.VBox(spacing=self.spacing_main) self.main_vbox = main_vbox # Saved search selection frame saved_search_vbox = Gtk.VBox(spacing=self.spacing_large) self.saved_search_vbox = saved_search_vbox for query_name, query in self.queries.items(): query_config = self.CONFIG_QUERY_PREFIX + query_name check_button = ConfigCheckButton(query_name, PM.CONFIG_SECTION, self._config_key(query_config)) check_button.set_active(self.config_get_bool(query_config)) saved_search_vbox.pack_start(check_button, False, False, 0) saved_search_scroll = self._expandable_scroll(min_h=0, max_h=300) saved_search_scroll.add(saved_search_vbox) frame = qltk.Frame( label=_('Synchronize the following saved searches:'), child=saved_search_scroll) main_vbox.pack_start(frame, False, False, 0) # Destination path entry field destination_entry = Gtk.Entry( placeholder_text=_('The absolute path to your export location'), text=config.get(PM.CONFIG_SECTION, self.CONFIG_PATH_KEY, '')) destination_entry.connect('changed', self._destination_path_changed) self.destination_entry = destination_entry # Destination path selection button destination_button = qltk.Button(label='', icon_name=Icons.FOLDER_OPEN) destination_button.connect('clicked', self._select_destination_path) # Destination path hbox destination_path_hbox = Gtk.HBox(spacing=self.spacing_small) destination_path_hbox.pack_start(destination_entry, True, True, 0) destination_path_hbox.pack_start(destination_button, False, False, 0) # Destination path information destination_warn_label = self._label_with_icon( _("All pre-existing files in the destination folder that aren't in " "the saved searches will be deleted."), Icons.DIALOG_WARNING) destination_info_label = self._label_with_icon( _('For devices mounted with MTP, export to a local destination ' 'folder, then transfer it to your device with rsync. ' 'Or, when syncing many files to an Android Device, use adb-sync, ' 'which is much faster.'), Icons.DIALOG_INFORMATION) # Destination path frame destination_vbox = Gtk.VBox(spacing=self.spacing_large) destination_vbox.pack_start(destination_path_hbox, False, False, 0) destination_vbox.pack_start(destination_warn_label, False, False, 0) destination_vbox.pack_start(destination_info_label, False, False, 0) frame = qltk.Frame(label=_('Destination path:'), child=destination_vbox) main_vbox.pack_start(frame, False, False, 0) # Export pattern frame export_pattern_combo = ComboBoxEntrySave( self.path_pattern, [self.default_export_pattern], title=_('Path Patterns'), edit_title=_(u'Edit saved patterns…')) export_pattern_combo.enable_clear_button() export_pattern_combo.show_all() export_pattern_entry = export_pattern_combo.get_child() export_pattern_entry.set_placeholder_text( _('The structure of the exported filenames, based on their tags')) export_pattern_entry.set_text( config.get(PM.CONFIG_SECTION, self.CONFIG_PATTERN_KEY, self.default_export_pattern)) export_pattern_entry.connect('changed', self._export_pattern_changed) self.export_pattern_entry = export_pattern_entry frame = qltk.Frame(label=_('Export pattern:'), child=export_pattern_combo) main_vbox.pack_start(frame, False, False, 0) # Start preview button preview_start_button = qltk.Button(label=_('Preview'), icon_name=Icons.VIEW_REFRESH) preview_start_button.set_visible(True) preview_start_button.connect('clicked', self._start_preview) self.preview_start_button = preview_start_button # Stop preview button preview_stop_button = qltk.Button(label=_('Stop preview'), icon_name=Icons.PROCESS_STOP) preview_stop_button.set_visible(False) preview_stop_button.set_no_show_all(True) preview_stop_button.connect('clicked', self._stop_preview) self.preview_stop_button = preview_stop_button # Details view column_types = [column[1] for column in self.model_cols.values()] self.model = Gtk.ListStore(*column_types) self.details_tree = details_tree = HintedTreeView(model=self.model) details_scroll = self._expandable_scroll() details_scroll.set_shadow_type(Gtk.ShadowType.IN) details_scroll.add(details_tree) self.renders = {} # Preview column: status render = Gtk.CellRendererText() column = self._tree_view_column(render, self._cdf_status, title=_('Status'), expand=False, sort=self._model_col_id('tag')) details_tree.append_column(column) # Preview column: file render = Gtk.CellRendererText() column = self._tree_view_column(render, self._cdf_source_path, title=_('Source File'), sort=self._model_col_id('filename')) details_tree.append_column(column) # Preview column: export path render = Gtk.CellRendererText() render.set_property('editable', True) render.connect('edited', self._row_edited) column = self._tree_view_column(render, self._cdf_export_path, title=_('Export Path'), sort=self._model_col_id('export')) details_tree.append_column(column) # Status labels self.status_operation = Gtk.Label(xalign=0.0, yalign=0.5, wrap=True, visible=False, no_show_all=True) self.status_progress = Gtk.Label(xalign=0.0, yalign=0.5, wrap=True, visible=False, no_show_all=True) self.status_duplicates = self._label_with_icon(_( 'Duplicate export paths detected! The export paths above can be ' 'edited before starting the synchronization.'), Icons.DIALOG_WARNING, visible=False) self.status_deletions = self._label_with_icon( _('Existing files in the destination path will be deleted!'), Icons.DIALOG_WARNING, visible=False) # Section for previewing exported files preview_vbox = Gtk.VBox(spacing=self.spacing_large) preview_vbox.pack_start(preview_start_button, False, False, 0) preview_vbox.pack_start(preview_stop_button, False, False, 0) preview_vbox.pack_start(details_scroll, True, True, 0) preview_vbox.pack_start(self.status_operation, False, False, 0) preview_vbox.pack_start(self.status_progress, False, False, 0) preview_vbox.pack_start(self.status_duplicates, False, False, 0) preview_vbox.pack_start(self.status_deletions, False, False, 0) main_vbox.pack_start(preview_vbox, True, True, 0) # Start sync button sync_start_button = qltk.Button(label=_('Start synchronization'), icon_name=Icons.DOCUMENT_SAVE) sync_start_button.set_sensitive(False) sync_start_button.set_visible(True) sync_start_button.connect('clicked', self._start_sync) self.sync_start_button = sync_start_button # Stop sync button sync_stop_button = qltk.Button(label=_('Stop synchronization'), icon_name=Icons.PROCESS_STOP) sync_stop_button.set_visible(False) sync_stop_button.set_no_show_all(True) sync_stop_button.connect('clicked', self._stop_sync) self.sync_stop_button = sync_stop_button # Section for the sync buttons sync_vbox = Gtk.VBox(spacing=self.spacing_large) sync_vbox.pack_start(sync_start_button, False, False, 0) sync_vbox.pack_start(sync_stop_button, False, False, 0) main_vbox.pack_start(sync_vbox, False, False, 0) return main_vbox
def __init__(self, prop, library): super(TrackNumbers, self).__init__(spacing=6) self.title = _("Track Numbers") self.set_border_width(12) hbox2 = gtk.HBox(spacing=12) hbox_start = gtk.HBox(spacing=3) label_start = gtk.Label(_("Start fro_m:")) label_start.set_use_underline(True) spin_start = gtk.SpinButton() spin_start.set_range(0, 999) spin_start.set_increments(1, 10) spin_start.set_value(1) label_start.set_mnemonic_widget(spin_start) hbox_start.pack_start(label_start) hbox_start.pack_start(spin_start) hbox_total = gtk.HBox(spacing=3) label_total = gtk.Label(_("_Total tracks:")) label_total.set_use_underline(True) spin_total = gtk.SpinButton() spin_total.set_range(0, 999) spin_total.set_increments(1, 10) label_total.set_mnemonic_widget(spin_total) hbox_total.pack_start(label_total) hbox_total.pack_start(spin_total) preview = qltk.Button(_("_Preview"), gtk.STOCK_CONVERT) hbox2.pack_start(hbox_start, expand=True, fill=False) hbox2.pack_start(hbox_total, expand=True, fill=False) hbox2.pack_start(preview, expand=False, fill=True) model = gtk.ListStore(object, str, str) view = HintedTreeView(model) self.pack_start(hbox2, expand=False) render = gtk.CellRendererText() column = TreeViewColumn(_('File'), render, text=1) column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE) view.append_column(column) render = gtk.CellRendererText() render.set_property('editable', True) column = TreeViewColumn(_('Track'), render, text=2) column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE) view.append_column(column) view.set_reorderable(True) w = gtk.ScrolledWindow() w.set_shadow_type(gtk.SHADOW_IN) w.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) w.add(view) self.pack_start(w) bbox = gtk.HButtonBox() bbox.set_spacing(12) bbox.set_layout(gtk.BUTTONBOX_END) save = gtk.Button(stock=gtk.STOCK_SAVE) save.connect_object( 'clicked', self.__save_files, prop, model, library) revert = gtk.Button(stock=gtk.STOCK_REVERT_TO_SAVED) bbox.pack_start(revert) bbox.pack_start(save) self.pack_start(bbox, expand=False) preview_args = [spin_start, spin_total, model, save, revert] preview.connect('clicked', self.__preview_tracks, *preview_args) revert.connect_object('clicked', self.__update, None, *preview_args[1:]) spin_total.connect( 'value-changed', self.__preview_tracks, *preview_args) spin_start.connect( 'value-changed', self.__preview_tracks, *preview_args) view.connect_object( 'drag-end', self.__class__.__preview_tracks, self, *preview_args) render.connect('edited', self.__row_edited, model, preview, save) prop.connect_object( 'changed', self.__class__.__update, self, spin_total, model, save, revert) self.show_all()
def __init__(self, prop, library): super(TrackNumbers, self).__init__(spacing=6) self.title = _("Track Numbers") self.set_border_width(12) hbox2 = Gtk.HBox(spacing=12) hbox_start = Gtk.HBox(spacing=3) label_start = Gtk.Label(label=_("Start fro_m:")) label_start.set_use_underline(True) spin_start = Gtk.SpinButton() spin_start.set_range(0, 999) spin_start.set_increments(1, 10) spin_start.set_value(1) label_start.set_mnemonic_widget(spin_start) hbox_start.pack_start(label_start, True, True, 0) hbox_start.pack_start(spin_start, True, True, 0) hbox_total = Gtk.HBox(spacing=3) label_total = Gtk.Label(label=_("_Total tracks:")) label_total.set_use_underline(True) spin_total = Gtk.SpinButton() spin_total.set_range(0, 999) spin_total.set_increments(1, 10) label_total.set_mnemonic_widget(spin_total) hbox_total.pack_start(label_total, True, True, 0) hbox_total.pack_start(spin_total, True, True, 0) preview = qltk.Button(_("_Preview"), Gtk.STOCK_CONVERT) hbox2.pack_start(hbox_start, True, False, 0) hbox2.pack_start(hbox_total, True, False, 0) hbox2.pack_start(preview, False, True, 0) model = Gtk.ListStore(object, str, str) view = HintedTreeView(model) self.pack_start(hbox2, False, True, 0) render = Gtk.CellRendererText() column = TreeViewColumn(_('File'), render, text=1) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) view.append_column(column) render = Gtk.CellRendererText() render.set_property('editable', True) column = TreeViewColumn(_('Track'), render, text=2) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) view.append_column(column) view.set_reorderable(True) w = Gtk.ScrolledWindow() w.set_shadow_type(Gtk.ShadowType.IN) w.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) w.add(view) self.pack_start(w, True, True, 0) bbox = Gtk.HButtonBox() bbox.set_spacing(12) bbox.set_layout(Gtk.ButtonBoxStyle.END) save = Gtk.Button(stock=Gtk.STOCK_SAVE) save.connect_object('clicked', self.__save_files, prop, model, library) revert = Gtk.Button(stock=Gtk.STOCK_REVERT_TO_SAVED) bbox.pack_start(revert, True, True, 0) bbox.pack_start(save, True, True, 0) self.pack_start(bbox, False, True, 0) preview_args = [spin_start, spin_total, model, save, revert] preview.connect('clicked', self.__preview_tracks, *preview_args) revert.connect_object('clicked', self.__update, None, *preview_args[1:]) spin_total.connect('value-changed', self.__preview_tracks, *preview_args) spin_start.connect('value-changed', self.__preview_tracks, *preview_args) view.connect_object('drag-end', self.__class__.__preview_tracks, self, *preview_args) render.connect('edited', self.__row_edited, model, preview, save) prop.connect_object('changed', self.__class__.__update, self, spin_total, model, save, revert) for child in self.get_children(): child.show_all()
def __init__(self, parent): if self.is_not_unique(): return super(PluginWindow, self).__init__() self.set_title(_("Plugins") + " - Quod Libet") self.set_border_width(12) self.set_default_size(655, 404) self.set_transient_for(parent) hbox = gtk.HBox(spacing=12) vbox = gtk.VBox(spacing=6) sw = gtk.ScrolledWindow() sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS) tv = HintedTreeView() model = gtk.ListStore(object, object) filter = model.filter_new() tv.set_model(filter) tv.set_rules_hint(True) filter_entry = ClearEntry() filter_entry.connect("changed", lambda s: filter.refilter()) combo_store = gtk.ListStore(str, int) filter_combo = gtk.ComboBox(combo_store) cell = gtk.CellRendererText() filter_combo.pack_start(cell, True) filter_combo.add_attribute(cell, "text", 0) filter_combo.connect("changed", lambda s: filter.refilter()) combo_sep = lambda model, iter: model[iter][1] == SEP filter_combo.set_row_separator_func(combo_sep) fb = gtk.HBox(spacing=6) fb.pack_start(filter_combo, expand=False) filter_entry.enable_clear_button() fb.pack_start(filter_entry) render = gtk.CellRendererToggle() def cell_data(col, render, model, iter): row = model[iter] render.set_active(row[1].enabled(row[0])) render.connect('toggled', self.__toggled, filter) column = gtk.TreeViewColumn("enabled", render) column.set_cell_data_func(render, cell_data) tv.append_column(column) render = gtk.CellRendererPixbuf() def cell_data2(col, render, model, iter): icon = getattr(model[iter][0], 'PLUGIN_ICON', gtk.STOCK_EXECUTE) if gtk.stock_lookup(icon): render.set_property('stock-id', icon) else: render.set_property('icon-name', icon) column = gtk.TreeViewColumn("image", render) column.set_cell_data_func(render, cell_data2) tv.append_column(column) render = gtk.CellRendererText() render.set_property('ellipsize', pango.ELLIPSIZE_END) render.set_property('xalign', 0.0) column = gtk.TreeViewColumn("name", render) def cell_data3(col, render, model, iter): render.set_property('text', model[iter][0].PLUGIN_NAME) column.set_cell_data_func(render, cell_data3) column.set_expand(True) tv.append_column(column) sw.add(tv) sw.set_shadow_type(gtk.SHADOW_IN) sw.set_size_request(250, -1) tv.set_headers_visible(False) bbox = gtk.HBox(homogeneous=True, spacing=12) errors = qltk.Button(_("Show _Errors"), gtk.STOCK_DIALOG_WARNING) errors.set_focus_on_click(False) bbox.pack_start(errors) refresh = gtk.Button(stock=gtk.STOCK_REFRESH) refresh.set_focus_on_click(False) bbox.pack_start(refresh) vbox.pack_start(fb, expand=False) vbox.pack_start(sw) vbox.pack_start(bbox, expand=False) hbox.pack_start(vbox, expand=False) selection = tv.get_selection() desc = WrapLabel() desc.set_selectable(True) selection.connect('changed', self.__description, desc) prefs = gtk.Frame() prefs.set_shadow_type(gtk.SHADOW_NONE) close = gtk.Button(stock=gtk.STOCK_CLOSE) close.connect('clicked', lambda *x: self.destroy()) bb_align = gtk.Alignment(0, 1, 1, 0) bb = gtk.HButtonBox() bb.set_layout(gtk.BUTTONBOX_END) bb.pack_start(close) bb_align.add(bb) vb2 = gtk.VBox(spacing=12) vb2.pack_start(desc, expand=False) vb2.pack_start(prefs, expand=False) vb2.pack_start(bb_align) hbox.pack_start(vb2, expand=True) self.add(hbox) selection.connect('changed', self.__preferences, prefs) refresh.connect('clicked', self.__refresh, tv, desc, errors, filter_combo, combo_store) errors.connect('clicked', self.__show_errors) tv.get_selection().emit('changed') refresh.clicked() self.connect('destroy', self.__destroy) filter.set_visible_func( self.__filter, (filter_entry, filter_combo, combo_store)) self.show_all() filter_entry.grab_focus() restore_id = config.get("memory", "plugin_selection") def restore_sel(row): return row[0].PLUGIN_ID == restore_id if not tv.select_by_func(restore_sel, one=True) and tv.get_model(): tv.set_cursor((0,))
def __init__(self, library, songs, parent=None): super(SongProperties, self).__init__(dialog=False) self.set_transient_for(qltk.get_top_parent(parent)) default_width = 600 config_suffix = "" if len(songs) <= 1: default_width -= 200 config_suffix += "single" self.set_default_size(default_width, 400) self.enable_window_tracking("quodlibet_properties", size_suffix=config_suffix) self.auto_save_on_change = config.getboolean( 'editing', 'auto_save_changes', False) paned = gtk.HPaned() notebook = qltk.Notebook() pages = [] pages.extend([Ctr(self, library) for Ctr in [EditTags, TagsFromPath, RenameFiles]]) if len(songs) > 1: pages.append(TrackNumbers(self, library)) for page in pages: notebook.append_page(page) self.set_border_width(12) fbasemodel = gtk.ListStore(object, str) fmodel = gtk.TreeModelSort(fbasemodel) fview = HintedTreeView(fmodel) fview.connect('button-press-event', self.__pre_selection_changed) fview.set_rules_hint(True) selection = fview.get_selection() selection.set_mode(gtk.SELECTION_MULTIPLE) self.__save = None if len(songs) > 1: render = gtk.CellRendererText() c1 = gtk.TreeViewColumn(_('File'), render, text=1) render.set_property('ellipsize', pango.ELLIPSIZE_END) c1.set_sort_column_id(1) fview.append_column(c1) sw = gtk.ScrolledWindow() sw.add(fview) sw.set_shadow_type(gtk.SHADOW_IN) sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) sw.show_all() paned.pack1(sw, shrink=True, resize=True) # Invisible selections behave a little strangely. So, when # handling this selection, there's a lot of if len(model) == 1 # checks that "hardcode" the first row being selected. for song in songs: fbasemodel.append(row=[song, util.fsdecode(song("~basename"))]) self.connect_object('changed', SongProperties.__set_title, self) selection.select_all() paned.pack2(notebook, shrink=False, resize=True) csig = selection.connect('changed', self.__selection_changed) s1 = library.connect( 'changed', self.__refresh, fbasemodel, fview) s2 = library.connect( 'removed', self.__remove, fbasemodel, selection, csig) self.connect_object('destroy', library.disconnect, s1) self.connect_object('destroy', library.disconnect, s2) self.connect_object('changed', self.set_pending, None) self.emit('changed', songs) self.add(paned) paned.set_position(175) notebook.show() paned.show() self.show()