def __popup_menu(self, view, library): model, itr = view.get_selection().get_selected() if itr is None: return songs = list(model[itr][0]) songs = filter(lambda s: isinstance(s, AudioFile), songs) menu = SongsMenu(library, songs, playlists=False, remove=False, ratings=False) menu.preseparate() def _remove(model, itr): playlist = model[itr][0] dialog = ConfirmRemovePlaylistDialog(self, playlist) if dialog.run() == Gtk.ResponseType.YES: playlist.delete() model.get_model().remove(model.convert_iter_to_child_iter(itr)) rem = MenuItem(_("_Delete"), Icons.EDIT_DELETE) connect_obj(rem, "activate", _remove, model, itr) menu.prepend(rem) def _rename(path): self.__render.set_property("editable", True) view.set_cursor(path, view.get_columns()[0], start_editing=True) ren = qltk.MenuItem(_("_Rename"), Icons.EDIT) qltk.add_fake_accel(ren, "F2") connect_obj(ren, "activate", _rename, model.get_path(itr)) menu.prepend(ren) playlist = model[itr][0] PLAYLIST_HANDLER.populate_menu(menu, library, self, [playlist]) menu.show_all() return view.popup_menu(menu, 0, Gtk.get_current_event_time())
def ClearButton(entry=None): clear = Gtk.Button() clear.add(Gtk.Image.new_from_stock(Gtk.STOCK_CLEAR, Gtk.IconSize.MENU)) clear.set_tooltip_text(_("Clear search")) if entry is not None: connect_obj(clear, 'clicked', entry.set_text, '') return clear
def __init__(self, filename=None, initial=[], count=5, id=None, validator=None, title=_("Saved Values"), edit_title=_(u"Edit saved values…")): self.count = count self.filename = filename id = filename or id try: model = self.__models[id] except KeyError: model = type(self).__models[id] = Gtk.ListStore(str, str, str) super(ComboBoxEntrySave, self).__init__( model=model, entry_text_column=0, has_entry=True) self.clear() render = Gtk.CellRendererPixbuf() self.pack_start(render, False) self.add_attribute(render, 'icon-name', 2) render = Gtk.CellRendererText() self.pack_start(render, True) self.add_attribute(render, 'text', 1) self.set_row_separator_func(self.__separator_func, None) if not len(model): self.__fill(filename, initial, edit_title) self.remove(self.get_child()) self.add(entry.ValidatingEntry(validator)) connect_obj(self, 'destroy', self.set_model, None) connect_obj(self, 'changed', self.__changed, model, validator, title)
def connect(self, signal, callback, *args, **kwargs): if self.get_submenu(): for item in self.get_submenu().get_children(): connect_obj(item, signal, callback, self, *args, **kwargs) else: super(EditTagsPlugin, self).connect( signal, callback, *args, **kwargs)
def setUp(self): config.init() config.set("player", "gst_pipeline", "fakesink") config.set("settings", "xine_driver", "none") module = player.init_backend(self.NAME) lib = library.init() self.player = module.init(lib.librarian) source = PlaylistModel() source.set(FILES) self.events = [] def start_end_handler(player, song, *args): self.events.append((args[-1], song)) self.player.connect("song-started", start_end_handler, "started") self.player.connect("song-ended", start_end_handler, "ended") self.player.setup(source, None, 0) self.signals = [] def handler(type_, *args): self.signals.append(type_) connect_obj(self.player, "unpaused", handler, "unpaused") connect_obj(self.player, "paused", handler, "paused")
def __init__(self, *args, **kwargs): if type(self).__window: return else: type(self).__window = self super(_Unique, self).__init__(*args, **kwargs) connect_obj(self, 'destroy', self.__destroy, self)
def MenuItems(marks, player, seekable): sizes = Gtk.SizeGroup(mode=Gtk.SizeGroupMode.HORIZONTAL) items = [] if not marks or marks[0][0] != 0: # Translators: Refers to the beginning of the playing song. marks.insert(0, (0, _("Beginning"))) for time, mark in marks: i = Gtk.MenuItem() # older pygobject (~3.2) added a child on creation if i.get_child(): i.remove(i.get_child()) connect_obj(i, 'activate', player.seek, time * 1000) i.set_sensitive(time >= 0 and seekable) hbox = Gtk.HBox(spacing=12) i.add(hbox) if time < 0: l = Gtk.Label(label=_("N/A")) else: l = Gtk.Label(label=util.format_time(time)) l.set_alignment(0.0, 0.5) sizes.add_widget(l) hbox.pack_start(l, False, True, 0) text = Gtk.Label(mark) text.set_max_width_chars(80) text.set_ellipsize(Pango.EllipsizeMode.END) text.set_alignment(0.0, 0.5) hbox.pack_start(text, True, True, 0) i.show_all() items.append(i) return items
def __init__(self, cbes, title, validator=None): # Do this before calling parent constructor self.cbes = cbes super(CBESEditor, self).__init__(title, validator) self.set_transient_for(qltk.get_top_parent(cbes)) connect_obj(self, 'destroy', self.__finish, cbes) self.value.set_text(cbes.get_child().get_text())
def __init__(self): super(FilterCheckButton, self).__init__(self._label, self._section, self._key) try: self.set_active(config.getboolean(self._section, self._key)) except: pass connect_obj(self, "toggled", self.emit, "preview")
def Menu(self, songs, library, items): in_fav = False in_all = False for song in songs: if song in self.__fav_stations: in_fav = True elif song in self.__stations: in_all = True if in_fav and in_all: break iradio_items = [] button = MenuItem(_("Add to Favorites"), Gtk.STOCK_ADD) button.set_sensitive(in_all) connect_obj(button, 'activate', self.__add_fav, songs) iradio_items.append(button) button = MenuItem(_("Remove from Favorites"), Gtk.STOCK_REMOVE) button.set_sensitive(in_fav) connect_obj(button, 'activate', self.__remove_fav, songs) iradio_items.append(button) items.append(iradio_items) menu = SongsMenu(self.__librarian, songs, playlists=False, remove=True, queue=False, devices=False, items=items) return menu
def __init__(self, player): super(Volume, self).__init__(size=Gtk.IconSize.MENU, use_symbolic=True) # https://bugzilla.gnome.org/show_bug.cgi?id=781605 scales = qltk.find_widgets(self.get_popup(), Gtk.Scale) if scales: scales[0].props.round_digits = -1 self.set_relief(Gtk.ReliefStyle.NORMAL) self.set_adjustment(Gtk.Adjustment.new(0, 0, 1, 0.05, 0.1, 0)) popup = self.get_popup() if hasattr(Gtk, "Popover") and isinstance(popup, Gtk.Popover): popup.set_position(Gtk.PositionType.BOTTOM) self._id = self.connect('value-changed', self.__volume_changed, player) self._id2 = player.connect('notify::volume', self.__volume_notify) self._id3 = player.connect('notify::mute', self.__mute_notify) self._orig_icon_list = self.props.icons player.notify("volume") player.notify("mute") self.connect("event", self._on_button_event, player) replaygain_menu = VolumeMenu(player) self.connect('popup-menu', self.__popup, replaygain_menu) connect_obj(self, 'button-press-event', self.__volume_button_press, replaygain_menu, player)
def __init__(self, library): super(FileSystem, self).__init__() sw = ScrolledWindow() sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) sw.set_shadow_type(Gtk.ShadowType.IN) dt = MainDirectoryTree(folders=get_scan_dirs()) targets = [("text/x-quodlibet-songs", Gtk.TargetFlags.SAME_APP, self.TARGET_QL), ("text/uri-list", 0, self.TARGET_EXT)] targets = [Gtk.TargetEntry.new(*t) for t in targets] dt.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, targets, Gdk.DragAction.COPY) dt.connect('drag-data-get', self.__drag_data_get) sel = dt.get_selection() sel.unselect_all() connect_obj(sel, 'changed', copool.add, self.__songs_selected, dt) sel.connect("changed", self._on_selection_changed) dt.connect('row-activated', lambda *a: self.songs_activated()) sw.add(dt) self.pack_start(sw, True, True, 0) self.show_all()
def __init__(self, app): super(DockMenu, self).__init__() player = app.player play_item = MenuItem(_("_Play"), Icons.MEDIA_PLAYBACK_START) play_item.connect("activate", self._on_play, player) pause_item = MenuItem(_("P_ause"), Icons.MEDIA_PLAYBACK_PAUSE) pause_item.connect("activate", self._on_pause, player) self.append(play_item) self.append(pause_item) previous = MenuItem(_("Pre_vious"), Icons.MEDIA_SKIP_BACKWARD) previous.connect("activate", lambda *args: player.previous()) self.append(previous) next_ = MenuItem(_("_Next"), Icons.MEDIA_SKIP_FORWARD) next_.connect("activate", lambda *args: player.next()) self.append(next_) browse = qltk.MenuItem(_("_Browse Library"), Icons.EDIT_FIND) browse_sub = Gtk.Menu() for Kind in browsers.browsers: if Kind.is_empty: continue i = Gtk.MenuItem(label=Kind.accelerated_name, use_underline=True) connect_obj(i, "activate", LibraryBrowser.open, Kind, app.library, app.player) browse_sub.append(i) browse.set_submenu(browse_sub) self.append(SeparatorMenuItem()) self.append(browse) self.show_all() self.hide()
def __connect_signals(self, view, library): view.connect("row-activated", lambda *x: self.songs_activated()) view.connect("popup-menu", self.__popup_menu, library) view.get_selection().connect("changed", self.activate) model = view.get_model() s = model.connect("row-changed", self.__check_current) connect_obj(self, "destroy", model.disconnect, s) self.connect("key-press-event", self.__key_pressed)
def __init__(self): super(ScanBox, self).__init__(spacing=6) self.model = model = Gtk.ListStore(str) view = RCMHintedTreeView(model=model) view.set_fixed_height_mode(True) view.set_headers_visible(False) view.set_tooltip_text(_("Songs in the listed folders will be added " "to the library during a library refresh")) 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) 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, 80)) render = Gtk.CellRendererText() render.set_property('ellipsize', Pango.EllipsizeMode.END) def cdf(column, cell, model, iter, data): row = model[iter] cell.set_property('text', unexpand(row[0])) column = Gtk.TreeViewColumn(None, render) column.set_cell_data_func(render, cdf) column.set_sizing(Gtk.TreeViewColumnSizing.FIXED) view.append_column(column) add = Button(_("_Add"), Icons.LIST_ADD) add.connect("clicked", self.__add) remove = Button(_("_Remove"), Icons.LIST_REMOVE) selection = view.get_selection() selection.set_mode(Gtk.SelectionMode.MULTIPLE) selection.connect("changed", self.__select_changed, remove) selection.emit("changed") connect_obj(remove, "clicked", self.__remove, view) vbox = Gtk.VBox(spacing=6) vbox.pack_start(add, False, True, 0) vbox.pack_start(remove, False, True, 0) self.pack_start(sw, True, True, 0) self.pack_start(vbox, False, True, 0) paths = map(fsdecode, get_scan_dirs()) for path in paths: model.append(row=[path]) for child in self.get_children(): child.show_all()
def __init__(self, parent, can_change, library): super(AddTagDialog, self).__init__( title=_("Add a Tag"), transient_for=qltk.get_top_parent(parent), use_header_bar=True) self.set_border_width(6) self.set_resizable(False) self.add_button(_("_Cancel"), Gtk.ResponseType.CANCEL) add = self.add_icon_button(_("_Add"), Icons.LIST_ADD, Gtk.ResponseType.OK) self.vbox.set_spacing(6) self.set_default_response(Gtk.ResponseType.OK) table = Gtk.Table(n_rows=2, n_columns=2) table.set_row_spacings(12) table.set_col_spacings(6) table.set_border_width(6) self.__tag = (TagsComboBoxEntry() if can_change is True else TagsComboBox(can_change)) label = Gtk.Label() label.set_alignment(0.0, 0.5) label.set_text(_("_Tag:")) label.set_use_underline(True) label.set_mnemonic_widget(self.__tag) table.attach(label, 0, 1, 0, 1) table.attach(self.__tag, 1, 2, 0, 1) self.__val = Gtk.Entry() self.__val.set_completion(LibraryValueCompletion("", library)) label = Gtk.Label() label.set_text(_("_Value:")) label.set_alignment(0.0, 0.5) label.set_use_underline(True) label.set_mnemonic_widget(self.__val) valuebox = Gtk.EventBox() table.attach(label, 0, 1, 1, 2) table.attach(valuebox, 1, 2, 1, 2) hbox = Gtk.HBox() valuebox.add(hbox) hbox.pack_start(self.__val, True, True, 0) hbox.set_spacing(6) invalid = Gtk.Image.new_from_icon_name( Icons.DIALOG_WARNING, Gtk.IconSize.SMALL_TOOLBAR) hbox.pack_start(invalid, True, True, 0) self.vbox.pack_start(table, True, True, 0) self.get_child().show_all() invalid.hide() for entry in [self.__tag, self.__val]: entry.connect( 'changed', self.__validate, add, invalid, valuebox) self.__tag.connect('changed', self.__set_value_completion, library) self.__set_value_completion(self.__tag, library) if can_change is True: connect_obj(self.__tag.get_child(), 'activate', Gtk.Entry.grab_focus, self.__val)
def enable_row_update(self, view, sw, column): connect_obj(view, "draw", self.__update_visibility, view) connect_destroy(sw.get_vadjustment(), "value-changed", self.__stop_update, view) self.__pending_paths = [] self.__update_deferred = DeferredSignal(self.__update_visible_rows, timeout=50, priority=GLib.PRIORITY_LOW) self.__column = column self.__first_expose = True
def Menu(self, songs, library, items): model, iters = self.__get_selected_songs() item = qltk.MenuItem(_("_Remove from Playlist"), Icons.LIST_REMOVE) qltk.add_fake_accel(item, "Delete") connect_obj(item, 'activate', self.__remove, iters, model) item.set_sensitive(bool(self.__view.get_selection().get_selected()[1])) items.append([item]) menu = super(PlaylistsBrowser, self).Menu(songs, library, items) return menu
def __init__(self, songs, library): super(Menu, self).__init__() for device in MediaDevices.devices(): i = Gtk.ImageMenuItem(device['name']) i.set_image( Gtk.Image.new_from_icon_name(device.icon, Gtk.IconSize.MENU)) i.set_sensitive(device.is_connected()) connect_obj(i, 'activate', self.__copy_to_device, device, songs, library) self.append(i)
def Menu(self, songs, library, items): model, iters = self.__get_selected_songs() remove = qltk.MenuItem(_("_Remove from Playlist"), Icons.LIST_REMOVE) qltk.add_fake_accel(remove, "Delete") connect_obj(remove, 'activate', self.__remove, iters, model) playlist_iter = self.__selected_playlists()[1] remove.set_sensitive(bool(playlist_iter)) items.append([remove]) menu = super(PlaylistsBrowser, self).Menu(songs, library, items) return menu
def __init__(self, library, player): super(PlayQueue, self).__init__(library, player, model_cls=QueueModel) self.set_size_request(-1, 120) self.connect('row-activated', self.__go_to, player) connect_obj(self, 'popup-menu', self.__popup, library) self.enable_drop() connect_obj(self, 'destroy', self.__write, self.model) self.__fill(library) self.connect('key-press-event', self.__delete_key_pressed)
def __init__(self, *args, **kwargs): self._header_bar = None dialog = kwargs.pop("dialog", True) super(Window, self).__init__(*args, **kwargs) type(self).windows.append(self) if dialog: self.set_type_hint(Gdk.WindowTypeHint.DIALOG) self.set_destroy_with_parent(True) self.set_position(Gtk.WindowPosition.CENTER_ON_PARENT) connect_obj(self, "destroy", type(self).windows.remove, self) self.connect("key-press-event", self._on_key_press)
def __popup_menu(self, view): selection = view.get_selection() model, paths = selection.get_selected_rows() if model: iters = map(model.get_iter, paths) menu = Gtk.Menu() item = MenuItem(_("_Stop"), Icons.PROCESS_STOP) connect_obj(item, 'activate', self.__stop_download, iters) menu.append(item) menu.connect('selection-done', lambda m: m.destroy()) menu.show_all() return view.popup_menu(menu, 0, Gtk.get_current_event_time())
def __init__(self): super(RegExpSub, self).__init__() self._from = Gtk.Entry() self._to = Gtk.Entry() self.pack_start(Gtk.Label("s/"), True, True, 0) self.pack_start(self._from, True, True, 0) self.pack_start(Gtk.Label("/"), True, True, 0) self.pack_start(self._to, True, True, 0) self.pack_start(Gtk.Label("/"), True, True, 0) connect_obj(self._from, 'changed', self.emit, 'changed') connect_obj(self._to, 'changed', self.emit, 'changed')
def __init__(self, songs, library, label=_("_Rating")): super(RatingsMenuItem, self).__init__(label=label, use_underline=True) submenu = Gtk.Menu() self.set_submenu(submenu) for i in RATINGS.all: itm = Gtk.MenuItem(label="%0.2f\t%s" % (i, util.format_rating(i))) submenu.append(itm) connect_obj(itm, 'activate', self.set_rating, i, songs, library) reset = Gtk.MenuItem(label=_("_Remove rating"), use_underline=True) connect_obj(reset, 'activate', self.remove_rating, songs, library) submenu.append(SeparatorMenuItem()) submenu.append(reset) submenu.show_all()
def __init__(self, browser): if self.is_not_unique(): return super(Preferences, self).__init__() self.set_transient_for(qltk.get_top_parent(browser)) self.set_default_size(350, 300) self.set_border_width(12) self.set_title(_("Paned Browser Preferences")) vbox = Gtk.VBox(spacing=12) column_modes = ColumnModes(browser) column_mode_frame = qltk.Frame(_("Column layout"), child=column_modes) editor = PatternEditor() editor.headers = get_headers() editor_frame = qltk.Frame(_("Column content"), child=editor) equal_width = ConfigCheckButton(_("Equal pane width"), "browsers", "equal_pane_width", populate=True) apply_ = Button(_("_Apply")) connect_obj(apply_, "clicked", self.__apply, editor, browser, False, equal_width) cancel = Button(_("_Cancel")) cancel.connect("clicked", lambda x: self.destroy()) box = Gtk.HButtonBox() box.set_spacing(6) box.set_layout(Gtk.ButtonBoxStyle.EDGE) box.pack_start(equal_width, True, True, 0) box.pack_start(apply_, False, False, 0) self.use_header_bar() if not self.has_close_button(): box.pack_start(cancel, True, True, 0) vbox.pack_start(column_mode_frame, False, False, 0) vbox.pack_start(editor_frame, True, True, 0) vbox.pack_start(box, False, True, 0) self.add(vbox) cancel.grab_focus() self.get_child().show_all()
def __init__(self, *args, **kwargs): super(SendTo, self).__init__(*args, **kwargs) self.command = None submenu = Gtk.Menu() for command in self.commands: item = Gtk.MenuItem(label=command.title) if not command.exists(): item.set_sensitive(False) else: connect_obj(item, 'activate', self.__set, command) submenu.append(item) if submenu.get_children(): self.set_submenu(submenu) else: self.set_sensitive(False)
def __init__(self, *args, **kwargs): super(CustomCommands, self).__init__(*args, **kwargs) self.com_index = None self.unique_only = False submenu = Gtk.Menu() for (name, c) in self.all_commands().items(): item = Gtk.MenuItem(label=name) connect_obj(item, 'activate', self.__set_pat, name) submenu.append(item) self.add_edit_item(submenu) if submenu.get_children(): self.set_submenu(submenu) else: self.set_sensitive(False)
def __init__(self, device): super(Volume, self).__init__(size=Gtk.IconSize.MENU, use_symbolic=True) self.set_relief(Gtk.ReliefStyle.NORMAL) self.set_adjustment(Gtk.Adjustment.new(0, 0, 1, 0.05, 0.1, 0)) self.connect('value-changed', self.__volume_changed, device) device.connect('notify::volume', self.__volume_notify) self.set_value(config.getfloat("memory", "volume")) replaygain_menu = ReplayGainMenu(device) replaygain_menu.attach_to_widget(self, None) self.connect('popup-menu', self.__popup, replaygain_menu) connect_obj(self, 'button-press-event', self.__volume_button_press, replaygain_menu)
def __init__(self, parent=None): if self.is_not_unique(): return super(DownloadWindow, self).__init__() self.set_title("Quod Libet - " + _("Downloads")) self.set_default_size(300, 150) self.set_border_width(12) self.set_transient_for(qltk.get_top_parent(parent)) self.__timeout = None view = AllTreeView() view.connect('popup-menu', self.__popup_menu) view.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE) view.set_model(self.downloads) view.set_rules_hint(True) render = Gtk.CellRendererText() render.set_property('ellipsize', Pango.EllipsizeMode.START) column = Gtk.TreeViewColumn(_("Filename"), render) column.set_sizing(Gtk.TreeViewColumnSizing.FIXED) column.set_expand(True) def cell_data_name(column, cell, model, iter, data): cell.set_property('text', model[iter][1].name) column.set_cell_data_func(render, cell_data_name) view.append_column(column) render = Gtk.CellRendererText() column = Gtk.TreeViewColumn(_("Size"), render) column.set_sizing(Gtk.TreeViewColumnSizing.GROW_ONLY) def cell_data_size(column, cell, model, iter, data): if model[iter][2] == 0: size = _("Queued") else: size = util.format_size(model[iter][1].tell()) cell.set_property('text', size) column.set_cell_data_func(render, cell_data_size) view.append_column(column) sw = Gtk.ScrolledWindow() sw.add(view) sw.set_shadow_type(Gtk.ShadowType.IN) sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) self.add(sw) connect_obj(self, 'delete-event', DownloadWindow.__delete_event, self) self.get_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('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)
def __init__(self, filename, title, initial=None, validator=None): self.filename = filename self.initial = initial or [] super(StandaloneEditor, self).__init__(title, validator) connect_obj(self, 'destroy', self.write, True)
def __init__(self, title, validator=None): super(_KeyValueEditor, self).__init__() self.set_border_width(12) self.set_title(title) self.set_default_size(self._WIDTH, self._HEIGHT) self.add(Gtk.VBox(spacing=6)) t = Gtk.Table(n_rows=2, n_columns=3) t.set_row_spacings(3) t.set_col_spacing(0, 3) t.set_col_spacing(1, 12) l = Gtk.Label(label=_("_Name:")) name = entry.UndoEntry() l.set_mnemonic_widget(name) l.set_use_underline(True) l.set_alignment(0.0, 0.5) t.attach(l, 0, 1, 0, 1, xoptions=Gtk.AttachOptions.FILL) t.attach(name, 1, 2, 0, 1) l = Gtk.Label(label=_("_Value:")) self.value = entry.ValidatingEntry(validator) l.set_mnemonic_widget(self.value) l.set_use_underline(True) l.set_alignment(0.0, 0.5) t.attach(l, 0, 1, 1, 2, xoptions=Gtk.AttachOptions.FILL) t.attach(self.value, 1, 2, 1, 2) add = Gtk.Button(stock=Gtk.STOCK_ADD) add.set_sensitive(False) t.attach(add, 2, 3, 1, 2, xoptions=Gtk.AttachOptions.FILL) self.get_child().pack_start(t, False, True, 0) # Set up the model for this widget self.model = Gtk.ListStore(str, str) self.fill_values() view = RCMHintedTreeView(model=self.model) view.set_headers_visible(False) view.set_reorderable(True) view.set_rules_hint(True) render = Gtk.CellRendererText() render.props.ellipsize = Pango.EllipsizeMode.END column = Gtk.TreeViewColumn("", render) column.set_cell_data_func(render, self.__cdf, None) view.append_column(column) sw = Gtk.ScrolledWindow() sw.set_shadow_type(Gtk.ShadowType.IN) sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) sw.add(view) self.get_child().pack_start(sw, True, True, 0) menu = Gtk.Menu() remove = Gtk.ImageMenuItem(label=Gtk.STOCK_REMOVE, use_stock=True) connect_obj(remove, 'activate', self.__remove, view) qltk.add_fake_accel(remove, "Delete") menu.append(remove) menu.show_all() bbox = Gtk.HButtonBox() rem_b = Gtk.Button(stock=Gtk.STOCK_REMOVE) rem_b.set_sensitive(False) bbox.pack_start(rem_b, True, True, 0) self.use_header_bar() close = Gtk.Button(stock=Gtk.STOCK_CLOSE) if not self.has_close_button(): bbox.pack_start(close, True, True, 0) else: bbox.set_layout(Gtk.ButtonBoxStyle.START) self.get_child().pack_start(bbox, False, True, 0) selection = view.get_selection() connect_obj(name, 'activate', Gtk.Entry.grab_focus, self.value) connect_obj(self.value, 'activate', Gtk.Button.clicked, add) self.value.connect('changed', self.__changed, [add]) connect_obj(add, 'clicked', self.__add, selection, name, self.value, self.model) selection.connect('changed', self.__set_text, name, self.value, rem_b) view.connect('popup-menu', self.__popup, menu) connect_obj(rem_b, 'clicked', self.__remove, view) connect_obj(close, 'clicked', qltk.Window.destroy, self) view.connect('key-press-event', self.__view_key_press) connect_obj(self, 'destroy', Gtk.Menu.destroy, menu) name.grab_focus() self.get_child().show_all()
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, library): super(AlbumList, self).__init__(spacing=6) self.set_orientation(Gtk.Orientation.VERTICAL) self._register_instance() if self.__model is None: self._init_model(library) self._cover_cancel = Gio.Cancellable() sw = ScrolledWindow() sw.set_shadow_type(Gtk.ShadowType.IN) self.view = view = AllTreeView() view.set_headers_visible(False) model_sort = AlbumSortModel(model=self.__model) model_filter = AlbumFilterModel(child_model=model_sort) self.__bg_filter = background_filter() self.__filter = None model_filter.set_visible_func(self.__parse_query) render = Gtk.CellRendererPixbuf() self.__cover_column = column = Gtk.TreeViewColumn("covers", render) column.set_visible(config.getboolean("browsers", "album_covers")) column.set_sizing(Gtk.TreeViewColumnSizing.FIXED) column.set_fixed_width(get_cover_size() + 12) render.set_property('height', get_cover_size() + 8) render.set_property('width', get_cover_size() + 8) def cell_data_pb(column, cell, model, iter_, no_cover): item = model.get_value(iter_) if item.album is None: surface = None elif item.cover: pixbuf = item.cover pixbuf = add_border_widget(pixbuf, self.view) surface = get_surface_for_pixbuf(self, pixbuf) # don't cache, too much state has an effect on the result self.__last_render_surface = None else: surface = no_cover if self.__last_render_surface == surface: return self.__last_render_surface = surface cell.set_property("surface", surface) column.set_cell_data_func(render, cell_data_pb, self._no_cover) view.append_column(column) render = Gtk.CellRendererText() column = Gtk.TreeViewColumn("albums", render) column.set_sizing(Gtk.TreeViewColumnSizing.FIXED) if view.supports_hints(): render.set_property('ellipsize', Pango.EllipsizeMode.END) def cell_data(column, cell, model, iter_, data): album = model.get_album(iter_) if album is None: text = "<b>%s</b>\n" % _("All Albums") text += numeric_phrase("%d album", "%d albums", len(model) - 1) markup = text else: markup = self.display_pattern % album if self.__last_render == markup: return self.__last_render = markup cell.markup = markup cell.set_property('markup', markup) column.set_cell_data_func(render, cell_data) view.append_column(column) view.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE) view.set_rules_hint(True) view.set_search_equal_func(self.__search_func, None) view.set_search_column(0) view.set_model(model_filter) sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) sw.add(view) view.connect('row-activated', self.__play_selection) self.__sig = view.connect('selection-changed', util.DeferredSignal(self.__update_songs, owner=view)) targets = [("text/x-quodlibet-songs", Gtk.TargetFlags.SAME_APP, 1), ("text/uri-list", 0, 2)] targets = [Gtk.TargetEntry.new(*t) for t in targets] view.drag_source_set( Gdk.ModifierType.BUTTON1_MASK, targets, Gdk.DragAction.COPY) view.connect("drag-data-get", self.__drag_data_get) connect_obj(view, 'popup-menu', self.__popup, view, library) self.accelerators = Gtk.AccelGroup() search = SearchBarBox(completion=AlbumTagCompletion(), accel_group=self.accelerators, star=self.STAR) search.connect('query-changed', self.__update_filter) connect_obj(search, 'focus-out', lambda w: w.grab_focus(), view) self.__search = search prefs = PreferencesButton(self, model_sort) search.pack_start(prefs, False, True, 0) self.pack_start(Align(search, left=6, top=6), False, True, 0) self.pack_start(sw, True, True, 0) self.connect("destroy", self.__destroy) self.enable_row_update(view, sw, self.__cover_column) self.connect('key-press-event', self.__key_pressed, library.librarian) if app.cover_manager: connect_destroy( app.cover_manager, "cover-changed", self._cover_changed) 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"), 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, library, dir=None): super(ExFalsoWindow, self).__init__(dialog=False) self.set_title("Ex Falso") self.set_default_size(750, 475) self.enable_window_tracking("exfalso") self.__library = library hp = ConfigRHPaned("memory", "exfalso_paned_position", 1.0) hp.set_border_width(0) hp.set_position(250) hp.show() self.add(hp) vb = Gtk.VBox() bbox = Gtk.HBox(spacing=6) about = Gtk.Button() about.add( Gtk.Image.new_from_stock(Gtk.STOCK_ABOUT, Gtk.IconSize.BUTTON)) connect_obj(about, 'clicked', self.__show_about, self) bbox.pack_start(about, False, True, 0) prefs = Gtk.Button() prefs.add( Gtk.Image.new_from_stock(Gtk.STOCK_PREFERENCES, Gtk.IconSize.BUTTON)) def prefs_cb(button): window = PreferencesWindow(self) window.show() prefs.connect('clicked', prefs_cb) bbox.pack_start(prefs, False, True, 0) plugins = qltk.Button(_("_Plugins"), Gtk.STOCK_EXECUTE) def plugin_window_cb(button): window = PluginWindow(self) window.show() plugins.connect('clicked', plugin_window_cb) bbox.pack_start(plugins, False, True, 0) l = Gtk.Label() l.set_alignment(1.0, 0.5) l.set_ellipsize(Pango.EllipsizeMode.END) bbox.pack_start(l, True, True, 0) fs = MainFileSelector() vb.pack_start(fs, True, True, 0) vb.pack_start(Align(bbox, border=6), False, True, 0) vb.show_all() hp.pack1(vb, resize=True, shrink=False) nb = qltk.Notebook() nb.props.scrollable = True nb.show() for Page in [EditTags, TagsFromPath, RenameFiles, TrackNumbers]: page = Page(self, self.__library) page.show() nb.append_page(page) align = Align(nb, top=3) align.show() hp.pack2(align, resize=True, shrink=False) fs.connect('changed', self.__changed, l) if dir: fs.go_to(dir) connect_destroy(self.__library, 'changed', self.__library_changed, fs) self.__save = None connect_obj(self, 'changed', self.set_pending, None) for c in fs.get_children(): c.get_child().connect('button-press-event', self.__pre_selection_changed, fs, nb) c.get_child().connect('focus', self.__pre_selection_changed, fs, nb) fs.get_children()[1].get_child().connect('popup-menu', self.__popup_menu, fs) self.emit('changed', []) self.get_child().show() self.__ag = Gtk.AccelGroup() key, mod = Gtk.accelerator_parse("<control>Q") self.__ag.connect(key, mod, 0, lambda *x: self.destroy()) self.add_accel_group(self.__ag)
def __init__(self, library, dir=None): super(ExFalsoWindow, self).__init__(dialog=False) self.set_title("Ex Falso") self.set_default_size(750, 475) self.enable_window_tracking("exfalso") self.__library = library hp = ConfigRHPaned("memory", "exfalso_paned_position", 1.0) hp.set_border_width(0) hp.set_position(250) hp.show() self.add(hp) vb = Gtk.VBox() bbox = Gtk.HBox(spacing=6) def prefs_cb(*args): window = PreferencesWindow(self) window.show() def plugin_window_cb(*args): window = PluginWindow(self) window.show() def about_cb(*args): about = AboutDialog(self, app) about.run() about.destroy() def update_cb(*args): d = UpdateDialog(self) d.run() d.destroy() menu = Gtk.Menu() about_item = MenuItem(_("_About"), Icons.HELP_ABOUT) about_item.connect("activate", about_cb) menu.append(about_item) check_item = MenuItem(_("_Check for Updates…"), Icons.NETWORK_SERVER) check_item.connect("activate", update_cb) menu.append(check_item) menu.append(SeparatorMenuItem()) plugin_item = MenuItem(_("_Plugins"), Icons.SYSTEM_RUN) plugin_item.connect("activate", plugin_window_cb) menu.append(plugin_item) pref_item = MenuItem(_("_Preferences"), Icons.PREFERENCES_SYSTEM) pref_item.connect("activate", prefs_cb) menu.append(pref_item) menu.show_all() menu_button = MenuButton( SymbolicIconImage(Icons.EMBLEM_SYSTEM, Gtk.IconSize.BUTTON), arrow=True, down=False) menu_button.set_menu(menu) bbox.pack_start(menu_button, False, True, 0) l = Gtk.Label() l.set_alignment(1.0, 0.5) l.set_ellipsize(Pango.EllipsizeMode.END) bbox.pack_start(l, True, True, 0) fs = MainFileSelector() vb.pack_start(fs, True, True, 0) vb.pack_start(Align(bbox, border=6), False, True, 0) vb.show_all() hp.pack1(vb, resize=True, shrink=False) nb = qltk.Notebook() nb.props.scrollable = True nb.show() for Page in [EditTags, TagsFromPath, RenameFiles, TrackNumbers]: page = Page(self, self.__library) page.show() nb.append_page(page) hp.pack2(nb, resize=True, shrink=False) fs.connect('changed', self.__changed, l) if dir: fs.go_to(dir) connect_destroy(self.__library, 'changed', self.__library_changed, fs) self.__save = None connect_obj(self, 'changed', self.set_pending, None) for c in fs.get_children(): c.get_child().connect('button-press-event', self.__pre_selection_changed, fs, nb) c.get_child().connect('focus', self.__pre_selection_changed, fs, nb) fs.get_children()[1].get_child().connect('popup-menu', self.__popup_menu, fs) self.emit('changed', []) self.get_child().show() self.__ag = Gtk.AccelGroup() key, mod = Gtk.accelerator_parse("<Primary>Q") self.__ag.connect(key, mod, 0, lambda *x: self.destroy()) self.add_accel_group(self.__ag) # GtkosxApplication assumes the menu bar is mapped, so add # it but don't show it. self._dummy_osx_menu_bar = Gtk.MenuBar() vb.pack_start(self._dummy_osx_menu_bar, False, False, 0)
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(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, songs): super(FingerprintDialog, self).__init__() self.set_border_width(12) self.set_title(_("Submit Acoustic Fingerprints")) self.set_default_size(300, 0) outer_box = Gtk.VBox(spacing=12) box = Gtk.VBox(spacing=6) self.__label = label = Gtk.Label() label.set_markup("<b>%s</b>" % _("Generating fingerprints:")) label.set_alignment(0, 0.5) box.pack_start(label, False, True, 0) self.__bar = bar = Gtk.ProgressBar() self.__set_fraction(0) box.pack_start(bar, False, True, 0) self.__label_song = label_song = Gtk.Label() label_song.set_alignment(0, 0.5) label_song.set_ellipsize(Pango.EllipsizeMode.MIDDLE) box.pack_start(label_song, False, True, 0) self.__stats = stats = Gtk.Label() stats.set_alignment(0, 0.5) expand = Gtk.Expander.new_with_mnemonic(_("_Details")) expand.add(stats) def expand_cb(expand, *args): self.resize(self.get_size()[0], 1) stats.connect("unmap", expand_cb) box.pack_start(expand, False, False, 0) self.__fp_results = {} self.__fp_done = 0 self.__songs = songs self.__musicdns_thread = None self.__acoustid_thread = None self.__update_stats() pool = FingerPrintPool() bbox = Gtk.HButtonBox() bbox.set_layout(Gtk.ButtonBoxStyle.END) bbox.set_spacing(6) self.__submit = submit = Button(_("_Submit"), Gtk.STOCK_APPLY) submit.set_sensitive(False) submit.connect('clicked', self.__submit_cb) cancel = Gtk.Button(stock=Gtk.STOCK_CANCEL) connect_obj(cancel, 'clicked', self.__cancel_cb, pool) bbox.pack_start(submit, True, True, 0) bbox.pack_start(cancel, True, True, 0) outer_box.pack_start(box, True, True, 0) outer_box.pack_start(bbox, False, True, 0) pool.connect('fingerprint-done', self.__fp_done_cb) pool.connect('fingerprint-error', self.__fp_error_cb) pool.connect('fingerprint-started', self.__fp_started_cb) for song in songs: pool.push(song) connect_obj(self, 'delete-event', self.__cancel_cb, pool) self.add(outer_box) self.show_all()
def __create_menu(self, player, library): def add_view_items(ag): act = Action(name="Information", label=_('_Information'), icon_name=Icons.DIALOG_INFORMATION) act.connect('activate', self.__current_song_info) ag.add_action(act) act = Action(name="Jump", label=_('_Jump to Playing Song'), icon_name=Icons.GO_JUMP) self.__jump_to_current(True, None, True) act.connect('activate', self.__jump_to_current) ag.add_action_with_accel(act, "<Primary>J") def add_top_level_items(ag): ag.add_action(Action(name="File", label=_("_File"))) ag.add_action(Action(name="Song", label=_("_Song"))) ag.add_action(Action(name="View", label=_('_View'))) ag.add_action(Action(name="Browse", label=_("_Browse"))) ag.add_action(Action(name="Control", label=_('_Control'))) ag.add_action(Action(name="Help", label=_('_Help'))) ag = Gtk.ActionGroup.new('QuodLibetWindowActions') add_top_level_items(ag) add_view_items(ag) act = Action(name="AddFolders", label=_(u'_Add a Folder…'), icon_name=Icons.LIST_ADD) act.connect('activate', self.open_chooser) ag.add_action_with_accel(act, "<Primary>O") act = Action(name="AddFiles", label=_(u'_Add a File…'), icon_name=Icons.LIST_ADD) act.connect('activate', self.open_chooser) ag.add_action(act) act = Action(name="AddLocation", label=_(u'_Add a Location…'), icon_name=Icons.LIST_ADD) act.connect('activate', self.open_location) ag.add_action(act) act = Action(name="BrowseLibrary", label=_('Open _Browser'), icon_name=Icons.EDIT_FIND) ag.add_action(act) act = Action(name="Preferences", label=_('_Preferences'), icon_name=Icons.PREFERENCES_SYSTEM) act.connect('activate', self.__preferences) ag.add_action(act) act = Action(name="Plugins", label=_('_Plugins'), icon_name=Icons.SYSTEM_RUN) act.connect('activate', self.__plugins) ag.add_action(act) act = Action(name="Quit", label=_('_Quit'), icon_name=Icons.APPLICATION_EXIT) act.connect('activate', lambda *x: self.destroy()) ag.add_action_with_accel(act, "<Primary>Q") act = Action(name="EditTags", label=_('Edit _Tags'), icon_name=Icons.DOCUMENT_PROPERTIES) act.connect('activate', self.__current_song_prop) ag.add_action(act) act = Action(name="EditBookmarks", label=_(u"Edit Bookmarks…")) connect_obj(act, 'activate', self.__edit_bookmarks, library.librarian, player) ag.add_action_with_accel(act, "<Primary>B") act = Action(name="Previous", label=_('Pre_vious'), icon_name=Icons.MEDIA_SKIP_BACKWARD) act.connect('activate', self.__previous_song) ag.add_action_with_accel(act, "<Primary>comma") act = Action(name="PlayPause", label=_('_Play'), icon_name=Icons.MEDIA_PLAYBACK_START) act.connect('activate', self.__play_pause) ag.add_action_with_accel(act, "<Primary>space") act = Action(name="Next", label=_('_Next'), icon_name=Icons.MEDIA_SKIP_FORWARD) act.connect('activate', self.__next_song) ag.add_action_with_accel(act, "<Primary>period") act = ToggleAction(name="StopAfter", label=_("Stop After This Song")) ag.add_action_with_accel(act, "<shift>space") # access point for the tray icon self.stop_after = act act = Action(name="Shortcuts", label=_("_Keyboard Shortcuts")) act.connect('activate', self.__keyboard_shortcuts) ag.add_action_with_accel(act, "<Primary>question") act = Action(name="About", label=_("_About"), icon_name=Icons.HELP_ABOUT) act.connect('activate', self.__show_about) ag.add_action_with_accel(act, None) act = Action(name="OnlineHelp", label=_("Online Help"), icon_name=Icons.HELP_BROWSER) def website_handler(*args): util.website(const.ONLINE_HELP) act.connect('activate', website_handler) ag.add_action_with_accel(act, "F1") act = Action(name="SearchHelp", label=_("Search Help")) def search_help_handler(*args): util.website(const.SEARCH_HELP) act.connect('activate', search_help_handler) ag.add_action_with_accel(act, None) act = Action(name="CheckUpdates", label=_("_Check for Updates…"), icon_name=Icons.NETWORK_SERVER) def check_updates_handler(*args): d = UpdateDialog(self) d.run() d.destroy() act.connect('activate', check_updates_handler) ag.add_action_with_accel(act, None) act = Action(name="RefreshLibrary", label=_("_Scan Library"), icon_name=Icons.VIEW_REFRESH) act.connect('activate', self.__rebuild, False) ag.add_action_with_accel(act, "<Primary>R") current = config.get("memory", "browser") try: browsers.get(current) except ValueError: current = browsers.name(browsers.default) first_action = None for Kind in browsers.browsers: name = browsers.name(Kind) index = browsers.index(name) action_name = "View" + Kind.__name__ act = RadioAction(name=action_name, label=Kind.accelerated_name, value=index) act.join_group(first_action) first_action = first_action or act if name == current: act.set_active(True) ag.add_action_with_accel(act, "<Primary>%d" % ((index + 1) % 10, )) assert first_action self._browser_action = first_action def action_callback(view_action, current_action): current = browsers.name( browsers.get(current_action.get_current_value())) self._select_browser(view_action, current, library, player) first_action.connect("changed", action_callback) for Kind in browsers.browsers: action = "Browser" + Kind.__name__ label = Kind.accelerated_name name = browsers.name(Kind) index = browsers.index(name) act = Action(name=action, label=label) def browser_activate(action, Kind): LibraryBrowser.open(Kind, library, player) act.connect('activate', browser_activate, Kind) ag.add_action_with_accel(act, "<Primary><alt>%d" % ((index + 1) % 10, )) ui = Gtk.UIManager() ui.insert_action_group(ag, -1) menustr = MENU % { "views": browser_menu_items(), "browsers": secondary_browser_menu_items(), "filters_menu": FilterMenu.MENU } ui.add_ui_from_string(menustr) self._filter_menu = FilterMenu(library, player, ui) # Cute. So. UIManager lets you attach tooltips, but when they're # for menu items, they just get ignored. So here I get to actually # attach them. ui.get_widget("/Menu/File/RefreshLibrary").set_tooltip_text( _("Check for changes in your library")) return ui
def __init__(self, title, values=None): super().__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, player, debug=False): super(GstPlayerPreferences, self).__init__(spacing=6) e = UndoEntry() e.set_tooltip_text( _("The GStreamer output pipeline used for " "playback. Leave blank for the default pipeline. " "In case the pipeline contains a sink, " "it will be used instead of the default one.")) e.set_text(config.get('player', 'gst_pipeline')) def changed(entry): config.set('player', 'gst_pipeline', entry.get_text()) e.connect('changed', changed) pipe_label = Gtk.Label(label=_('_Output pipeline:')) pipe_label.set_use_underline(True) pipe_label.set_mnemonic_widget(e) apply_button = Button(_("_Apply")) def format_buffer(scale, value): return _("%.1f seconds") % value def scale_changed(scale): duration_msec = int(scale.get_value() * 1000) player._set_buffer_duration(duration_msec) duration = config.getfloat("player", "gst_buffer") scale = Gtk.HScale.new( Gtk.Adjustment(value=duration, lower=0.2, upper=10)) scale.set_value_pos(Gtk.PositionType.RIGHT) scale.set_show_fill_level(True) scale.connect('format-value', format_buffer) scale.connect('value-changed', scale_changed) buffer_label = Gtk.Label(label=_('_Buffer duration:')) buffer_label.set_use_underline(True) buffer_label.set_mnemonic_widget(scale) def rebuild_pipeline(*args): player._rebuild_pipeline() apply_button.connect('clicked', rebuild_pipeline) gapless_button = ConfigCheckButton(_('Disable _gapless playback'), "player", "gst_disable_gapless", populate=True) gapless_button.set_alignment(0.0, 0.5) gapless_button.set_tooltip_text( _("Disabling gapless playback can avoid track changing problems " "with some GStreamer versions")) widgets = [ (pipe_label, e, apply_button), (buffer_label, scale, None), ] table = Gtk.Table(n_rows=len(widgets), n_columns=3) table.set_col_spacings(6) table.set_row_spacings(6) for i, (left, middle, right) in enumerate(widgets): left.set_alignment(0.0, 0.5) table.attach(left, 0, 1, i, i + 1, xoptions=Gtk.AttachOptions.FILL | Gtk.AttachOptions.SHRINK) if right: table.attach(middle, 1, 2, i, i + 1) table.attach(right, 2, 3, i, i + 1, xoptions=Gtk.AttachOptions.FILL | Gtk.AttachOptions.SHRINK) else: table.attach(middle, 1, 3, i, i + 1) table.attach(gapless_button, 0, 3, 2, 3) self.pack_start(table, True, True, 0) if debug: def print_bin(player): player._print_pipeline() b = Button("Print Pipeline", Icons.DIALOG_INFORMATION) connect_obj(b, 'clicked', print_bin, player) self.pack_start(b, True, True, 0)
def __init__(self, library): Browser.__init__(self, spacing=6) self.set_orientation(Gtk.Orientation.VERTICAL) self.songcontainer = qltk.paned.ConfigRVPaned("browsers", "covergrid_pos", 0.4) if config.getboolean("browsers", "covergrid_wide", False): self.songcontainer.set_orientation(Gtk.Orientation.HORIZONTAL) self._register_instance() if self.__model is None: self._init_model(library) self._cover_cancel = Gio.Cancellable() self.scrollwin = sw = ScrolledWindow() sw.set_shadow_type(Gtk.ShadowType.IN) model_sort = AlbumSortModel(model=self.__model) model_filter = AlbumFilterModel(child_model=model_sort) self.view = view = IconView(model_filter) #view.set_item_width(get_cover_size() + 12) self.view.set_row_spacing(config.getint("browsers", "row_spacing", 6)) self.view.set_column_spacing( config.getint("browsers", "column_spacing", 6)) self.view.set_item_padding(config.getint("browsers", "item_padding", 6)) self.view.set_has_tooltip(True) self.view.connect("query-tooltip", self._show_tooltip) self.__bg_filter = background_filter() self.__filter = None model_filter.set_visible_func(self.__parse_query) mag = config.getfloat("browsers", "covergrid_magnification", 3.) self.view.set_item_width(get_cover_size() * mag + 8) self.__cover = render = Gtk.CellRendererPixbuf() render.set_property('width', get_cover_size() * mag + 8) render.set_property('height', get_cover_size() * mag + 8) view.pack_start(render, False) def cell_data_pb(view, cell, model, iter_, no_cover): item = model.get_value(iter_) if item.album is None: surface = None elif item.cover: pixbuf = item.cover pixbuf = add_border_widget(pixbuf, self.view) surface = get_surface_for_pixbuf(self, pixbuf) # don't cache, too much state has an effect on the result self.__last_render_surface = None else: surface = no_cover if self.__last_render_surface == surface: return self.__last_render_surface = surface cell.set_property("surface", surface) view.set_cell_data_func(render, cell_data_pb, self._no_cover) self.__text_cells = render = Gtk.CellRendererText() render.set_visible(config.getboolean("browsers", "album_text", True)) render.set_property('alignment', Pango.Alignment.CENTER) render.set_property('xalign', 0.5) render.set_property('ellipsize', Pango.EllipsizeMode.END) view.pack_start(render, False) def cell_data(view, cell, model, iter_, data): album = model.get_album(iter_) if album is None: text = "<b>%s</b>" % _("All Albums") text += "\n" + ngettext("%d album", "%d albums", len(model) - 1) % (len(model) - 1) markup = text else: markup = self.display_pattern % album if self.__last_render == markup: return self.__last_render = markup cell.markup = markup cell.set_property('markup', markup) view.set_cell_data_func(render, cell_data, None) view.set_selection_mode(Gtk.SelectionMode.MULTIPLE) sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) sw.add(view) view.connect('item-activated', self.__play_selection, None) self.__sig = connect_destroy( view, 'selection-changed', util.DeferredSignal(self.__update_songs, owner=self)) targets = [("text/x-quodlibet-songs", Gtk.TargetFlags.SAME_APP, 1), ("text/uri-list", 0, 2)] targets = [Gtk.TargetEntry.new(*t) for t in targets] view.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, targets, Gdk.DragAction.COPY) view.connect("drag-data-get", self.__drag_data_get) # NOT WORKING connect_obj(view, 'button-press-event', self.__rightclick, view, library) connect_obj(view, 'popup-menu', self.__popup, view, library) self.accelerators = Gtk.AccelGroup() search = SearchBarBox(completion=AlbumTagCompletion(), accel_group=self.accelerators) search.connect('query-changed', self.__update_filter) connect_obj(search, 'focus-out', lambda w: w.grab_focus(), view) self.__search = search prefs = PreferencesButton(self, model_sort) search.pack_start(prefs, False, True, 0) self.pack_start(Align(search, left=6, top=6), False, True, 0) self.pack_start(sw, True, True, 0) self.connect("destroy", self.__destroy) self.enable_row_update(view, sw, self.view) self.__update_filter() self.connect('key-press-event', self.__key_pressed, library.librarian) if app.cover_manager: connect_destroy(app.cover_manager, "cover-changed", self._cover_changed) self.show_all()
def add_edit_item(cls, submenu): config = Gtk.MenuItem(label=_("Edit Custom Commands") + "...") connect_obj(config, 'activate', cls.edit_patterns, config) config.set_sensitive(not JSONBasedEditor.is_not_unique()) submenu.append(SeparatorMenuItem()) submenu.append(config)
def __init__(self, model): songs_text = numeric_phrase("%d duplicate group", "%d duplicate groups", len(model)) super().__init__() self.set_destroy_with_parent(True) self.set_title("Quod Libet - %s (%s)" % (Duplicates.PLUGIN_NAME, songs_text)) self.finished = False self.set_default_size(960, 480) self.set_border_width(6) swin = Gtk.ScrolledWindow() swin.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) swin.set_shadow_type(Gtk.ShadowType.IN) # Set up the browser view view = DuplicateSongsView(model) def cell_text(column, cell, model, iter_, index): text = model[iter_][index] cell.markup = text cell.set_property("markup", text) # Set up the columns for i, (tag, f) in enumerate(DuplicatesTreeModel.TAG_MAP): e = (Pango.EllipsizeMode.START if tag == '~filename' else Pango.EllipsizeMode.END) render = Gtk.CellRendererText() render.set_property("ellipsize", e) col = Gtk.TreeViewColumn(util.tag(tag), render) # Numeric columns are better smaller here. if tag.startswith("~#"): col.set_fixed_width(80) col.set_sizing(Gtk.TreeViewColumnSizing.FIXED) else: col.set_expand(True) col.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) col.set_resizable(True) col.set_cell_data_func(render, cell_text, i + 1) view.append_column(col) view.connect('popup-menu', self.__songs_popup_menu) swin.add(view) # A basic information area hbox = Gtk.HBox(spacing=6) def expand_all(*args): model = view.get_model() for row in model: if view.row_expanded(row.path): view.collapse_row(row.path) else: for row in model: view.expand_row(row.path, False) expand = Gtk.Button(_("Collapse / Expand all")) connect_obj(expand, "clicked", expand_all, view) hbox.pack_start(expand, False, True, 0) label = Gtk.Label(label=_("Duplicate key expression is '%s'") % Duplicates.get_key_expression()) hbox.pack_start(label, True, True, 0) close = Button(_("_Close"), Icons.WINDOW_CLOSE) close.connect('clicked', self.__quit) hbox.pack_start(close, False, True, 0) vbox = Gtk.VBox(spacing=6) vbox.pack_start(swin, True, True, 0) vbox.pack_start(hbox, False, True, 0) self.add(vbox) self.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 = TreeViewColumnButton(title=self.config.title) def on_column_header_clicked(column, event): # In case the column header gets clicked select the "All" entry if event.button != Gdk.BUTTON_PRIMARY or \ event.type != Gdk.EventType.BUTTON_PRESS: return Gdk.EVENT_PROPAGATE self.set_selected([]) return Gdk.EVENT_STOP column.set_clickable(True) column.connect("button-press-event", on_column_header_clicked) 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 = self.connect( 'selection-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, Kind, value, traceback, dump, minidump): # This is all implemented a bit different than the rest of Quod # Libet's windows since I want it to be as stupid as possible, to # minimize the chances of something going wrong with the thing # that handles things going wrong, i.e. it only uses GTK+ code, # no QLTK wrappers. Gtk.Window.__init__(self) self.set_default_size(400, 400) self.set_border_width(12) self.set_title(_("Error Occurred")) desc = _( "An exception has occured in Quod Libet. A dump file has " "been saved to <b >%(dump-path)s</b> that will help us debug the " "crash. " "Please file a new issue at %(new-issue-url)s" "and attach this file or include its contents. This " "file may contain some identifying information about you or your " "system, such as a list of recent files played. If this is " "unacceptable, send <b>%(mini-dump-path)s</b> instead with a " "description of what " "you were doing.") % { "dump-path": unexpand(dump), "mini-dump-path": unexpand(minidump), "new-issue-url": "https://github.com/quodlibet/quodlibet/issues/new", } suggestion = _( "Quod Libet may now be unstable. Closing it and " "restarting is recommended. Your library will be saved.") label = Gtk.Label(label=desc + "\n\n" + suggestion) label.set_selectable(True) label.set_use_markup(True) label.set_line_wrap(True) box = Gtk.VBox(spacing=6) buttons = Gtk.HButtonBox() view = Gtk.TreeView() sw = Gtk.ScrolledWindow() sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.ALWAYS) sw.set_shadow_type(Gtk.ShadowType.IN) sw.add(view) model = Gtk.ListStore(str, str, int) self.__fill_list(view, model, value, traceback) view.set_model(model) cancel = qltk.Button(_("_Cancel")) close = qltk.Button(_("_Quit"), Icons.APPLICATION_EXIT) buttons.pack_start(close, True, True, 0) buttons.pack_start(cancel, True, True, 0) box.pack_start(label, False, True, 0) box.pack_start(sw, True, True, 0) box.pack_start(buttons, False, True, 0) self.add(box) self.connect('destroy', self.__destroy) connect_obj(cancel, 'clicked', Gtk.Window.destroy, self) close.connect('clicked', lambda *x: Gtk.main_quit()) self.get_child().show_all() def first_draw(*args): filename = unexpand(dump) offset = gdecode(label.get_text()).find(filename) label.select_region(offset, offset + len(filename)) self.disconnect(self.__draw_id) self.__draw_id = self.connect("draw", first_draw)
def __init__(self, app, add_show_item=False): super(IndicatorMenu, self).__init__() self._app = app player = app.player show_item_bottom = is_kde() if add_show_item: show_item = Gtk.CheckMenuItem.new_with_mnemonic( _("_Show %(application-name)s") % { "application-name": app.name}) def on_toggled(menuitem): app.window.set_visible(menuitem.get_active()) pconfig.set("window_visible", menuitem.get_active()) self._toggle_id = show_item.connect("toggled", on_toggled) def on_visible_changed(*args): with show_item.handler_block(self._toggle_id): show_item.set_active(app.window.get_visible()) connect_destroy(app.window, "notify::visible", on_visible_changed) else: show_item = None self._play_item = MenuItem(_("_Play"), Icons.MEDIA_PLAYBACK_START) self._play_item.connect("activate", self._on_play_pause, player) self._play_item.set_no_show_all(True) self._pause_item = MenuItem(_("P_ause"), Icons.MEDIA_PLAYBACK_PAUSE) self._pause_item.connect("activate", self._on_play_pause, player) self._pause_item.set_no_show_all(True) self._action_item = None previous = MenuItem(_("Pre_vious"), Icons.MEDIA_SKIP_BACKWARD) previous.connect('activate', lambda *args: player.previous(force=True)) next = MenuItem(_("_Next"), Icons.MEDIA_SKIP_FORWARD) next.connect('activate', lambda *args: player.next()) player_options = app.player_options shuffle = Gtk.CheckMenuItem(label=_("_Shuffle"), use_underline=True) player_options.bind_property("random", shuffle, "active", GObject.BindingFlags.BIDIRECTIONAL) player_options.notify("random") repeat = Gtk.CheckMenuItem(label=_("_Repeat"), use_underline=True) player_options.bind_property("repeat", repeat, "active", GObject.BindingFlags.BIDIRECTIONAL) player_options.notify("repeat") safter = Gtk.CheckMenuItem(label=_("Stop _After This Song"), use_underline=True) player_options.bind_property("stop-after", safter, "active", GObject.BindingFlags.BIDIRECTIONAL) player_options.notify("stop-after") browse = qltk.MenuItem(_("Open _Browser"), Icons.EDIT_FIND) browse_sub = Gtk.Menu() for Kind in browsers.browsers: if Kind.is_empty: continue i = Gtk.MenuItem(label=Kind.accelerated_name, use_underline=True) connect_obj(i, 'activate', LibraryBrowser.open, Kind, app.library, app.player) browse_sub.append(i) browse.set_submenu(browse_sub) self._props = qltk.MenuItem(_("Edit _Tags"), Icons.DOCUMENT_PROPERTIES) def on_properties(*args): song = player.song window = SongProperties(app.librarian, [song]) window.show() self._props.connect('activate', on_properties) self._info = MenuItem(_("_Information"), Icons.DIALOG_INFORMATION) def on_information(*args): song = player.song window = Information(app.librarian, [song]) window.show() self._info.connect('activate', on_information) def set_rating(value): song = player.song song["~#rating"] = value app.librarian.changed([song]) self._rating_item = rating = RatingsMenuItem([], app.library) quit = MenuItem(_("_Quit"), Icons.APPLICATION_EXIT) quit.connect('activate', lambda *x: app.quit()) if not show_item_bottom and show_item: self.append(show_item) self.append(SeparatorMenuItem()) self.append(self._play_item) self.append(self._pause_item) self.append(previous) self.append(next) self.append(SeparatorMenuItem()) self.append(shuffle) self.append(repeat) self.append(safter) self.append(SeparatorMenuItem()) self.append(rating) self.append(self._props) self.append(self._info) self.append(SeparatorMenuItem()) self.append(browse) self.append(SeparatorMenuItem()) self.append(quit) if show_item_bottom and show_item: self.append(SeparatorMenuItem()) self.append(show_item) self.show_all() self.set_paused(True) self.set_song(None)
def __init__(self, Prototype, values, filename, title): if self.is_not_unique(): return super().__init__() self.Prototype = Prototype self.current = None self.filename = filename self.name = Prototype.NAME or Prototype.__name__ self.input_entries = {} self.set_border_width(12) self.set_title(title) self.set_default_size(self._WIDTH, self._HEIGHT) self.add(Gtk.HBox(spacing=6)) self.get_child().set_homogeneous(True) self.accels = Gtk.AccelGroup() # Set up the model for this widget self.model = Gtk.ListStore(object) self._fill_values(values) # The browser for existing data self.view = view = RCMHintedTreeView(model=self.model) view.set_headers_visible(False) view.set_reorderable(True) view.set_rules_hint(True) render = Gtk.CellRendererText() render.set_padding(3, 6) render.props.ellipsize = Pango.EllipsizeMode.END column = Gtk.TreeViewColumn("", render) column.set_cell_data_func(render, self.__cdf) view.append_column(column) sw = Gtk.ScrolledWindow() sw.set_shadow_type(Gtk.ShadowType.IN) sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) sw.add(view) self.get_child().pack_start(sw, True, True, 0) vbox = Gtk.VBox(spacing=6) # Input for new ones. frame = self.__build_input_frame() vbox.pack_start(frame, False, True, 0) # Add context menu menu = Gtk.Menu() rem = MenuItem(_("_Remove"), Icons.LIST_REMOVE) keyval, mod = Gtk.accelerator_parse("Delete") rem.add_accelerator('activate', self.accels, keyval, mod, Gtk.AccelFlags.VISIBLE) connect_obj(rem, 'activate', self.__remove, view) menu.append(rem) menu.show_all() view.connect('popup-menu', self.__popup, menu) view.connect('key-press-event', self.__view_key_press) connect_obj(self, 'destroy', Gtk.Menu.destroy, menu) # New and Close buttons bbox = Gtk.HButtonBox() self.remove_but = Button(_("_Remove"), Icons.LIST_REMOVE) self.remove_but.set_sensitive(False) self.new_but = Button(_("_New"), Icons.DOCUMENT_NEW) self.new_but.connect('clicked', self._new_item) bbox.pack_start(self.new_but, True, True, 0) close = Button(_("_Close"), Icons.WINDOW_CLOSE) connect_obj(close, 'clicked', qltk.Window.destroy, self) bbox.pack_start(close, True, True, 0) vbox.pack_end(bbox, False, True, 0) self.get_child().pack_start(vbox, True, True, 0) # Initialise self.selection = view.get_selection() self.selection.connect('changed', self.__select) self.connect('destroy', self.__finish) self.get_child().show_all()
def __init__(self, library): super(MediaDevices, self).__init__(spacing=6) self.set_orientation(Gtk.Orientation.VERTICAL) self._register_instance() self.__cache = {} # Device list on the left pane swin = ScrolledWindow() swin.set_shadow_type(Gtk.ShadowType.IN) swin.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) self.pack_start(swin, True, True, 0) self.__view = view = AllTreeView() view.set_model(self.__devices) view.set_rules_hint(True) view.set_headers_visible(False) view.get_selection().set_mode(Gtk.SelectionMode.BROWSE) connect_obj(view.get_selection(), 'changed', self.__refresh, False) view.connect('popup-menu', self.__popup_menu, library) view.connect('row-activated', lambda *a: self.songs_activated()) swin.add(view) col = Gtk.TreeViewColumn("Devices") view.append_column(col) render = Gtk.CellRendererPixbuf() col.pack_start(render, False) col.add_attribute(render, 'icon-name', 1) self.__render = render = Gtk.CellRendererText() render.set_property('ellipsize', Pango.EllipsizeMode.END) render.connect('edited', self.__edited) col.pack_start(render, True) col.set_cell_data_func(render, MediaDevices.cell_data) hbox = Gtk.HBox(spacing=6) hbox.set_homogeneous(True) self.pack_start(Align(hbox, left=3, bottom=3), False, True, 0) # refresh button refresh = Button(_("_Refresh"), Icons.VIEW_REFRESH, Gtk.IconSize.MENU) self.__refresh_button = refresh connect_obj(refresh, 'clicked', self.__refresh, True) refresh.set_sensitive(False) hbox.pack_start(refresh, True, True, 0) # eject button eject = Button(_("_Eject"), Icons.MEDIA_EJECT, Gtk.IconSize.MENU) self.__eject_button = eject eject.connect('clicked', self.__eject) eject.set_sensitive(False) hbox.pack_start(eject, True, True, 0) # Device info on the right pane self.__header = table = Gtk.Table() table.set_col_spacings(8) self.__device_icon = icon = Gtk.Image() icon.set_size_request(48, 48) table.attach(icon, 0, 1, 0, 2, 0) self.__device_name = label = Gtk.Label() label.set_ellipsize(Pango.EllipsizeMode.END) label.set_alignment(0, 0) table.attach(label, 1, 3, 0, 1) self.__device_space = label = Gtk.Label() label.set_ellipsize(Pango.EllipsizeMode.END) label.set_alignment(0, 0.5) table.attach(label, 1, 2, 1, 2) self.__progress = progress = Gtk.ProgressBar() progress.set_size_request(150, -1) table.attach(progress, 2, 3, 1, 2, xoptions=0, yoptions=0) self.accelerators = Gtk.AccelGroup() key, mod = Gtk.accelerator_parse('F2') self.accelerators.connect(key, mod, 0, self.__rename) self.__statusbar = WaitLoadBar() for child in self.get_children(): child.show_all()
def edit_pattern(button): w = PatternEdit(button, AnimOsd.ConfDef.string) w.set_default_size(520, 260) w.text = self.Conf.string connect_obj(w.apply, 'clicked', set_string, w) w.show()
def __init__(self, library): super(CollectionBrowser, self).__init__(spacing=6) self._register_instance() if self.__model is None: self._init_model(library) sw = ScrolledWindow() sw.set_shadow_type(Gtk.ShadowType.IN) self.view = view = CollectionView() view.set_headers_visible(False) model_sort = CollectionSortModel(model=self.__model) model_filter = CollectionFilterModel(child_model=model_sort) self.__filter = None self.__bg_filter = background_filter() model_filter.set_visible_func(self.__parse_query) view.set_model(model_filter) def sort(model, i1, i2, data): t1, t2 = model[i1][0], model[i2][0] if t1 is None or t2 is None: # FIXME: why? return 0 # FIXME: order this deterministically if t1 is MultiNode or t1 is UnknownNode or \ t2 is MultiNode or t2 is UnknownNode: return -cmp(t1, t2) if not isinstance(t1, Album): return cmp(util.human_sort_key(t1), util.human_sort_key(t2)) a1, a2 = t1, t2 return (cmp(a1.peoplesort and a1.peoplesort[0], a2.peoplesort and a2.peoplesort[0]) or cmp(a1.date or "ZZZZ", a2.date or "ZZZZ") or cmp( (a1.sort, a1.key), (a2.sort, a2.key))) model_sort.set_sort_func(0, sort) model_sort.set_sort_column_id(0, Gtk.SortType.ASCENDING) column = Gtk.TreeViewColumn("albums") def cell_data(column, cell, model, iter_, data): markup = model.get_markup(self.__model.tags, iter_) cell.markup = markup cell.set_property('markup', markup) def get_scaled_cover(album): # XXX: Cache this somewhere else cover = None if not hasattr(album, "_scaled_cover"): scale_factor = get_scale_factor(self) album.scan_cover(scale_factor=scale_factor) if album.cover: s = 25 * scale_factor cover = scale(album.cover, (s, s)) album._scaled_cover = cover else: cover = album._scaled_cover return cover def cell_data_pb(column, cell, model, iter_, data): album = model.get_album(iter_) if album is None: cell.set_property('stock_id', Gtk.STOCK_DIRECTORY) else: cover = get_scaled_cover(album) if cover: round_ = config.getboolean("albumart", "round") cover = add_border_widget(cover, view, cell, round=round_) pbosf = get_pbosf_for_pixbuf(self, cover) set_renderer_from_pbosf(cell, pbosf) else: cell.set_property('stock_id', Gtk.STOCK_CDROM) imgrender = Gtk.CellRendererPixbuf() render = Gtk.CellRendererText() if view.supports_hints(): render.set_property('ellipsize', Pango.EllipsizeMode.END) column.pack_start(imgrender, False) column.pack_start(render, True) column.set_cell_data_func(render, cell_data) column.set_cell_data_func(imgrender, cell_data_pb) view.append_column(column) sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) sw.add(view) hbox = Gtk.HBox(spacing=6) prefs = Gtk.Button() prefs.add(SymbolicIconImage("emblem-system", Gtk.IconSize.MENU)) prefs.connect('clicked', lambda *x: Preferences(self)) search = SearchBarBox(completion=AlbumTagCompletion(), accel_group=self.accelerators) search.connect('query-changed', self.__update_filter) self.__search = search hbox.pack_start(search, True, True, 0) hbox.pack_start(prefs, False, True, 0) self.pack_start(Align(hbox, left=6, top=6), False, True, 0) self.pack_start(sw, True, True, 0) view.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE) self.__sig = view.get_selection().connect('changed', self.__selection_changed) view.connect('row-activated', self.__play) connect_obj(view, 'popup-menu', self.__popup, view, library) targets = [("text/x-quodlibet-songs", Gtk.TargetFlags.SAME_APP, 1), ("text/uri-list", 0, 2)] targets = [Gtk.TargetEntry.new(*t) for t in targets] view.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, targets, Gdk.DragAction.COPY) view.connect("drag-data-get", self.__drag_data_get) self.connect("destroy", self.__destroy) self.show_all()
def _popup_menu(self, icon, button, time): if self.__destroy_win32_menu(): return self.__menu = menu = Gtk.Menu() player = app.player window = app.window pp_icon = [Gtk.STOCK_MEDIA_PAUSE, Gtk.STOCK_MEDIA_PLAY][player.paused] playpause = Gtk.ImageMenuItem.new_from_stock(pp_icon, None) playpause.connect('activate', self.__play_pause) previous = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_MEDIA_PREVIOUS, None) previous.connect('activate', lambda *args: player.previous()) next = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_MEDIA_NEXT, None) next.connect('activate', lambda *args: player.next()) orders = Gtk.MenuItem(label=_("Play _Order"), use_underline=True) repeat = Gtk.CheckMenuItem(label=_("_Repeat"), use_underline=True) repeat.set_active(window.repeat.get_active()) repeat.connect('toggled', lambda s: window.repeat.set_active(s.get_active())) def set_safter(widget, safter_action): safter_action.set_active(widget.get_active()) safter_action = app.window.stop_after safter = Gtk.CheckMenuItem(label=_("Stop _after this song"), use_underline=True) safter.set_active(safter_action.get_active()) safter.connect('toggled', set_safter, safter_action) def set_order(widget, order): name = order.name try: window.order.set_active_by_name(name) except ValueError: pass order_items = [] item = None active_order = window.order.get_active() for Kind in ORDERS: item = RadioMenuItem(group=item, label=Kind.accelerated_name, use_underline=True) order_items.append(item) if Kind is active_order: item.set_active(True) item.connect('toggled', set_order, Kind) order_sub = Gtk.Menu() order_sub.append(repeat) order_sub.append(safter) order_sub.append(SeparatorMenuItem()) for item in order_items: order_sub.append(item) orders.set_submenu(order_sub) browse = qltk.MenuItem(_("_Browse Library"), Gtk.STOCK_FIND) browse_sub = Gtk.Menu() for Kind in browsers.browsers: if not Kind.in_menu: continue i = Gtk.MenuItem(label=Kind.accelerated_name, use_underline=True) connect_obj(i, 'activate', LibraryBrowser.open, Kind, app.library, app.player) browse_sub.append(i) browse.set_submenu(browse_sub) props = qltk.MenuItem(_("Edit _Tags"), Gtk.STOCK_PROPERTIES) props.connect('activate', self.__properties) info = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_INFO, None) info.connect('activate', self.__information) def set_rating(value): song = player.song if song is None: return else: song["~#rating"] = value app.librarian.changed([song]) rating = Gtk.MenuItem(label=_("_Rating"), use_underline=True) rating_sub = Gtk.Menu() for r in RATINGS.all: item = Gtk.MenuItem(label="%0.2f\t%s" % (r, util.format_rating(r))) connect_obj(item, 'activate', set_rating, r) rating_sub.append(item) rating.set_submenu(rating_sub) quit = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_QUIT, None) quit.connect('activate', lambda *x: app.quit()) menu.append(playpause) menu.append(SeparatorMenuItem()) menu.append(previous) menu.append(next) menu.append(orders) menu.append(SeparatorMenuItem()) menu.append(browse) menu.append(SeparatorMenuItem()) menu.append(props) menu.append(info) menu.append(rating) menu.append(SeparatorMenuItem()) menu.append(quit) menu.show_all() if sys.platform in ("win32", "darwin"): pos_func = pos_arg = None else: pos_func = Gtk.StatusIcon.position_menu pos_arg = self._icon menu.popup(None, None, pos_func, pos_arg, button, time)
def __popup_menu(self, view, parent): menu = Gtk.Menu() view.ensure_popup_selection() model, rows = view.get_selection().get_selected_rows() can_change = min([model[path][0].canedit for path in rows]) items = [ SplitDisc, SplitTitle, SplitPerformer, SplitArranger, SplitValues, SplitPerformerFromTitle, SplitOriginalArtistFromTitle ] items.extend(self.handler.plugins) items.sort(key=lambda item: (item._order, item.__name__)) if len(rows) == 1: row = model[rows[0]] entry = row[0] comment = entry.value text = comment.text split_menu = Gtk.Menu() for Item in items: if Item.tags and entry.tag not in Item.tags: continue try: b = Item(entry.tag, text) except: util.print_exc() else: b.connect('activate', self.__menu_activate, view) if (not min( list(map(self.__songinfo.can_change, b.needs)) + [1]) or comment.is_special()): b.set_sensitive(False) vals = b.activated(entry.tag, text) if len(vals) > 1 and vals[1][1]: split_menu.append(b) if split_menu.get_children(): split_menu.append(SeparatorMenuItem()) pref_item = MenuItem(_("_Configure"), Icons.PREFERENCES_SYSTEM) split_menu.append(pref_item) def show_prefs(parent): from quodlibet.qltk.exfalsowindow import ExFalsoWindow if isinstance(app.window, ExFalsoWindow): from quodlibet.qltk.exfalsowindow import PreferencesWindow window = PreferencesWindow(parent) else: from quodlibet.qltk.prefs import PreferencesWindow window = PreferencesWindow(parent, open_page="tagging") window.show() connect_obj(pref_item, "activate", show_prefs, self) split_item = MenuItem(_("_Split Tag"), Icons.EDIT_FIND_REPLACE) if split_menu.get_children(): split_item.set_submenu(split_menu) else: split_item.set_sensitive(False) menu.append(split_item) copy_b = MenuItem(_("_Copy Value(s)"), Icons.EDIT_COPY) copy_b.connect('activate', self.__copy_tag_value, view) qltk.add_fake_accel(copy_b, "<Primary>c") menu.append(copy_b) remove_b = MenuItem(_("_Remove"), Icons.LIST_REMOVE) remove_b.connect('activate', self.__remove_tag, view) qltk.add_fake_accel(remove_b, "Delete") menu.append(remove_b) menu.show_all() # Setting the menu itself to be insensitive causes it to not # be dismissed; see #473. for c in menu.get_children(): c.set_sensitive(can_change and c.get_property('sensitive')) copy_b.set_sensitive(True) remove_b.set_sensitive(True) menu.connect('selection-done', lambda m: m.destroy()) # XXX: Keep reference self.__menu = menu return view.popup_menu(menu, 3, Gtk.get_current_event_time())
def __init__(self, parent, library): super().__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, library, player): super(QueueExpander, self).__init__(spacing=3) sw = ScrolledWindow() sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) sw.set_shadow_type(Gtk.ShadowType.IN) self.queue = PlayQueue(library, player) self.queue.props.expand = True sw.add(self.queue) add_css(self, ".ql-expanded title { margin-bottom: 5px; }") outer = ExpandBoxHack(spacing=12) left = Gtk.HBox(spacing=12) hb2 = Gtk.HBox(spacing=3) state_icon = PlaybackStatusIcon() state_icon.stop() state_icon.show() hb2.pack_start(state_icon, True, True, 0) name_label = Gtk.Label(label=_("_Queue"), use_underline=True) hb2.pack_start(name_label, True, True, 0) left.pack_start(hb2, False, True, 0) b = SmallImageButton( image=SymbolicIconImage(Icons.EDIT_CLEAR, Gtk.IconSize.MENU)) b.set_tooltip_text(_("Remove all songs from the queue")) b.connect('clicked', self.__clear_queue) b.set_no_show_all(True) b.set_relief(Gtk.ReliefStyle.NONE) left.pack_start(b, False, False, 0) self.count_label = count_label = Gtk.Label() left.pack_start(count_label, False, True, 0) outer.pack_start(left, True, True, 0) close_button = SmallImageButton(image=SymbolicIconImage( "window-close", Gtk.IconSize.MENU), relief=Gtk.ReliefStyle.NONE) close_button.connect("clicked", lambda *x: self.hide()) outer.pack_start(close_button, False, False, 6) self.set_label_fill(True) cb = ConfigCheckButton(_("_Random"), "memory", "shufflequeue") cb.connect('toggled', self.__queue_shuffle, self.queue.model) cb.set_active(config.getboolean("memory", "shufflequeue")) cb.set_no_show_all(True) left.pack_start(cb, False, True, 0) self.set_label_widget(outer) self.add(sw) connect_obj(self, 'notify::expanded', self.__expand, cb, b) targets = [("text/x-quodlibet-songs", Gtk.TargetFlags.SAME_APP, DND_QL), ("text/uri-list", 0, DND_URI_LIST)] targets = [Gtk.TargetEntry.new(*t) for t in targets] self.drag_dest_set(Gtk.DestDefaults.ALL, targets, Gdk.DragAction.COPY) self.connect('drag-motion', self.__motion) self.connect('drag-data-received', self.__drag_data_received) self.queue.model.connect_after( 'row-inserted', util.DeferredSignal(self.__check_expand), count_label) self.queue.model.connect_after( 'row-deleted', util.DeferredSignal(self.__update_count), count_label) connect_obj(self, 'notify::visible', self.__visible, cb, b) self.__update_count(self.model, None, count_label) connect_destroy(player, 'song-started', self.__update_state_icon, state_icon) connect_destroy(player, 'paused', self.__update_state_icon_pause, state_icon, True) connect_destroy(player, 'unpaused', self.__update_state_icon_pause, state_icon, False) # to make the children clickable if mapped # ....no idea why, but works def hack(expander): label = expander.get_label_widget() if label: label.unmap() label.map() self.connect("map", hack) self.set_expanded(config.getboolean("memory", "queue_expanded")) self.notify("expanded") for child in self.get_children(): child.show_all()
def setUp(self): self.librarian = self.Librarian() self.Library.librarian = self.librarian self.lib1 = self.Library("One") self.lib2 = self.Library("Two") self.added_1 = [] self.changed_1 = [] self.removed_1 = [] self.added_2 = [] self.changed_2 = [] self.removed_2 = [] self.added = [] self.changed = [] self.removed = [] connect_obj(self.lib1, 'added', list.extend, self.added_1) connect_obj(self.lib1, 'changed', list.extend, self.changed_1) connect_obj(self.lib1, 'removed', list.extend, self.removed_1) connect_obj(self.lib2, 'added', list.extend, self.added_2) connect_obj(self.lib2, 'changed', list.extend, self.changed_2) connect_obj(self.lib2, 'removed', list.extend, self.removed_2) connect_obj(self.librarian, 'added', list.extend, self.added) connect_obj(self.librarian, 'changed', list.extend, self.changed) connect_obj(self.librarian, 'removed', list.extend, self.removed)
def __init__(self): super(Kakasi, self).__init__( _("Romanize _Japanese text"), use_underline=True) connect_obj(self, 'toggled', self.emit, 'preview')
def __init__(self, library, song, close=False): super().__init__(spacing=6) hb = Gtk.HBox(spacing=12) self.time = time = Gtk.Entry() time.set_width_chars(5) self.markname = name = Gtk.Entry() add = qltk.Button(_("_Add"), Icons.LIST_ADD, Gtk.IconSize.MENU) hb.pack_start(time, False, True, 0) hb.pack_start(name, True, True, 0) hb.pack_start(add, False, True, 0) self.pack_start(hb, False, True, 0) model = Gtk.ListStore(int, str) sw = Gtk.ScrolledWindow() sw.set_shadow_type(Gtk.ShadowType.IN) sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) sw.add(RCMHintedTreeView(model=model)) render = Gtk.CellRendererText() def cdf(column, cell, model, iter, data): if model[iter][0] < 0: cell.set_property('text', _("N/A")) else: cell.set_property('text', util.format_time(model[iter][0])) render.set_property('editable', True) render.connect('edited', self.__edit_time, model) col = Gtk.TreeViewColumn(_("Time"), render) col.set_cell_data_func(render, cdf, None) sw.get_child().append_column(col) render = Gtk.CellRendererText() render.set_property('ellipsize', Pango.EllipsizeMode.END) col = Gtk.TreeViewColumn(_("Bookmark Name"), render, text=1) render.set_property('editable', True) render.connect('edited', self.__edit_name, model) sw.get_child().append_column(col) self.pack_start(sw, True, True, 0) self.accels = Gtk.AccelGroup() hbox = Gtk.HButtonBox() remove = qltk.Button(_("_Remove"), Icons.LIST_REMOVE) remove.set_sensitive(False) hbox.pack_start(remove, True, True, 0) if close: self.close = qltk.Button(_("_Close"), Icons.WINDOW_CLOSE) hbox.pack_start(self.close, True, True, 0) else: hbox.set_layout(Gtk.ButtonBoxStyle.END) self.pack_start(hbox, False, True, 0) connect_obj(add, 'clicked', self.__add, model, time, name) model.set_sort_column_id(0, Gtk.SortType.ASCENDING) model.connect('row-changed', self._set_bookmarks, library, song) model.connect('row-inserted', self._set_bookmarks, library, song) selection = sw.get_child().get_selection() selection.set_mode(Gtk.SelectionMode.MULTIPLE) selection.connect('changed', self.__check_selection, remove) remove.connect('clicked', self.__remove, selection, library, song) connect_obj(time, 'changed', self.__check_entry, add, time, name) connect_obj(name, 'changed', self.__check_entry, add, time, name) connect_obj(name, 'activate', Gtk.Button.clicked, add) time.set_text(_("MM:SS")) connect_obj(time, 'activate', Gtk.Entry.grab_focus, name) name.set_text(_("Bookmark Name")) menu = Gtk.Menu() remove = qltk.MenuItem(_("_Remove"), Icons.LIST_REMOVE) remove.connect('activate', self.__remove, selection, library, song) keyval, mod = Gtk.accelerator_parse("Delete") remove.add_accelerator( 'activate', self.accels, keyval, mod, Gtk.AccelFlags.VISIBLE) menu.append(remove) menu.show_all() sw.get_child().connect('popup-menu', self.__popup, menu) sw.get_child().connect('key-press-event', self.__view_key_press, remove) connect_obj(self, 'destroy', Gtk.Menu.destroy, menu) self.__fill(model, song)