def test_without_model(self): column = TreeViewColumn() self.c.append_column(column) column = self.c.get_columns()[0] column.set_sort_indicator(True) self.c.set_search_column(0) with self.c.without_model() as model: self.assertEqual(model, self.m) self.assertTrue(self.c.get_model() is None) self.assertEqual(self.c.get_search_column(), 0) column = self.c.get_columns()[0] self.assertTrue(column.get_sort_indicator())
def __init__(self, parent, library): super(EditTags, self).__init__(spacing=12) self.title = _("Edit Tags") self.set_border_width(12) model = Gtk.ListStore(str, str, bool, bool, bool, str, bool, str) view = RCMHintedTreeView(model) selection = view.get_selection() render = Gtk.CellRendererPixbuf() column = TreeViewColumn(_("Write"), render) style = view.get_style() pixbufs = [ style.lookup_icon_set(stock).render_icon(style, Gtk.TextDirection.NONE, state, Gtk.IconSize.MENU, view, None) for state in (Gtk.StateType.INSENSITIVE, Gtk.StateType.NORMAL) for stock in (Gtk.STOCK_EDIT, Gtk.STOCK_DELETE) ] def cdf_write(col, rend, model, iter, (write, delete)): row = model[iter] if row[CANEDIT]: rend.set_property('stock-id', None) rend.set_property('pixbuf', pixbufs[2 * row[EDITED] + row[DELETED]]) else: rend.set_property('stock-id', Gtk.STOCK_DIALOG_AUTHENTICATION)
def __init__(self, parent, library): super(RenameFiles, self).__init__(const.NBP, const.NBP_EXAMPLES.split("\n")) column = TreeViewColumn(_('File'), Gtk.CellRendererText(), text=1) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) self.view.append_column(column) render = Gtk.CellRendererText() render.set_property('editable', True) column = TreeViewColumn(_('New Name'), render, text=2) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) self.view.append_column(column) self.preview.connect_object('clicked', self.__preview, None) parent.connect_object('changed', self.__class__.__preview, self) self.save.connect_object('clicked', self.__rename, library) render.connect('edited', self.__row_edited)
def __init__(self, parent, library): super(RenameFiles, self).__init__( const.NBP, const.NBP_EXAMPLES.split("\n")) column = TreeViewColumn( _('File'), gtk.CellRendererText(), text=1) column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE) self.view.append_column(column) render = gtk.CellRendererText() render.set_property('editable', True) column = TreeViewColumn(_('New Name'), render, text=2) column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE) self.view.append_column(column) self.preview.connect_object('clicked', self.__preview, None) parent.connect_object('changed', self.__class__.__preview, self) self.save.connect_object('clicked', self.__rename, library) render.connect('edited', self.__row_edited)
def __init__(self, initial=None, filter=filesel_filter, folders=None): """ initial -- a path to a file which should be shown initially filter -- a function which filters paths shown in the file list folders -- list of shown folders in the directory tree """ super(FileSelector, self).__init__(orientation=Gtk.Orientation.VERTICAL) self.__filter = filter if initial is not None: assert isinstance(initial, fsnative) if initial and os.path.isfile(initial): initial = os.path.dirname(initial) dirlist = DirectoryTree(initial, folders=folders) model = ObjectStore() filelist = AllTreeView(model=model) filelist.connect("draw", self.__restore_scroll_pos_on_draw) column = TreeViewColumn(title=_("Songs")) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) render = Gtk.CellRendererPixbuf() render.props.xpad = 3 def cell_icon(column, cell, model, iter_, userdata): value = model.get_value(iter_) if is_image(value): cell.set_property('icon-name', Icons.IMAGE_X_GENERIC) else: cell.set_property('icon-name', Icons.AUDIO_X_GENERIC) column.set_cell_data_func(render, cell_icon) column.pack_start(render, False) render = Gtk.CellRendererText() if filelist.supports_hints(): render.set_property('ellipsize', Pango.EllipsizeMode.END) column.pack_start(render, True) def cell_data(column, cell, model, iter_, userdata): value = model.get_value(iter_) cell.set_property('text', fsn2text(os.path.basename(value))) column.set_cell_data_func(render, cell_data) filelist.append_column(column) filelist.set_rules_hint(True) filelist.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE) filelist.set_search_equal_func(search_func, False) filelist.set_search_column(0) self.__sig = filelist.get_selection().connect('changed', self.__changed) dirlist.get_selection().connect('changed', self.__dir_selection_changed, filelist) dirlist.get_selection().emit('changed') def select_all_files(view, path, col, fileselection): view.expand_row(path, False) fileselection.select_all() dirlist.connect('row-activated', select_all_files, filelist.get_selection()) sw = ScrolledWindow() sw.add(dirlist) sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) sw.set_shadow_type(Gtk.ShadowType.IN) self.pack1(sw, resize=True) sw = ScrolledWindow() sw.add(filelist) sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) sw.set_shadow_type(Gtk.ShadowType.IN) self.pack2(sw, resize=True)
def __init__(self, parent, library): super(RenameFiles, self).__init__(spacing=6) self.__skip_interactive = False self.set_border_width(12) hbox = Gtk.HBox(spacing=6) cbes_defaults = NBP_EXAMPLES.split("\n") self.combo = ComboBoxEntrySave(NBP, cbes_defaults, title=_("Path Patterns"), edit_title=_(u"Edit saved patterns…")) self.combo.show_all() hbox.pack_start(self.combo, True, True, 0) self.preview = qltk.Button(_("_Preview"), Icons.VIEW_REFRESH) self.preview.show() hbox.pack_start(self.preview, False, True, 0) self.pack_start(hbox, False, True, 0) self.combo.get_child().connect('changed', self._changed) model = ObjectStore() self.view = Gtk.TreeView(model=model) self.view.show() sw = Gtk.ScrolledWindow() sw.set_shadow_type(Gtk.ShadowType.IN) sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) sw.add(self.view) self.pack_start(sw, True, True, 0) self.pack_start(Gtk.VBox(), False, True, 0) # rename options rename_options = Gtk.HBox() # file name options filter_box = FilterPluginBox(self.handler, self.FILTERS) filter_box.connect("preview", self.__filter_preview) filter_box.connect("changed", self.__filter_changed) self.filter_box = filter_box frame_filename_options = Frame(_("File names"), filter_box) frame_filename_options.show_all() rename_options.pack_start(frame_filename_options, False, True, 0) # album art options albumart_box = Gtk.VBox() # move art moveart_box = Gtk.VBox() self.moveart = ConfigCheckButton( _('_Move album art'), "rename", "move_art", populate=True) self.moveart.set_tooltip_text( _("See '[albumart] filenames' config entry " + "for image search strings")) self.moveart.show() moveart_box.pack_start(self.moveart, False, True, 0) self.moveart_overwrite = ConfigCheckButton( _('_Overwrite album art at target'), "rename", "move_art_overwrite", populate=True) self.moveart_overwrite.show() moveart_box.pack_start(self.moveart_overwrite, False, True, 0) albumart_box.pack_start(moveart_box, False, True, 0) # remove empty removeemptydirs_box = Gtk.VBox() self.removeemptydirs = ConfigCheckButton( _('_Remove empty directories'), "rename", "remove_empty_dirs", populate=True) self.removeemptydirs.show() removeemptydirs_box.pack_start(self.removeemptydirs, False, True, 0) albumart_box.pack_start(removeemptydirs_box, False, True, 0) frame_albumart_options = Frame(_("Album art"), albumart_box) frame_albumart_options.show_all() rename_options.pack_start(frame_albumart_options, False, True, 0) self.pack_start(rename_options, False, True, 0) # Save button self.save = Button(_("_Save"), Icons.DOCUMENT_SAVE) self.save.show() bbox = Gtk.HButtonBox() bbox.set_layout(Gtk.ButtonBoxStyle.END) bbox.pack_start(self.save, True, True, 0) self.pack_start(bbox, False, True, 0) render = Gtk.CellRendererText() column = TreeViewColumn(title=_('File')) column.pack_start(render, True) 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) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) self.view.append_column(column) render = Gtk.CellRendererText() render.set_property('editable', True) column = TreeViewColumn(title=_('New Name')) column.pack_start(render, True) def cell_data_new_name(column, cell, model, iter_, data): entry = model.get_value(iter_) cell.set_property("text", entry.new_name or u"") column.set_cell_data_func(render, cell_data_new_name) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) self.view.append_column(column) connect_obj(self.preview, 'clicked', self._preview, None) connect_obj(parent, 'changed', self.__class__._preview, self) connect_obj(self.save, 'clicked', self._rename, library) render.connect('edited', self.__row_edited) for child in self.get_children(): child.show()
def __init__(self, initial=None, folders=None): """ initial -- the path to select/scroll to folders -- a list of paths to show in the tree view, None will result in a separator. """ model = ObjectTreeStore() super(DirectoryTree, self).__init__(model=model) if initial is not None: assert is_fsnative(initial) column = TreeViewColumn(title=_("Folders")) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) render = Gtk.CellRendererPixbuf() render.set_property('icon-name', Icons.FOLDER) render.props.xpad = 3 column.pack_start(render, False) render = Gtk.CellRendererText() if self.supports_hints(): render.set_property('ellipsize', Pango.EllipsizeMode.END) column.pack_start(render, True) def cell_data(column, cell, model, iter_, userdata): value = model.get_value(iter_) if value is not None: text = fsdecode(os.path.basename(value) or value) cell.set_property('text', text) column.set_cell_data_func(render, cell_data) self.append_column(column) self.set_search_equal_func(search_func, True) self.set_search_column(0) if folders is None: folders = [] for path in folders: niter = model.append(None, [path]) if path is not None: assert is_fsnative(path) model.append(niter, ["dummy"]) self.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE) self.connect( 'test-expand-row', DirectoryTree.__expanded, model) self.set_row_separator_func( lambda model, iter_, data: model.get_value(iter_) is None, None) if initial: self.go_to(initial) menu = Gtk.Menu() m = qltk.MenuItem(_(u"_New Folder…"), Icons.DOCUMENT_NEW) m.connect('activate', self.__mkdir) menu.append(m) m = qltk.MenuItem(_("_Delete"), Icons.EDIT_DELETE) m.connect('activate', self.__rmdir) menu.append(m) m = qltk.MenuItem(_("_Refresh"), Icons.VIEW_REFRESH) m.connect('activate', self.__refresh) menu.append(m) m = qltk.MenuItem(_("_Select All Subfolders"), Icons.FOLDER) m.connect('activate', self.__expand) menu.append(m) menu.show_all() connect_obj(self, 'popup-menu', self.__popup_menu, menu) # Allow to drag and drop files from outside targets = [ ("text/uri-list", 0, 42) ] targets = [Gtk.TargetEntry.new(*t) for t in targets] self.drag_dest_set(Gtk.DestDefaults.ALL, targets, Gdk.DragAction.COPY) self.connect('drag-data-received', self.__drag_data_received)
class EditTags(Gtk.VBox): _SAVE_BUTTON_KEY = 'ql-save' _REVERT_BUTTON_KEY = 'ql-revert' # Translators: translate only to override the text # for the tag "save" button _SAVE_BUTTON_TEXT = _('ql-save') # Translators: translate only to override the for the tag "revert" button _REVERT_BUTTON_TEXT = _('ql-revert') handler = EditTagsPluginHandler() @classmethod def init_plugins(cls): PluginManager.instance.register_handler(cls.handler) def __init__(self, parent, library): super(EditTags, self).__init__(spacing=12) self.title = _("Edit Tags") self.set_border_width(12) model = Gtk.ListStore(str, str, bool, bool, bool, str, bool, str) view = RCMHintedTreeView(model) selection = view.get_selection() render = Gtk.CellRendererPixbuf() column = TreeViewColumn(_("Write"), render) style = view.get_style() pixbufs = [ style.lookup_icon_set(stock).render_icon(style, Gtk.TextDirection.NONE, state, Gtk.IconSize.MENU, view, None) for state in (Gtk.StateType.INSENSITIVE, Gtk.StateType.NORMAL) for stock in (Gtk.STOCK_EDIT, Gtk.STOCK_DELETE) ] def cdf_write(col, rend, model, iter, (write, delete)): row = model[iter] if row[CANEDIT]: rend.set_property('stock-id', None) rend.set_property('pixbuf', pixbufs[2 * row[EDITED] + row[DELETED]]) else: rend.set_property('stock-id', Gtk.STOCK_DIALOG_AUTHENTICATION) column.set_cell_data_func(render, cdf_write, (2, 4)) view.append_column(column) render = Gtk.CellRendererText() column = TreeViewColumn(_('Tag'), render, text=0, editable=3, strikethrough=4) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) render.set_property('editable', True) render.connect('edited', self.__edit_tag_name, model) render.connect('editing-started', self.__tag_editing_started, model, library) view.append_column(column) render = Gtk.CellRendererText() render.set_property('ellipsize', Pango.EllipsizeMode.END) render.set_property('editable', True) render.connect('edited', self.__edit_tag, model) render.connect('editing-started', self.__value_editing_started, model, library) render.markup = 1 column = TreeViewColumn(_('Value'), render, markup=1, editable=3, strikethrough=4) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) view.append_column(column) sw = Gtk.ScrolledWindow() sw.set_shadow_type(Gtk.ShadowType.IN) sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) sw.add(view) self.pack_start(sw, True, True, 0) # Add and Remove [tags] buttons buttonbox = Gtk.HBox(spacing=18) bbox1 = Gtk.HButtonBox() bbox1.set_spacing(6) bbox1.set_layout(Gtk.ButtonBoxStyle.START) add = Gtk.Button(stock=Gtk.STOCK_ADD) add.set_focus_on_click(False) add.connect('clicked', self.__add_tag, model, library) bbox1.pack_start(add, True, True, 0) # Remove button remove = Gtk.Button(stock=Gtk.STOCK_REMOVE) remove.set_focus_on_click(False) remove.connect('clicked', self.__remove_tag, view) remove.set_sensitive(False) bbox1.pack_start(remove, True, True, 0) # Revert and save buttons # Both can have customised translated text (and thus accels) bbox2 = Gtk.HButtonBox() bbox2.set_spacing(6) bbox2.set_layout(Gtk.ButtonBoxStyle.END) revert = (Gtk.Button( stock=Gtk.STOCK_REVERT_TO_SAVED) if self._REVERT_BUTTON_KEY == self._REVERT_BUTTON_TEXT else Gtk.Button( label=self._REVERT_BUTTON_TEXT, use_underline=True)) revert.set_sensitive(False) # Save button. save = (Gtk.Button(stock=Gtk.STOCK_SAVE) if self._SAVE_BUTTON_TEXT == self._SAVE_BUTTON_KEY else Gtk.Button(label=self._SAVE_BUTTON_TEXT, use_underline=True)) save.set_sensitive(False) self.save = save bbox2.pack_start(revert, True, True, 0) bbox2.pack_start(save, True, True, 0) buttonbox.pack_start(bbox1, True, True, 0) buttonbox.pack_start(bbox2, True, True, 0) self.pack_start(buttonbox, False, True, 0) UPDATE_ARGS = [view, buttonbox, model, add, [save, revert, remove]] parent.connect_object('changed', self.__class__.__update, self, *UPDATE_ARGS) revert.connect_object('clicked', self.__update, None, *UPDATE_ARGS) revert.connect_object('clicked', parent.set_pending, None) save.connect('clicked', self.__save_files, revert, model, library) save.connect_object('clicked', parent.set_pending, None) for sig in ['row-inserted', 'row-deleted', 'row-changed']: model.connect(sig, self.__enable_save, [save, revert]) model.connect_object(sig, parent.set_pending, save) view.connect('popup-menu', self.__popup_menu, parent) view.connect('button-press-event', self.__button_press) view.connect('key-press-event', self.__view_key_press_event) selection.connect('changed', self.__tag_select, remove) selection.set_mode(Gtk.SelectionMode.MULTIPLE) for child in self.get_children(): child.show_all()
def __init__(self, initial=None, folders=None): """ initial -- the path to select/scroll to folders -- a list of paths to show in the tree view, None will result in a separator. """ model = ObjectTreeStore() super(DirectoryTree, self).__init__(model=model) if initial is not None: assert is_fsnative(initial) column = TreeViewColumn(_("Folders")) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) render = Gtk.CellRendererPixbuf() render.set_property('stock_id', Gtk.STOCK_DIRECTORY) column.pack_start(render, False) render = Gtk.CellRendererText() if self.supports_hints(): render.set_property('ellipsize', Pango.EllipsizeMode.END) column.pack_start(render, True) def cell_data(column, cell, model, iter_, userdata): value = model.get_value(iter_) if value is not None: text = fsdecode(os.path.basename(value) or value) cell.set_property('text', text) column.set_cell_data_func(render, cell_data) self.append_column(column) self.set_search_equal_func(search_func, True) self.set_search_column(0) if folders is None: folders = [] for path in folders: niter = model.append(None, [path]) if path is not None: assert is_fsnative(path) model.append(niter, ["dummy"]) self.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE) self.connect('test-expand-row', DirectoryTree.__expanded, model) self.set_row_separator_func( lambda model, iter_, data: model.get_value(iter_) is None, None) if initial: self.go_to(initial) menu = Gtk.Menu() m = qltk.MenuItem(_(u"_New Folder…"), Gtk.STOCK_NEW) m.connect('activate', self.__mkdir) menu.append(m) m = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_DELETE, None) m.connect('activate', self.__rmdir) menu.append(m) m = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_REFRESH, None) m.connect('activate', self.__refresh) menu.append(m) m = qltk.MenuItem(_("_Select All Subfolders"), Gtk.STOCK_DIRECTORY) m.connect('activate', self.__expand) menu.append(m) menu.show_all() connect_obj(self, 'popup-menu', self.__popup_menu, menu) # Allow to drag and drop files from outside targets = [("text/uri-list", 0, 42)] targets = [Gtk.TargetEntry.new(*t) for t in targets] self.drag_dest_set(Gtk.DestDefaults.ALL, targets, Gdk.DragAction.COPY) self.connect('drag-data-received', self.__drag_data_received)
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, library, prefs, next_=None): super(Pane, self).__init__() self.set_fixed_height_mode(True) self.config = PaneConfig(prefs) self.__next = next_ self.__restore_values = None self.__no_fill = 0 column = TreeViewColumn(self.config.title) column.set_use_markup(True) column.set_sizing(Gtk.TreeViewColumnSizing.FIXED) column.set_fixed_width(50) render = Gtk.CellRendererText() render.set_property('ellipsize', Pango.EllipsizeMode.END) column.pack_start(render, True) def text_cdf(column, cell, model, iter_, data): entry = model.get_value(iter_) is_markup, text = entry.get_text(self.config) if is_markup: cell.markup = text cell.set_property('markup', text) else: cell.markup = None cell.set_property('text', text) column.set_cell_data_func(render, text_cdf) render_count = Gtk.CellRendererText() render_count.set_property('xalign', 1.0) column.pack_start(render_count, False) def count_cdf(column, cell, model, iter_, data): entry = model.get_value(iter_) markup = entry.get_count_text(self.config) cell.markup = markup cell.set_property('markup', markup) column.set_cell_data_func(render_count, count_cdf) self.append_column(column) model = PaneModel(self.config) self.set_model(model) self.set_search_equal_func(self.__search_func, None) self.set_search_column(0) self.set_enable_search(True) selection = self.get_selection() selection.set_mode(Gtk.SelectionMode.MULTIPLE) self.__sig = selection.connect('changed', self.__selection_changed) s = self.connect('popup-menu', self.__popup_menu, library) connect_obj(self, 'destroy', self.disconnect, s) targets = [ ("text/x-quodlibet-songs", Gtk.TargetFlags.SAME_APP, self.TARGET_INFO_QL), ("text/uri-list", 0, self.TARGET_INFO_URI_LIST) ] targets = [Gtk.TargetEntry.new(*t) for t in targets] self.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, targets, Gdk.DragAction.COPY) self.connect("drag-data-get", self.__drag_data_get) self.connect("destroy", self.__destroy) self.connect("key-press-event", self.__key_pressed)
def __init__(self, prefs, next, library): super(Pane, self).__init__() self.set_fixed_height_mode(True) self.pattern = PanePattern(prefs) self.tags = self.pattern.tags self.__next = next self.__model = model = gtk.ListStore(int, object) self.__sort_cache = {} self.__key_cache = {} column = TreeViewColumn(self.pattern.title) column.set_use_markup(True) column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) column.set_fixed_width(50) column.pack_start(self.__render) column.set_cell_data_func(self.__render, self.__text_cdf, self.pattern.has_markup) column.pack_start(self.__render_count, expand=False) column.set_cell_data_func(self.__render_count, self.__count_cdf, self.pattern.format_display) self.append_column(column) self.set_model(model) self.set_search_equal_func(self.__search_func) selection = self.get_selection() selection.set_mode(gtk.SELECTION_MULTIPLE) self.__sig = selection.connect('changed', self.__selection_changed) s = self.connect('popup-menu', self.__popup_menu, library) self.connect_object('destroy', self.disconnect, s) targets = [("text/x-quodlibet-songs", gtk.TARGET_SAME_APP, 1), ("text/uri-list", 0, 2)] self.drag_source_set( gtk.gdk.BUTTON1_MASK, targets, gtk.gdk.ACTION_COPY) self.connect("drag-data-get", self.__drag_data_get) self.connect("destroy", self.__destroy)
def __init__(self, parent, library): super(RenameFiles, self).__init__(spacing=6) self.set_border_width(12) hbox = Gtk.HBox(spacing=6) cbes_defaults = NBP_EXAMPLES.split("\n") self.combo = ComboBoxEntrySave(NBP, cbes_defaults, title=_("Path Patterns"), edit_title=_(u"Edit saved patterns…")) self.combo.show_all() hbox.pack_start(self.combo, True, True, 0) self.preview = qltk.Button(_("_Preview"), Icons.VIEW_REFRESH) self.preview.show() hbox.pack_start(self.preview, False, True, 0) self.pack_start(hbox, False, True, 0) self.combo.get_child().connect('changed', self._changed) model = ObjectStore() self.view = Gtk.TreeView(model=model) self.view.show() sw = Gtk.ScrolledWindow() sw.set_shadow_type(Gtk.ShadowType.IN) sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) sw.add(self.view) self.pack_start(sw, True, True, 0) self.pack_start(Gtk.VBox(), False, True, 0) filter_box = FilterPluginBox(self.handler, self.FILTERS) filter_box.connect("preview", self.__filter_preview) filter_box.connect("changed", self.__filter_changed) self.filter_box = filter_box self.pack_start(filter_box, False, True, 0) # Save button self.save = Button(_("_Save"), Icons.DOCUMENT_SAVE) self.save.show() bbox = Gtk.HButtonBox() bbox.set_layout(Gtk.ButtonBoxStyle.END) bbox.pack_start(self.save, True, True, 0) self.pack_start(bbox, False, True, 0) render = Gtk.CellRendererText() column = TreeViewColumn(_('File'), render) 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) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) self.view.append_column(column) render = Gtk.CellRendererText() render.set_property('editable', True) column = TreeViewColumn(_('New Name'), render) def cell_data_new_name(column, cell, model, iter_, data): entry = model.get_value(iter_) cell.set_property("text", entry.new_name or u"") column.set_cell_data_func(render, cell_data_new_name) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) self.view.append_column(column) connect_obj(self.preview, 'clicked', self.__preview, None) connect_obj(parent, 'changed', self.__class__.__preview, self) connect_obj(self.save, 'clicked', self.__rename, library) render.connect('edited', self.__row_edited) for child in self.get_children(): child.show()
def test_main(self): TreeViewColumn(title="foo") area = Gtk.CellAreaBox() tvc = TreeViewColumn(cell_area=area) self.assertEqual(tvc.get_area(), area)
def __init__(self, initial=None, folders=None): super(DirectoryTree, self).__init__(gtk.TreeStore(str)) column = TreeViewColumn(_("Folders")) column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE) render = gtk.CellRendererPixbuf() render.set_property('stock_id', gtk.STOCK_DIRECTORY) column.pack_start(render, expand=False) render = gtk.CellRendererText() column.pack_start(render) column.set_cell_data_func(render, self.cell_data) column.set_attributes(render, text=0) self.append_column(column) self.set_search_equal_func(search_func, True) if folders is None: folders = [] if os.name == "nt": try: from win32com.shell import shell, shellcon as con import pywintypes except ImportError: pass else: if folders: folders.append(None) try: desktop = shell.SHGetFolderPath(0, con.CSIDL_DESKTOP, 0, 0) except pywintypes.com_error: pass else: folders.append(desktop) folders.append(const.HOME) try: music = shell.SHGetFolderPath(0, con.CSIDL_MYMUSIC, 0, 0) except pywintypes.com_error: pass else: folders.append(music) if folders: folders.append(None) drives = [letter + ":\\" for letter in "CDEFGHIJKLMNOPQRSTUVWXYZ"] map(folders.append, filter(os.path.isdir, drives)) else: if folders: folders.append(None) folders.extend([const.HOME, "/"]) # Read in the GTK bookmarks list; gjc says this is the right way try: f = file(os.path.join(const.HOME, ".gtk-bookmarks")) except EnvironmentError: pass else: folders.append(None) for line in (l for l in f.readlines() if l.strip()): folder_url = line.split()[0] folders.append(urlparse.urlsplit(folder_url)[2]) def is_folder(filename): return filename is None or os.path.isdir(filename) folders = filter(is_folder, folders) if folders[-1] is None: folders.pop() for path in folders: niter = self.get_model().append(None, [path]) if path is not None: self.get_model().append(niter, ["dummy"]) self.get_selection().set_mode(gtk.SELECTION_MULTIPLE) self.connect( 'test-expand-row', DirectoryTree.__expanded, self.get_model()) self.set_row_separator_func(lambda model, iter: model[iter][0] is None) if initial: self.go_to(initial) menu = gtk.Menu() m = qltk.MenuItem(_("_New Folder..."), gtk.STOCK_NEW) m.connect('activate', self.__mkdir) menu.append(m) m = gtk.ImageMenuItem(gtk.STOCK_DELETE) m.connect('activate', self.__rmdir) menu.append(m) m = gtk.ImageMenuItem(gtk.STOCK_REFRESH) m.connect('activate', self.__refresh) menu.append(m) m = qltk.MenuItem(_("_Select All Subfolders"), gtk.STOCK_DIRECTORY) m.connect('activate', self.__expand) menu.append(m) menu.show_all() self.connect_object('popup-menu', self.__popup_menu, menu)
def __init__(self, initial=None, filter=filesel_filter, folders=None): super(FileSelector, self).__init__() self.__filter = filter if initial and os.path.isfile(initial): initial = os.path.dirname(initial) dirlist = DirectoryTree(initial, folders=folders) filelist = AllTreeView(gtk.ListStore(str)) column = TreeViewColumn(_("Songs")) column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE) render = gtk.CellRendererPixbuf() render.set_property('stock_id', gtk.STOCK_FILE) render.props.xpad = 3 column.pack_start(render, expand=False) render = gtk.CellRendererText() column.pack_start(render) column.set_cell_data_func(render, self.cell_data) column.set_attributes(render, text=0) filelist.append_column(column) filelist.set_rules_hint(True) filelist.get_selection().set_mode(gtk.SELECTION_MULTIPLE) filelist.set_search_equal_func(search_func, False) self.__sig = filelist.get_selection().connect( 'changed', self.__changed) dirlist.get_selection().connect( 'changed', self.__fill, filelist) dirlist.get_selection().emit('changed') def select_all_files(view, path, col, fileselection): view.expand_row(path, False) fileselection.select_all() dirlist.connect('row-activated', select_all_files, filelist.get_selection()) sw = ScrolledWindow() sw.add(dirlist) sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) sw.set_shadow_type(gtk.SHADOW_IN) self.pack1(sw, resize=True) sw = ScrolledWindow() sw.add(filelist) sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) sw.set_shadow_type(gtk.SHADOW_IN) self.pack2(sw, resize=True)
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 __preview(self, songs): if songs is None: songs = [row[0].song for row in (self.view.get_model() or [])] if songs: pattern_text = self.combo.get_child().get_text().decode("utf-8") else: pattern_text = "" try: pattern = TagsFromPattern(pattern_text) except re.error: qltk.ErrorMessage( self, _("Invalid pattern"), _("The pattern\n\t<b>%s</b>\nis invalid. " "Possibly it contains the same tag twice or " "it has unbalanced brackets (< / >).") % (util.escape(pattern_text))).run() return else: if pattern_text: self.combo.prepend_text(pattern_text) self.combo.write(const.TBP) invalid = [] for header in pattern.headers: if not min([song.can_change(header) for song in songs]): invalid.append(header) if len(invalid) and songs: if len(invalid) == 1: title = _("Invalid tag") msg = _("Invalid tag <b>%s</b>\n\nThe files currently" " selected do not support editing this tag.") else: title = _("Invalid tags") msg = _("Invalid tags <b>%s</b>\n\nThe files currently" " selected do not support editing these tags.") qltk.ErrorMessage(self, title, msg % ", ".join(invalid)).run() pattern = TagsFromPattern("") self.view.set_model(None) model = ObjectStore() for col in self.view.get_columns(): self.view.remove_column(col) render = Gtk.CellRendererText() col = TreeViewColumn(_('File'), render) col.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) col.set_cell_data_func(render, cell_data_file) def cell_data_header(column, cell, model, iter_, header): entry = model.get_value(iter_) cell.set_property("text", entry.get_match(header)) self.view.append_column(col) for i, header in enumerate(pattern.headers): render = Gtk.CellRendererText() render.set_property('editable', True) render.connect('edited', self.__row_edited, model, header) escaped_title = header.replace("_", "__") col = Gtk.TreeViewColumn(escaped_title, render) col.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) col.set_cell_data_func(render, cell_data_header, header) self.view.append_column(col) for song in songs: entry = ListEntry(song) match = pattern.match(song) for h in pattern.headers: text = match.get(h, '') for f in self.filter_box.filters: if f.active: text = f.filter(h, text) if not song.can_multiple_values(h): text = u", ".join(text.split("\n")) entry.matches[h] = text model.append([entry]) # save for last to potentially save time if songs: self.view.set_model(model) self.preview.set_sensitive(False) self.save.set_sensitive(len(pattern.headers) > 0)
def __init__(self, initial=None, filter=filesel_filter, folders=None): """ initial -- a path to a file which should be shown initially filter -- a function which filters paths shown in the file list folders -- list of shown folders in the directory tree """ super(FileSelector, self).__init__() self.__filter = filter if initial is not None: initial = util.fsnative(initial) if initial and os.path.isfile(initial): initial = os.path.dirname(initial) dirlist = DirectoryTree(initial, folders=folders) model = ObjectStore() filelist = AllTreeView(model) column = TreeViewColumn(_("Songs")) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) render = Gtk.CellRendererPixbuf() render.set_property('stock_id', Gtk.STOCK_FILE) render.props.xpad = 3 column.pack_start(render, False) render = Gtk.CellRendererText() column.pack_start(render, True) def cell_data(column, cell, model, iter_, userdata): value = model.get_value(iter_) cell.set_property('text', fsdecode(os.path.basename(value))) column.set_cell_data_func(render, cell_data) filelist.append_column(column) filelist.set_rules_hint(True) filelist.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE) filelist.set_search_equal_func(search_func, False) # Allow to drag and drop files from outside filelist.enable_model_drag_dest([], Gdk.DragAction.COPY) filelist.drag_dest_add_uri_targets() filelist.connect('drag-data-received', self.__file_dropped) self.__sig = filelist.get_selection().connect('changed', self.__changed) dirlist.get_selection().connect('changed', self.__dir_selection_changed, filelist) dirlist.get_selection().emit('changed') def select_all_files(view, path, col, fileselection): view.expand_row(path, False) fileselection.select_all() dirlist.connect('row-activated', select_all_files, filelist.get_selection()) sw = ScrolledWindow() sw.add(dirlist) sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) sw.set_shadow_type(Gtk.ShadowType.IN) self.pack1(sw, resize=True) sw = ScrolledWindow() sw.add(filelist) sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) sw.set_shadow_type(Gtk.ShadowType.IN) self.pack2(sw, resize=True)
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, 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, initial=None, folders=None): """ initial -- the path to select/scroll to folders -- a list of paths to show in the tree view, None will result in a separator. """ model = ObjectTreeStore() super(DirectoryTree, self).__init__(model=model) if initial is not None: initial = util.fsnative(initial) column = TreeViewColumn(_("Folders")) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) render = Gtk.CellRendererPixbuf() render.set_property('stock_id', Gtk.STOCK_DIRECTORY) column.pack_start(render, False) render = Gtk.CellRendererText() column.pack_start(render, True) def cell_data(column, cell, model, iter_, userdata): value = model.get_value(iter_) if value is not None: text = fsdecode(os.path.basename(value) or value) cell.set_property('text', text) column.set_cell_data_func(render, cell_data) self.append_column(column) self.set_search_equal_func(search_func, True) if folders is None: folders = [] for path in folders: niter = model.append(None, [path]) if path is not None: model.append(niter, ["dummy"]) self.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE) self.connect('test-expand-row', DirectoryTree.__expanded, model) self.set_row_separator_func( lambda model, iter_, data: model.get_value(iter_) is None, None) if initial: self.go_to(initial) menu = Gtk.Menu() m = qltk.MenuItem(_("_New Folder..."), Gtk.STOCK_NEW) m.connect('activate', self.__mkdir) menu.append(m) m = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_DELETE, None) m.connect('activate', self.__rmdir) menu.append(m) m = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_REFRESH, None) m.connect('activate', self.__refresh) menu.append(m) m = qltk.MenuItem(_("_Select All Subfolders"), Gtk.STOCK_DIRECTORY) m.connect('activate', self.__expand) menu.append(m) menu.show_all() self.connect_object('popup-menu', self.__popup_menu, menu)
def __init__(self, parent, library): super(RenameFiles, self).__init__(spacing=6) self.__skip_interactive = False self.set_border_width(12) hbox = Gtk.HBox(spacing=6) cbes_defaults = NBP_EXAMPLES.split("\n") self.combo = ComboBoxEntrySave(NBP, cbes_defaults, title=_("Path Patterns"), edit_title=_(u"Edit saved patterns…")) self.combo.show_all() hbox.pack_start(self.combo, True, True, 0) self.preview = qltk.Button(_("_Preview"), Icons.VIEW_REFRESH) self.preview.show() hbox.pack_start(self.preview, False, True, 0) self.pack_start(hbox, False, True, 0) self.combo.get_child().connect('changed', self._changed) model = ObjectStore() self.view = Gtk.TreeView(model=model) self.view.show() sw = Gtk.ScrolledWindow() sw.set_shadow_type(Gtk.ShadowType.IN) sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) sw.add(self.view) self.pack_start(sw, True, True, 0) self.pack_start(Gtk.VBox(), False, True, 0) # rename options rename_options = Gtk.HBox() # file name options filter_box = FilterPluginBox(self.handler, self.FILTERS) filter_box.connect("preview", self.__filter_preview) filter_box.connect("changed", self.__filter_changed) self.filter_box = filter_box frame_filename_options = Frame(_("File names"), filter_box) frame_filename_options.show_all() rename_options.pack_start(frame_filename_options, False, True, 0) # album art options albumart_box = Gtk.VBox() # move art moveart_box = Gtk.VBox() self.moveart = ConfigCheckButton(_('_Move album art'), "rename", "move_art", populate=True) self.moveart.set_tooltip_text( _("See '[albumart] filenames' config entry " + "for image search strings")) self.moveart.show() moveart_box.pack_start(self.moveart, False, True, 0) self.moveart_overwrite = ConfigCheckButton( _('_Overwrite album art at target'), "rename", "move_art_overwrite", populate=True) self.moveart_overwrite.show() moveart_box.pack_start(self.moveart_overwrite, False, True, 0) albumart_box.pack_start(moveart_box, False, True, 0) # remove empty removeemptydirs_box = Gtk.VBox() self.removeemptydirs = ConfigCheckButton( _('_Remove empty directories'), "rename", "remove_empty_dirs", populate=True) self.removeemptydirs.show() removeemptydirs_box.pack_start(self.removeemptydirs, False, True, 0) albumart_box.pack_start(removeemptydirs_box, False, True, 0) frame_albumart_options = Frame(_("Album art"), albumart_box) frame_albumart_options.show_all() rename_options.pack_start(frame_albumart_options, False, True, 0) self.pack_start(rename_options, False, True, 0) # Save button self.save = Button(_("_Save"), Icons.DOCUMENT_SAVE) self.save.show() bbox = Gtk.HButtonBox() bbox.set_layout(Gtk.ButtonBoxStyle.END) bbox.pack_start(self.save, True, True, 0) self.pack_start(bbox, False, True, 0) render = Gtk.CellRendererText() column = TreeViewColumn(title=_('File')) column.pack_start(render, True) 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) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) self.view.append_column(column) render = Gtk.CellRendererText() render.set_property('editable', True) column = TreeViewColumn(title=_('New Name')) column.pack_start(render, True) def cell_data_new_name(column, cell, model, iter_, data): entry = model.get_value(iter_) cell.set_property("text", entry.new_name or u"") column.set_cell_data_func(render, cell_data_new_name) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) self.view.append_column(column) connect_obj(self.preview, 'clicked', self._preview, None) connect_obj(parent, 'changed', self.__class__._preview, self) connect_obj(self.save, 'clicked', self._rename, library) render.connect('edited', self.__row_edited) for child in self.get_children(): child.show()
def __init__(self, parent, library): super(EditTags, self).__init__(spacing=12) self.title = _("Edit Tags") self.set_border_width(12) model = ObjectStore() view = RCMHintedTreeView(model=model) self._view = view selection = view.get_selection() render = Gtk.CellRendererPixbuf() column = TreeViewColumn() column.pack_start(render, True) column.set_fixed_width(24) column.set_expand(False) def cdf_write(col, rend, model, iter_, *args): entry = model.get_value(iter_) rend.set_property('sensitive', entry.edited or entry.deleted) if entry.canedit or entry.deleted: if entry.deleted: rend.set_property('icon-name', Icons.EDIT_DELETE) else: rend.set_property('icon-name', Icons.EDIT) else: rend.set_property('icon-name', Icons.CHANGES_PREVENT) column.set_cell_data_func(render, cdf_write) view.append_column(column) render = Gtk.CellRendererText() column = TreeViewColumn(title=_('Tag')) column.pack_start(render, True) def cell_data_tag(column, cell, model, iter_, data): entry = model.get_value(iter_) cell.set_property("text", entry.tag) cell.set_property("strikethrough", entry.deleted) column.set_cell_data_func(render, cell_data_tag) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) render.set_property('editable', True) render.connect('edited', self.__edit_tag_name, model) render.connect('editing-started', self.__tag_editing_started, model, library) view.append_column(column) render = Gtk.CellRendererText() render.set_property('ellipsize', Pango.EllipsizeMode.END) render.set_property('editable', True) render.connect('edited', self.__edit_tag, model) render.connect('editing-started', self.__value_editing_started, model, library) column = TreeViewColumn(title=_('Value')) column.pack_start(render, True) def cell_data_value(column, cell, model, iter_, data): entry = model.get_value(iter_) markup = entry.value.get_markup() cell.markup = markup cell.set_property("markup", markup) cell.set_property("editable", entry.canedit) cell.set_property("strikethrough", entry.deleted) column.set_cell_data_func(render, cell_data_value) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) view.append_column(column) sw = Gtk.ScrolledWindow() sw.set_shadow_type(Gtk.ShadowType.IN) sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) sw.add(view) self.pack_start(sw, True, True, 0) cb = ConfigCheckButton( _("Show _programmatic tags"), 'editing', 'alltags', populate=True, tooltip=_("Access all tags, including machine-generated " "ones e.g. MusicBrainz or Replay Gain tags")) cb.connect('toggled', self.__all_tags_toggled) self.pack_start(cb, False, True, 0) # Add and Remove [tags] buttons buttonbox = Gtk.HBox(spacing=18) bbox1 = Gtk.HButtonBox() bbox1.set_spacing(6) bbox1.set_layout(Gtk.ButtonBoxStyle.START) add = qltk.Button(_("_Add"), Icons.LIST_ADD) add.set_focus_on_click(False) self._add = add add.connect('clicked', self.__add_tag, model, library) bbox1.pack_start(add, True, True, 0) # Remove button remove = qltk.Button(_("_Remove"), Icons.LIST_REMOVE) remove.set_focus_on_click(False) remove.connect('clicked', self.__remove_tag, view) remove.set_sensitive(False) self._remove = remove bbox1.pack_start(remove, True, True, 0) # Revert and save buttons # Both can have customised translated text (and thus accels) bbox2 = Gtk.HButtonBox() bbox2.set_spacing(6) bbox2.set_layout(Gtk.ButtonBoxStyle.END) # Translators: Revert button in the tag editor revert = Button(C_("edittags", "_Revert"), Icons.DOCUMENT_REVERT) self._revert = revert revert.set_sensitive(False) # Translators: Save button in the tag editor save = Button(C_("edittags", "_Save"), Icons.DOCUMENT_SAVE) save.set_sensitive(False) self._save = save bbox2.pack_start(revert, True, True, 0) bbox2.pack_start(save, True, True, 0) buttonbox.pack_start(bbox1, True, True, 0) buttonbox.pack_start(bbox2, True, True, 0) self.pack_start(buttonbox, False, True, 0) self._buttonbox = buttonbox parent.connect('changed', self.__parent_changed) revert.connect('clicked', lambda *x: self._update()) connect_obj(revert, 'clicked', parent.set_pending, None) save.connect('clicked', self.__save_files, revert, model, library) connect_obj(save, 'clicked', parent.set_pending, None) for sig in ['row-inserted', 'row-deleted', 'row-changed']: model.connect(sig, self.__enable_save, [save, revert]) connect_obj(model, sig, parent.set_pending, save) view.connect('popup-menu', self.__popup_menu, parent) view.connect('button-press-event', self.__button_press) view.connect('key-press-event', self.__view_key_press_event) selection.connect('changed', self.__tag_select, remove) selection.set_mode(Gtk.SelectionMode.MULTIPLE) self._parent = parent for child in self.get_children(): child.show_all()
def __preview(self, songs): if songs is None: songs = [row[0].song for row in (self.view.get_model() or [])] if songs: pattern_text = gdecode(self.combo.get_child().get_text()) else: pattern_text = "" try: pattern = TagsFromPattern(pattern_text) except re.error: qltk.ErrorMessage( self, _("Invalid pattern"), _("The pattern\n\t<b>%s</b>\nis invalid. " "Possibly it contains the same tag twice or " "it has unbalanced brackets (< / >).") % ( util.escape(pattern_text))).run() return else: if pattern_text: self.combo.prepend_text(pattern_text) self.combo.write(TBP) invalid = [] for header in pattern.headers: if not min([song.can_change(header) for song in songs]): invalid.append(header) if len(invalid) and songs: if len(invalid) == 1: title = _("Invalid tag") msg = _("Invalid tag <b>%s</b>\n\nThe files currently" " selected do not support editing this tag.") else: title = _("Invalid tags") msg = _("Invalid tags <b>%s</b>\n\nThe files currently" " selected do not support editing these tags.") qltk.ErrorMessage( self, title, msg % ", ".join(invalid)).run() pattern = TagsFromPattern("") self.view.set_model(None) model = ObjectStore() for col in self.view.get_columns(): self.view.remove_column(col) render = Gtk.CellRendererText() col = TreeViewColumn(title=_('File')) col.pack_start(render, True) col.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) col.set_cell_data_func(render, cell_data_file) def cell_data_header(column, cell, model, iter_, header): entry = model.get_value(iter_) cell.set_property("text", entry.get_match(header)) self.view.append_column(col) for i, header in enumerate(pattern.headers): render = Gtk.CellRendererText() render.set_property('editable', True) render.connect('edited', self.__row_edited, model, header) escaped_title = header.replace("_", "__") col = Gtk.TreeViewColumn(escaped_title, render) col.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) col.set_cell_data_func(render, cell_data_header, header) self.view.append_column(col) for song in songs: entry = ListEntry(song) match = pattern.match(song) for h in pattern.headers: text = match.get(h, '') for f in self.filter_box.filters: if f.active: text = f.filter(h, text) if not song.can_multiple_values(h): text = u", ".join(text.split("\n")) entry.matches[h] = text model.append([entry]) # save for last to potentially save time if songs: self.view.set_model(model) self.preview.set_sensitive(False) self.save.set_sensitive(len(pattern.headers) > 0)
def __init__(self, parent, library): super(EditTags, self).__init__(spacing=12) self.title = _("Edit Tags") self.set_border_width(12) model = ObjectStore() view = RCMHintedTreeView(model=model) self._view = view selection = view.get_selection() render = Gtk.CellRendererPixbuf() column = TreeViewColumn() column.pack_start(render, True) column.set_fixed_width(24) column.set_expand(False) def cdf_write(col, rend, model, iter_, *args): entry = model.get_value(iter_) rend.set_property('sensitive', entry.edited or entry.deleted) if entry.canedit or entry.deleted: if entry.deleted: rend.set_property('icon-name', Icons.EDIT_DELETE) else: rend.set_property('icon-name', Icons.EDIT) else: rend.set_property('icon-name', Icons.CHANGES_PREVENT) column.set_cell_data_func(render, cdf_write) view.append_column(column) render = Gtk.CellRendererText() column = TreeViewColumn(title=_('Tag')) column.pack_start(render, True) def cell_data_tag(column, cell, model, iter_, data): entry = model.get_value(iter_) cell.set_property("text", entry.tag) cell.set_property("strikethrough", entry.deleted) column.set_cell_data_func(render, cell_data_tag) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) render.set_property('editable', True) render.connect('edited', self.__edit_tag_name, model) render.connect( 'editing-started', self.__tag_editing_started, model, library) view.append_column(column) render = Gtk.CellRendererText() render.set_property('ellipsize', Pango.EllipsizeMode.END) render.set_property('editable', True) render.connect('edited', self.__edit_tag, model) render.connect( 'editing-started', self.__value_editing_started, model, library) column = TreeViewColumn(title=_('Value')) column.pack_start(render, True) def cell_data_value(column, cell, model, iter_, data): entry = model.get_value(iter_) markup = entry.value.get_markup() cell.markup = markup cell.set_property("markup", markup) cell.set_property("editable", entry.canedit) cell.set_property("strikethrough", entry.deleted) column.set_cell_data_func(render, cell_data_value) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) view.append_column(column) sw = Gtk.ScrolledWindow() sw.set_shadow_type(Gtk.ShadowType.IN) sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) sw.add(view) self.pack_start(sw, True, True, 0) cb = ConfigCheckButton( _("Show _programmatic tags"), 'editing', 'alltags', populate=True, tooltip=_("Access all tags, including machine-generated " "ones e.g. MusicBrainz or Replay Gain tags")) cb.connect('toggled', self.__all_tags_toggled) self.pack_start(cb, False, True, 0) # Add and Remove [tags] buttons buttonbox = Gtk.HBox(spacing=18) bbox1 = Gtk.HButtonBox() bbox1.set_spacing(6) bbox1.set_layout(Gtk.ButtonBoxStyle.START) add = qltk.Button(_("_Add"), Icons.LIST_ADD) add.set_focus_on_click(False) self._add = add add.connect('clicked', self.__add_tag, model, library) bbox1.pack_start(add, True, True, 0) # Remove button remove = qltk.Button(_("_Remove"), Icons.LIST_REMOVE) remove.set_focus_on_click(False) remove.connect('clicked', self.__remove_tag, view) remove.set_sensitive(False) self._remove = remove bbox1.pack_start(remove, True, True, 0) # Revert and save buttons # Both can have customised translated text (and thus accels) bbox2 = Gtk.HButtonBox() bbox2.set_spacing(6) bbox2.set_layout(Gtk.ButtonBoxStyle.END) # Translators: Revert button in the tag editor revert = Button(C_("edittags", "_Revert"), Icons.DOCUMENT_REVERT) self._revert = revert revert.set_sensitive(False) # Translators: Save button in the tag editor save = Button(C_("edittags", "_Save"), Icons.DOCUMENT_SAVE) save.set_sensitive(False) self._save = save bbox2.pack_start(revert, True, True, 0) bbox2.pack_start(save, True, True, 0) buttonbox.pack_start(bbox1, True, True, 0) buttonbox.pack_start(bbox2, True, True, 0) self.pack_start(buttonbox, False, True, 0) self._buttonbox = buttonbox parent.connect('changed', self.__parent_changed) revert.connect('clicked', lambda *x: self._update()) connect_obj(revert, 'clicked', parent.set_pending, None) save.connect('clicked', self.__save_files, revert, model, library) connect_obj(save, 'clicked', parent.set_pending, None) for sig in ['row-inserted', 'row-deleted', 'row-changed']: model.connect(sig, self.__enable_save, [save, revert]) connect_obj(model, sig, parent.set_pending, save) view.connect('popup-menu', self.__popup_menu, parent) view.connect('button-press-event', self.__button_press) view.connect('key-press-event', self.__view_key_press_event) selection.connect('changed', self.__tag_select, remove) selection.set_mode(Gtk.SelectionMode.MULTIPLE) self._parent = parent for child in self.get_children(): child.show_all()
def __init__(self, initial=None, folders=None): """ initial -- the path to select/scroll to folders -- a list of paths to show in the tree view, None will result in a separator. """ model = ObjectTreeStore() super(DirectoryTree, self).__init__(model=model) if initial is not None: assert isinstance(initial, fsnative) column = TreeViewColumn(title=_("Folders")) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) render = Gtk.CellRendererPixbuf() render.set_property('icon-name', Icons.FOLDER) render.props.xpad = 3 column.pack_start(render, False) render = Gtk.CellRendererText() if self.supports_hints(): render.set_property('ellipsize', Pango.EllipsizeMode.END) column.pack_start(render, True) def cell_data(column, cell, model, iter_, userdata): value = model.get_value(iter_) if value is not None: text = fsn2text(os.path.basename(value) or value) cell.set_property('text', text) column.set_cell_data_func(render, cell_data) self.append_column(column) self.set_search_equal_func(search_func, True) self.set_search_column(0) if folders is None: folders = [] for path in folders: niter = model.append(None, [path]) if path is not None: assert isinstance(path, fsnative) model.append(niter, [fsnative(u"dummy")]) self.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE) self.connect('test-expand-row', DirectoryTree.__expanded, model) self.set_row_separator_func( lambda model, iter_, data: model.get_value(iter_) is None, None) if initial: self.go_to(initial) menu = self._create_menu() connect_obj(self, 'popup-menu', self._popup_menu, menu) # Allow to drag and drop files from outside targets = [("text/uri-list", 0, 42)] targets = [Gtk.TargetEntry.new(*t) for t in targets] self.drag_dest_set(Gtk.DestDefaults.ALL, targets, Gdk.DragAction.COPY) self.connect('drag-data-received', self.__drag_data_received)
def __init__(self, initial=None, filter=filesel_filter, folders=None): """ initial -- a path to a file which should be shown initially filter -- a function which filters paths shown in the file list folders -- list of shown folders in the directory tree """ super(FileSelector, self).__init__( orientation=Gtk.Orientation.VERTICAL) self.__filter = filter if initial is not None: assert is_fsnative(initial) if initial and os.path.isfile(initial): initial = os.path.dirname(initial) dirlist = DirectoryTree(initial, folders=folders) model = ObjectStore() filelist = AllTreeView(model=model) column = TreeViewColumn(title=_("Songs")) column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) render = Gtk.CellRendererPixbuf() render.props.xpad = 3 def cell_icon(column, cell, model, iter_, userdata): value = model.get_value(iter_) if is_image(value): cell.set_property('icon-name', Icons.IMAGE_X_GENERIC) else: cell.set_property('icon-name', Icons.AUDIO_X_GENERIC) column.set_cell_data_func(render, cell_icon) column.pack_start(render, False) render = Gtk.CellRendererText() if filelist.supports_hints(): render.set_property('ellipsize', Pango.EllipsizeMode.END) column.pack_start(render, True) def cell_data(column, cell, model, iter_, userdata): value = model.get_value(iter_) cell.set_property('text', fsdecode(os.path.basename(value))) column.set_cell_data_func(render, cell_data) filelist.append_column(column) filelist.set_rules_hint(True) filelist.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE) filelist.set_search_equal_func(search_func, False) filelist.set_search_column(0) self.__sig = filelist.get_selection().connect( 'changed', self.__changed) dirlist.get_selection().connect( 'changed', self.__dir_selection_changed, filelist) dirlist.get_selection().emit('changed') def select_all_files(view, path, col, fileselection): view.expand_row(path, False) fileselection.select_all() dirlist.connect('row-activated', select_all_files, filelist.get_selection()) sw = ScrolledWindow() sw.add(dirlist) sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) sw.set_shadow_type(Gtk.ShadowType.IN) self.pack1(sw, resize=True) sw = ScrolledWindow() sw.add(filelist) sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) sw.set_shadow_type(Gtk.ShadowType.IN) self.pack2(sw, resize=True)
def __init__(self, library, prefs, next_=None): super(Pane, self).__init__() self.set_fixed_height_mode(True) self.config = PaneConfig(prefs) self.__next = next_ self.__restore_values = None self.__no_fill = 0 column = TreeViewColumn(self.config.title) column.set_use_markup(True) column.set_sizing(Gtk.TreeViewColumnSizing.FIXED) column.set_fixed_width(50) render = Gtk.CellRendererText() render.set_property('ellipsize', Pango.EllipsizeMode.END) column.pack_start(render, True) def text_cdf(column, cell, model, iter_, data): entry = model.get_value(iter_) is_markup, text = entry.get_text(self.config) if is_markup: cell.markup = text cell.set_property('markup', text) else: cell.markup = None cell.set_property('text', text) column.set_cell_data_func(render, text_cdf) render_count = Gtk.CellRendererText() render_count.set_property('xalign', 1.0) column.pack_start(render_count, False) def count_cdf(column, cell, model, iter_, data): entry = model.get_value(iter_) markup = entry.get_count_text(self.config) cell.markup = markup cell.set_property('markup', markup) column.set_cell_data_func(render_count, count_cdf) self.append_column(column) model = PaneModel(self.config) self.set_model(model) self.set_search_equal_func(self.__search_func, None) self.set_search_column(0) self.set_enable_search(True) selection = self.get_selection() selection.set_mode(Gtk.SelectionMode.MULTIPLE) self.__sig = selection.connect('changed', self.__selection_changed) s = self.connect('popup-menu', self.__popup_menu, library) self.connect_object('destroy', self.disconnect, s) targets = [("text/x-quodlibet-songs", Gtk.TargetFlags.SAME_APP, self.TARGET_INFO_QL), ("text/uri-list", 0, self.TARGET_INFO_URI_LIST)] targets = [Gtk.TargetEntry.new(*t) for t in targets] self.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, targets, Gdk.DragAction.COPY) self.connect("drag-data-get", self.__drag_data_get) self.connect("destroy", self.__destroy) self.connect("key-press-event", self.__key_pressed)