def setUp(self): config.init() self.h = SongsMenuPluginHandler() library = SongLibrary() library.librarian = SongLibrarian() self.lib = library self.parent = Gtk.Window()
def setUp(self): self.tempdir = mkdtemp() self.pm = PluginManager(folders=[self.tempdir]) self.confirmed = False self.handler = SongsMenuPluginHandler(self._confirmer, self._confirmer) self.pm.register_handler(self.handler) self.pm.rescan() self.assertEquals(self.pm.plugins, []) self.library = SongLibrary('foo')
class ExFalsoWindow(Window, PersistentWindowMixin): __gsignals__ = { 'changed': (GObject.SignalFlags.RUN_LAST, None, (object, )), } pm = SongsMenuPluginHandler() @classmethod def init_plugins(cls): PluginManager.instance.register_handler(cls.pm) 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_icon_name(Icons.HELP_ABOUT, Gtk.IconSize.BUTTON)) connect_obj(about, 'clicked', self.__show_about, self) bbox.pack_start(about, False, True, 0) def prefs_cb(*args): window = PreferencesWindow(self) window.show() def plugin_window_cb(*args): window = PluginWindow(self) window.show() menu = Gtk.Menu() 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 __library_changed(self, library, songs, fs): fs.rescan() def set_as_osx_window(self, osx_app): osx_app.set_menu_bar(self._dummy_osx_menu_bar) def get_osx_is_persistent(self): return False def __show_about(self, window): about = AboutExFalso(self) about.run() about.destroy() def set_pending(self, button, *excess): self.__save = button def __pre_selection_changed(self, view, event, fs, nb): if self.__save: resp = qltk.CancelRevertSave(self).run() if resp == Gtk.ResponseType.YES: self.__save.clicked() elif resp == Gtk.ResponseType.NO: fs.rescan() else: nb.grab_focus() return True # cancel or closed def __popup_menu(self, view, fs): # get all songs for the selection filenames = [ normalize_path(f, canonicalise=True) for f in fs.get_selected_paths() ] maybe_songs = [self.__library.get(f) for f in filenames] songs = [s for s in maybe_songs if s] if songs: menu = self.pm.Menu(self.__library, songs) if menu is None: menu = Gtk.Menu() else: menu.prepend(SeparatorMenuItem()) else: menu = Gtk.Menu() b = TrashMenuItem() b.connect('activate', self.__delete, filenames, fs) menu.prepend(b) def selection_done_cb(menu): menu.destroy() menu.connect('selection-done', selection_done_cb) menu.show_all() return view.popup_menu(menu, 0, Gtk.get_current_event_time()) def __delete(self, item, paths, fs): trash_files(self, paths) fs.rescan() def __changed(self, selector, selection, label): model, rows = selection.get_selected_rows() files = [] if len(rows) < 2: count = len(model or []) else: count = len(rows) label.set_text(ngettext("%d song", "%d songs", count) % count) for row in rows: filename = model[row][0] if not os.path.exists(filename): pass elif filename in self.__library: song = self.__library[filename] if song("~#mtime") + 1. < mtime(filename): try: song.reload() except Exception: pass files.append(song) else: files.append(formats.MusicFile(filename)) files = filter(None, files) if len(files) == 0: self.set_title("Ex Falso") elif len(files) == 1: self.set_title("%s - Ex Falso" % files[0].comma("title")) else: self.set_title("%s - Ex Falso" % (ngettext( "%(title)s and %(count)d more", "%(title)s and %(count)d more", len(files) - 1) % ({ 'title': files[0].comma("title"), 'count': len(files) - 1 }))) self.__library.add(files) self.emit('changed', files)
class ExFalsoWindow(Gtk.Window, PersistentWindowMixin): __gsignals__ = { 'changed': (GObject.SignalFlags.RUN_LAST, None, (object, )), 'artwork-changed': (GObject.SignalFlags.RUN_LAST, None, (object, )) } pm = SongsMenuPluginHandler(confirm_action) @classmethod def init_plugins(cls): PluginManager.instance.register_handler(cls.pm) def __init__(self, library, dir=None): super(ExFalsoWindow, self).__init__() 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)) about.connect_object('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(Alignment(bbox, border=6), False, True, 0) vb.show_all() hp.pack1(vb, resize=True, shrink=False) nb = qltk.Notebook() nb.show() for Page in [EditTags, TagsFromPath, RenameFiles, TrackNumbers]: page = Page(self, self.__library) page.show() nb.append_page(page) align = Alignment(nb, top=3) align.show() hp.pack2(align, resize=True, shrink=False) fs.connect('changed', self.__changed, l) if dir: fs.go_to(dir) s = self.__library.connect('changed', lambda *x: fs.rescan()) self.connect_object('destroy', self.__library.disconnect, s) self.__save = None self.connect_object('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 __show_about(self, window): about = AboutExFalso(self) about.run() about.destroy() def set_pending(self, button, *excess): self.__save = button def __pre_selection_changed(self, view, event, fs, nb): if self.__save: resp = qltk.CancelRevertSave(self).run() if resp == Gtk.ResponseType.YES: self.__save.clicked() elif resp == Gtk.ResponseType.NO: fs.rescan() else: nb.grab_focus() return True # cancel or closed def __popup_menu(self, view, fs): # get all songs for the selection filenames = [ normalize_path(f, canonicalise=True) for f in fs.get_selected_paths() ] maybe_songs = [self.__library.get(f) for f in filenames] songs = [s for s in maybe_songs if s] if songs: menu = self.pm.Menu(self.__library, self, songs) if menu is None: menu = Gtk.Menu() else: menu.prepend(SeparatorMenuItem()) else: menu = Gtk.Menu() b = TrashMenuItem() b.connect('activate', self.__delete, filenames, fs) menu.prepend(b) menu.connect_object('selection-done', Gtk.Menu.destroy, menu) menu.show_all() return view.popup_menu(menu, 0, Gtk.get_current_event_time()) def __delete(self, item, paths, fs): trash_files(self, paths) fs.rescan() def __changed(self, selector, selection, label): model, rows = selection.get_selected_rows() files = [] if len(rows) < 2: count = len(model or []) else: count = len(rows) label.set_text(ngettext("%d song", "%d songs", count) % count) for row in rows: filename = util.fsnative(model[row][0]) if not os.path.exists(filename): pass elif filename in self.__library: file = self.__library[filename] if file("~#mtime") + 1. < mtime(filename): try: file.reload() except StandardError: pass files.append(file) else: files.append(formats.MusicFile(filename)) files = filter(None, files) if len(files) == 0: self.set_title("Ex Falso") elif len(files) == 1: self.set_title("%s - Ex Falso" % files[0].comma("title")) else: self.set_title("%s - Ex Falso" % (ngettext( "%(title)s and %(count)d more", "%(title)s and %(count)d more", len(files) - 1) % ({ 'title': files[0].comma("title"), 'count': len(files) - 1 }))) self.__library.add(files) self.emit('changed', files)