def closeEvent(self, e): preview_msg = translate('Previews', 'Some files have uncommited previews. ' 'These changes will be lost once you exit puddletag. <br />' 'Do you want to exit without writing those changes?<br />') if tagmodel.has_previews(parent=self, msg=preview_msg): e.ignore() return False controls = PuddleDock._controls for control in PuddleDock._controls.values(): if hasattr(control, 'saveSettings'): try: control.saveSettings(self) except TypeError: control.saveSettings() cparser = PuddleConfig() settings = QSettings(constants.QT_CONFIG, QSettings.IniFormat) if self._lastdir: cparser.set('main', 'lastfolder', unicode(self._lastdir[0], 'utf8')) cparser.set("main", "maximized", self.isMaximized()) settings.setValue('main/state', QVariant(self.saveState())) headstate = self._table.horizontalHeader().saveState() settings.setValue('table/header', QVariant(headstate)) genres.save_genres(status['genres']) e.accept()
def loadsets(): algos = [] if not os.path.exists(DUPEDIR): os.makedirs(DUPEDIR) saveset(**DEFAULTSET) files = [os.path.join(DUPEDIR, z) for z in os.listdir(DUPEDIR)] sets = [] cparser = PuddleConfig() for f in files: cparser.filename = f name = cparser.get('info', 'name', '') disp = cparser.get('info', 'disp', []) algos = [] for section in cparser.sections(): if section == 'info': continue tags = cparser.get(section, 'tags', []) threshold = float(cparser.get(section, 'threshold', '0.85')) func = cparser.get(section, 'func', '') matchcase = cparser.get(section, 'matchcase', True) maintag = cparser.get(section, 'maintag', 'artist') algos.append(Algo(tags, threshold, func, matchcase)) sets.append([name, disp, algos, maintag]) return sets
def parse_shortcuts(): def tr(s): s = s.replace('"', r'\"') return 'translate("Menus", "%s")' % s f = tempfile.NamedTemporaryFile('rb+') fn = f.name loadshortcuts.check_file(fn, ':/shortcuts') cparser = PuddleConfig(fn) action_strings = [] setting = cparser.data for section in cparser.sections(): if section.startswith('shortcut'): values = dict([(str(k), v) for k,v in setting[section].items()]) action_strings.append(tr(values['name'])) if 'tooltip' in values: action_strings.append(tr(values['tooltip'])) f.close() menus = tempfile.NamedTemporaryFile('rb+') fn = menus.name loadshortcuts.check_file(fn, ':/menus') cparser = PuddleConfig(fn) action_strings.extend(map(tr, cparser.data['menu'])) menus.close() return action_strings
def applySettings(self, *args): cparser = PuddleConfig(CONFIGPATH) fields = self.getItems() cparser.set('view_all_fields', 'fields', fields) if state: show_all_fields()
def connect_action_shortcuts(actions): cparser = PuddleConfig() cparser.filename = ls.menu_path for action in actions: shortcut = cparser.get('shortcuts', unicode(action.text()), '') if shortcut: action.setShortcut(shortcut)
def parse_shortcuts(): def tr(s): s = s.replace('"', r'\"') return 'translate("Menus", "%s")' % s f = tempfile.NamedTemporaryFile('rb+') fn = f.name loadshortcuts.check_file(fn, ':/shortcuts') cparser = PuddleConfig(fn) action_strings = [] setting = cparser.data for section in cparser.sections(): if section.startswith('shortcut'): values = dict([(str(k), v) for k, v in setting[section].items()]) action_strings.append(tr(values['name'])) if 'tooltip' in values: action_strings.append(tr(values['tooltip'])) f.close() menus = tempfile.NamedTemporaryFile('rb+') fn = menus.name loadshortcuts.check_file(fn, ':/menus') cparser = PuddleConfig(fn) action_strings.extend(list(map(tr, cparser.data['menu']))) menus.close() return action_strings
def loadSettings(self, filename=None, actions=None): self._names = [] self._hotkeys = [] if filename is None: filename = os.path.join(ACTIONDIR, 'action_shortcuts') self._listbox.clear() cparser = PuddleConfig(filename) if actions is None: self._actions = load_actions() else: self._actions = actions from puddlestuff.puddletag import status if status['actions']: shortcuts = dict( (unicode(a.text()), unicode(a.shortcut().toString())) for a in status['actions']) else: shortcuts = {} for section in sorted(cparser.sections()): if section.startswith('Shortcut'): name = cparser.get(section, NAME, 'Default') self._names.append(name) filenames = cparser.get(section, FILENAMES, []) shortcut = shortcuts.get(name, u'') self.addShortcut(name, filenames, shortcut, select=False) self._hotkeys.append(shortcut)
def applySettings(self, *args): cparser = PuddleConfig(CONFIGPATH) fields = self.getItems() cparser.set('view_all_fields', 'fields', fields) if state: show_all_fields()
def changeProfile(self, index): try: self.profile = self.profiles[index] except IndexError: return cparser = PuddleConfig() cparser.set('masstagging', 'lastindex', index)
def loadSettings(self): settings = QSettings(QT_CONFIG, QSettings.IniFormat) header = self.header() header.restoreState(settings.value('dirview/header').toByteArray()) hide = settings.value('dirview/hide', QVariant(True)).toBool() self.setHeaderHidden(hide) if self.isVisible() == False: return cparser = PuddleConfig() d = cparser.get('main', 'lastfolder', '/') while not os.path.exists(d): d = os.path.dirname(d) if not d: return def expand_thread_func(): index = self.model().index(d) parents = [] while index.isValid(): parents.append(index) index = index.parent() return parents def expandindexes(indexes): self.setEnabled(False) [self.expand(index) for index in indexes] self.setEnabled(True) thread = PuddleThread(expand_thread_func, self) thread.connect(thread, SIGNAL('threadfinished'), expandindexes) thread.start()
def loadSettings(self, filename=None, actions=None): self._names = [] self._hotkeys = [] if filename is None: filename = os.path.join(ACTIONDIR, 'action_shortcuts') self._listbox.clear() cparser = PuddleConfig(filename) if actions is None: self._actions = load_actions() else: self._actions = actions from puddlestuff.puddletag import status if status['actions']: shortcuts = dict((unicode(a.text()), unicode(a.shortcut().toString())) for a in status['actions']) else: shortcuts = {} for section in sorted(cparser.sections()): if section.startswith('Shortcut'): name = cparser.get(section, NAME, 'Default') self._names.append(name) filenames = cparser.get(section, FILENAMES, []) shortcut = shortcuts.get(name, u'') self.addShortcut(name, filenames, shortcut, select=False) self._hotkeys.append(shortcut)
def connect_action_shortcuts(actions): cparser = PuddleConfig() cparser.filename = ls.menu_path for action in actions: shortcut = cparser.get('shortcuts', unicode(action.text()), '') if shortcut: action.setShortcut(shortcut)
def convert_mtp(filename): cparser = PuddleConfig(filename) info_section = 'info' name = cparser.get(info_section, NAME, u'') numsources = cparser.get(info_section, 'numsources', 0) album_bound = cparser.get(info_section, ALBUM_BOUND, 70) / 100.0 track_bound = cparser.get(info_section, TRACK_BOUND, 80) / 100.0 match_fields = cparser.get(info_section, FIELDS, ['artist', 'title']) pattern = cparser.get(info_section, PATTERN, u'%artist% - %album%/%track% - %title%') jfdi = cparser.get(info_section, JFDI, True) desc = cparser.get(info_section, DESC, u'') existing = cparser.get(info_section, EXISTING_ONLY, False) ts_profiles = [] for num in range(numsources): section = 'config%s' % num get = lambda key, default: cparser.get(section, key, default) source = DummyTS() source.name = get('source', u'') fields = fields_from_text(get('fields', u'')) no_result = get('no_match', 0) ts_profiles.append(TagSourceProfile(None, source, fields, no_result)) return MassTagProfile(name, desc, match_fields, None, pattern, ts_profiles, album_bound, track_bound, jfdi, existing, u'')
def saveSettings(self): patterns = [ unicode(self.listbox.item(row).text()) for row in xrange(self.listbox.count()) ] cparser = PuddleConfig() cparser.setSection('editor', 'patterns', patterns)
def _loadSettings(self, actions): cparser = PuddleConfig(os.path.join(CONFIGDIR, 'user_shortcuts')) for action in actions: shortcut = cparser.get('shortcuts', unicode(action.text()), '') if shortcut: action.setShortcut(QKeySequence(shortcut))
def load_patterns(filepath=None): settings = PuddleConfig(filepath) return [settings.get('editor', 'patterns', ['%artist% - $num(%track%,2) - %title%', '%artist% - %album% - $num(%track%,2) - %title%', '%artist% - %title%', '%artist% - %album%', '%artist% - Track %track%', '%artist% - %title%']), settings.get('editor', 'index', 0, True)]
def load_gen_settings(setlist, extras=False): settings = PuddleConfig() settings.filename = os.path.join(settings.savedir, 'gensettings') ret = [] for setting in setlist: desc = setting[0] default = setting[1] ret.append([desc, settings.get(desc, 'value', default)]) return ret
def load_gen_settings(setlist, extras=False): settings = PuddleConfig() settings.filename = os.path.join(settings.savedir, 'gensettings') ret = [] for setting in setlist: desc = setting[0] default = setting[1] ret.append([desc, settings.get(desc, 'value', default)]) return ret
def applyPrefs(self, values): musicdir = values[0] self.musicdir = musicdir cparser = PuddleConfig() cparser.set('exampletagsource', 'musicdir', musicdir) self.preferences[0][2] = musicdir isdir = os.path.isdir join = os.path.join self._dirs = [z for z in os.listdir(musicdir) if isdir(join(musicdir, z))]
def __init__(self, parent=None): QWidget.__init__(self, parent) cparser = PuddleConfig() get_color = lambda key, default: QColor.fromRgb(*cparser.get( 'extendedtags', key, default, True)) add = get_color('add', [0, 255, 0]) edit = get_color('edit', [255, 255, 0]) remove = get_color('remove', [255, 0, 0]) get_color = lambda key, default: QColor.fromRgb(*cparser.get( 'table', key, default, True)) preview = get_color('preview_color', [192, 255, 192]) selection_default = QPalette().color(QPalette.Mid).getRgb()[:-1] selection = get_color('selected_color', selection_default) colors = (add, edit, remove, preview, selection) text = translate( "Colour Settings", '<p>Below are the backgrounds used for various controls in puddletag. <br /> Double click the desired action to change its colour.</p>' ) label = QLabel(text) self.listbox = QTableWidget(0, 1, self) self.listbox.setEditTriggers(QAbstractItemView.NoEditTriggers) header = self.listbox.horizontalHeader() self.listbox.setSortingEnabled(False) header.setVisible(True) header.setStretchLastSection(True) self.listbox.setHorizontalHeaderLabels(['Action']) self.listbox.setRowCount(len(colors)) titles = [ (translate("Colour Settings", 'Row selected in file-view.'), selection), (translate("Colour Settings", 'Row colour for files with previews.'), preview), (translate("Colour Settings", 'Field added in Extended Tags.'), add), (translate("Colour Settings", 'Field edited in Extended Tags.'), edit), (translate("Colour Settings", 'Field removed in Extended Tags.'), remove), ] for i, z in enumerate(titles): self.listbox.setItem(i, 0, StatusWidgetItem(*z)) vbox = QVBoxLayout() vbox.addWidget(label) vbox.addWidget(self.listbox) self.setLayout(vbox) self.connect(self.listbox, SIGNAL('cellDoubleClicked(int,int)'), self.edit)
def editSortOptions(self): cparser = PuddleConfig() options = cparser.get('table', 'sortoptions', ['__filename,track,__dirpath','track, album', '__filename,album,__dirpath']) from puddlestuff.webdb import SortOptionEditor win = SortOptionEditor(options, self) self.connect(win, SIGNAL('options'), self.applySortOptions) win.show()
def savesettings(d, filepath=None): settings = PuddleConfig() if filepath: settings.filename = filepath else: settings.filename = os.path.join(settings.savedir, 'tagpanel') settings.set('panel', 'numrows', unicode(len(d))) for row, rowtags in d.items(): settings.set(unicode(row), 'tags', [z[1] for z in rowtags]) settings.set(unicode(row), 'titles', [z[0] for z in rowtags])
def applyPrefs(self, values): musicdir = values[0] self.musicdir = musicdir cparser = PuddleConfig() cparser.set('exampletagsource', 'musicdir', musicdir) self.preferences[0][2] = musicdir isdir = os.path.isdir join = os.path.join musicdir = musicdir.encode('utf8') self._dirs = [z for z in os.listdir(musicdir) if isdir(join(musicdir,z))]
def _load(filename): cparser = PuddleConfig(filename) confirmations = {} for section in cparser.sections(): if section.startswith(SECTION): name = cparser.get(section, NAME, u'') desc = cparser.get(section, DESC, u'') value = cparser.get(section, VALUE, True) confirmations[name] = [value, desc] return confirmations
def loadsets(): algos = [] if not os.path.exists(DUPEDIR): os.makedirs(DUPEDIR) saveset(**DEFAULTSET) files = [os.path.join(DUPEDIR, z) for z in os.listdir(DUPEDIR)] sets = [] cparser = PuddleConfig() for f in files: cparser.filename = f name = cparser.get('info', 'name', '') disp = cparser.get('info', 'disp', []) algos = [] for section in cparser.sections(): if section == 'info': continue tags = cparser.get(section, 'tags', []) threshold = float(cparser.get(section, 'threshold', '0.85')) func = cparser.get(section, 'func', '') matchcase = cparser.get(section, 'matchcase', True) maintag = cparser.get(section, 'maintag', 'artist') algos.append(Algo(tags, threshold, func, matchcase)) sets.append([name, disp, algos, maintag]) return sets
def create_tool_windows(parent, extra=None): """Creates the dock widgets for the main window (parent) using the modules stored in puddlestuff/mainwin. Returns (the toggleViewActions of the docks, the dockWidgets the mselves).""" actions = [] docks = [] cparser = PuddleConfig() cparser.filename = ls.menu_path widgets = ( mainwin.tagpanel, mainwin.artwork, mainwin.dirview, mainwin.patterncombo, mainwin.filterwin, puddlestuff.webdb, mainwin.storedtags, mainwin.logdialog, puddlestuff.masstag.dialogs, ) controls = [z.control for z in widgets] controls.extend(mainwin.action_dialogs.controls) if extra: controls.extend(extra) for z in controls: name = z[0] try: if not z[2]: PuddleDock._controls[name] = z[1](status=status) continue except IndexError: pass p = PuddleDock(z[0], z[1], parent, status) parent.addDockWidget(z[2], p) try: if z[4]: p.setFloating(True) p.move(parent.rect().center()) except IndexError: pass p.setVisible(z[3]) docks.append(p) action = p.toggleViewAction() action.setText(name) scut = cparser.get("winshortcuts", name, "") if scut: action.setShortcut(scut) actions.append(action) return actions, docks
def load_patterns(filepath=None): settings = PuddleConfig(filepath) return [ settings.get('editor', 'patterns', [ '%artist% - $num(%track%,2) - %title%', '%artist% - %album% - $num(%track%,2) - %title%', '%artist% - %title%', '%artist% - %album%', '%artist% - Track %track%', '%artist% - %title%' ]), settings.get('editor', 'index', 0, True) ]
def editSortOptions(self): cparser = PuddleConfig() options = cparser.get('table', 'sortoptions', [ '__filename,track,__dirpath', 'track, album', '__filename,album,__dirpath' ]) from puddlestuff.webdb import SortOptionEditor win = SortOptionEditor(options, self) self.connect(win, SIGNAL('options'), self.applySortOptions) win.show()
def load_plugins(plugins=None, parent=None): [sys.path.insert(0, d) for d in PLUGIN_DIRS] cparser = PuddleConfig() to_load = cparser.get('plugins', 'to_load', []) functions = {} tagsources = [] dialogs = [] musiclibs = [] modules = [] functions_no_preview = [] join = os.path.join if plugins is None: plugins = [] [plugins.extend(get_plugins(d)) for d in PLUGIN_DIRS] plugins.sort(key=lambda d: d.get(NAME, u'')) for plugin in plugins: if plugin[MODULE_NAME] not in to_load: continue try: module = __import__(plugin[MODULE_NAME]) except: logging.exception(u'Failed to load plugin: ' + plugin['name']) continue if hasattr(module, 'functions'): functions.update(module.functions) if hasattr(module, 'functions_no_preview'): functions_no_preview.extend(module.functions_no_preview) if hasattr(module, 'tagsources'): tagsources.extend(module.tagsources) if hasattr(module, 'dialogs'): dialogs.extend(module.dialogs) if hasattr(module, 'musiclibs'): musiclibs.extend(module.musiclibs) modules.append(module) for d in PLUGIN_DIRS: del (sys.path[0]) return { FUNCTIONS: functions, TAGSOURCE: tagsources, DIALOGS: dialogs, MUSICLIBS: musiclibs, MODULES: modules, FUNCTIONS_NO_PREVIEW: functions_no_preview }
def save(filename=None, confirmations=None): if filename is None: filename = _filename cparser = PuddleConfig(filename) if confirmations is None: confirmations = _confirmations for i, name in enumerate(confirmations): set_value = lambda k,v: cparser.set(SECTION + unicode(i), k, v) set_value(NAME, name) set_value(VALUE, confirmations[name][0]) set_value(DESC, confirmations[name][1])
def load_plugins(plugins=None, parent=None): [sys.path.insert(0, d) for d in PLUGIN_DIRS] cparser = PuddleConfig() to_load = cparser.get('plugins', 'to_load', []) functions = {} tagsources = [] dialogs = [] musiclibs = [] modules = [] functions_no_preview = [] join = os.path.join if plugins is None: plugins = [] [plugins.extend(get_plugins(d)) for d in PLUGIN_DIRS] plugins.sort(key=lambda d: d.get(NAME, u'')) for plugin in plugins: if plugin[MODULE_NAME] not in to_load: continue try: module = __import__(plugin[MODULE_NAME]) except: print u'Failed to load plugin: ', plugin['name'] traceback.print_exc() continue if hasattr(module, 'functions'): functions.update(module.functions) if hasattr(module, 'functions_no_preview'): functions_no_preview.extend(module.functions_no_preview) if hasattr(module, 'tagsources'): tagsources.extend(module.tagsources) if hasattr(module, 'dialogs'): dialogs.extend(module.dialogs) if hasattr(module, 'musiclibs'): musiclibs.extend(module.musiclibs) modules.append(module) for d in PLUGIN_DIRS: del(sys.path[0]) return {FUNCTIONS: functions, TAGSOURCE: tagsources, DIALOGS: dialogs, MUSICLIBS: musiclibs, MODULES: modules, FUNCTIONS_NO_PREVIEW: functions_no_preview}
def updateOrder(self): self.listbox.clear() self.macros = self.loadMacros() cparser = PuddleConfig() to_check = cparser.get('actions', 'checked', []) for i, m in sorted(self.macros.items()): func_name = m.name item = QListWidgetItem(func_name) item.setFlags(item.flags() | Qt.ItemIsEditable) if func_name in to_check: item.setCheckState(Qt.Checked) else: item.setCheckState(Qt.Unchecked) self.listbox.addItem(item)
def create_tool_windows(parent, extra=None): """Creates the dock widgets for the main window (parent) using the modules stored in puddlestuff/mainwin. Returns (the toggleViewActions of the docks, the dockWidgets the mselves).""" actions = [] docks = [] cparser = PuddleConfig() cparser.filename = ls.menu_path widgets = (mainwin.tagpanel, mainwin.artwork, mainwin.dirview, mainwin.patterncombo, mainwin.filterwin, puddlestuff.webdb, mainwin.storedtags, mainwin.logdialog, puddlestuff.masstag.dialogs) controls = [z.control for z in widgets] controls.extend(mainwin.action_dialogs.controls) if extra: controls.extend(extra) for z in controls: name = z[0] try: if not z[2]: PuddleDock._controls[name] = z[1](status=status) continue except IndexError: pass p = PuddleDock(z[0], z[1], parent, status) parent.addDockWidget(z[2], p) try: if z[4]: p.setFloating(True) p.move(parent.rect().center()) except IndexError: pass p.setVisible(z[3]) docks.append(p) action = p.toggleViewAction() action.setText(name) scut = cparser.get('winshortcuts', name, '') if scut: action.setShortcut(scut) actions.append(action) return actions, docks
def __init__(self, parent = None): QWidget.__init__(self, parent) cparser = PuddleConfig() get_color = lambda key, default: QColor.fromRgb( *cparser.get('extendedtags', key, default, True)) add = get_color('add', [0,255,0]) edit = get_color('edit', [255,255,0]) remove = get_color('remove', [255,0,0]) get_color = lambda key, default: QColor.fromRgb( *cparser.get('table', key, default, True)) preview = get_color('preview_color', [192, 255, 192]) selection_default = QPalette().color(QPalette.Mid).getRgb()[:-1] selection = get_color('selected_color', selection_default) colors = (add, edit, remove, preview, selection) text = translate("Colour Settings", '<p>Below are the backgrounds used for various controls in puddletag. <br /> Double click the desired action to change its colour.</p>') label = QLabel(text) self.listbox = QTableWidget(0, 1, self) self.listbox.setEditTriggers(QAbstractItemView.NoEditTriggers) header = self.listbox.horizontalHeader() self.listbox.setSortingEnabled(False) header.setVisible(True) header.setStretchLastSection (True) self.listbox.setHorizontalHeaderLabels(['Action']) self.listbox.setRowCount(len(colors)) titles = [ (translate("Colour Settings", 'Row selected in file-view.'), selection), (translate("Colour Settings", 'Row colour for files with previews.'), preview), (translate("Colour Settings", 'Field added in Extended Tags.'), add), (translate("Colour Settings", 'Field edited in Extended Tags.'), edit), (translate("Colour Settings", 'Field removed in Extended Tags.'), remove),] for i, z in enumerate(titles): self.listbox.setItem(i, 0, StatusWidgetItem(*z)) vbox = QVBoxLayout() vbox.addWidget(label) vbox.addWidget(self.listbox) self.setLayout(vbox) self.connect(self.listbox, SIGNAL('cellDoubleClicked(int,int)'), self.edit)
def loadSettings(self): convert_mtps(PROFILEDIR) if not os.path.exists(PROFILEDIR): os.mkdir(PROFILEDIR) self.setProfiles(load_all_mtps(PROFILEDIR, self.tag_sources)) index = PuddleConfig().get('masstagging', 'lastindex', 0) if index < self.profileCombo.count(): self.profileCombo.setCurrentIndex(index)
def savePlayList(self): tags = status['selectedfiles'] if not tags: tags = status['alltags'] settings = PuddleConfig() try: dirname = self._lastdir[0] except IndexError: dirname = constants.HOMEDIR filepattern = settings.get('playlist', 'filepattern', 'puddletag.m3u') default = encode_fn(findfunc.tagtofilename(filepattern, tags[0])) f = unicode( QFileDialog.getSaveFileName( self, translate("Playlist", 'Save Playlist...'), os.path.join(dirname, default))) if f: if settings.get('playlist', 'extinfo', 1, True): pattern = settings.get('playlist', 'extpattern', '%artist% - %title%') else: pattern = None reldir = settings.get('playlist', 'reldir', 0, True) windows_separator = settings.get('playlist', 'windows_separator', 0, False) m3u.exportm3u(tags, f, pattern, reldir, windows_separator)
def load_settings(filename=None, actions=None): if filename is None: filename = FILENAME if not os.path.exists(os.path.dirname(filename)): os.makedirs(os.path.dirname(filename)) cparser = PuddleConfig(filename) actions = load_actions() if actions is None else actions shortcuts = [] for section in sorted(cparser.sections()): if section.startswith(SHORTCUT_SECTION): name = cparser.get(section, NAME, 'Default') filenames = cparser.get(section, FILENAMES, []) shortcuts.append([name, filenames]) return actions, shortcuts
def load_settings(filename=None, actions=None): if filename is None: filename = FILENAME if not os.path.exists(os.path.dirname(filename)): os.makedirs(os.path.dirname(filename)) cparser = PuddleConfig(filename) actions = load_actions() if actions is None else actions shortcuts = [] for section in sorted(cparser.sections()): if section.startswith(SHORTCUT_SECTION): name = cparser.get(section, NAME, 'Default') filenames = cparser.get(section, FILENAMES, []) shortcuts.append([name, filenames]) return actions, shortcuts
def create_actions(parent): enable_preview = QAction('Enabl&e Preview Mode', parent) enable_preview.setShortcut('Ctrl+Shift+P') obj.connect(enable_preview, SIGNAL('triggered()'), toggle_preview_mode) clear_selection = PreviewAction('Clear Selected &Files', parent) clear_selection.setShortcut('Ctrl+Shift+F') obj.connect(clear_selection, SIGNAL('triggered()'), clear_selected) write = PreviewAction('&Write Previews', parent) write.setShortcut('Ctrl+W') obj.connect(write, SIGNAL('triggered()'), lambda: emit('writepreview')) revert = PreviewAction('&Undo Last Clear', parent) revert.setShortcut('Ctrl+Shift+Z') obj.connect(revert, SIGNAL('triggered()'), undo_last) sort = QAction('Sort &By', parent) obj.connect(sort, SIGNAL('triggered()'), sort_by_fields) clear_cells = PreviewAction('Clear Selected &Cells', parent) obj.connect(clear_cells, SIGNAL('triggered()'), clear_selected_cells) cparser = PuddleConfig() options = cparser.get('table', 'sortoptions', [ '__filename,track,__dirpath', 'track, album', '__filename,album,__dirpath' ]) global _sort_action _sort_action = sort sort_actions = set_sort_options(options) preview_actions = [clear_selection, write, revert, clear_cells] toggle = partial(toggle_preview_display, enable_preview, preview_actions) obj.receives.append(['previewModeChanged', toggle]) [connect_shortcut(z, FILESSELECTED) for z in preview_actions] return [enable_preview, clear_selection, write, revert, sort, clear_cells ] + sort_actions
def saveset(setname, disp, algs, maintag): cparser = PuddleConfig() filename = os.path.join(DUPEDIR, setname) open(filename, 'w').close() #I have to clear the file because if a previous #set had more algos then the extra algos will get loaded. cparser.filename = filename algs = [{'tags': a.tags, 'threshold': a.threshold, 'func': a.func.__name__, 'matchcase': a.matchcase, 'maintag': maintag} for a in algs] cparser.set('info', 'name', setname) cparser.set('info', 'disp', disp) for i, a in enumerate(algs): setname = u'alg' + unicode(i) for key, val in a.items(): cparser.set(setname, key, val)
def __init__(self, controls, parent=None): QWidget.__init__(self, parent) settings = [] for control in controls: if hasattr(control, 'gensettings'): settings.extend(load_gen_settings(control.gensettings, True)) self._controls = [] def create_control(desc, val): if isinstance(val, bool): return SettingsCheckBox(val, desc) elif isinstance(val, basestring): return SettingsLineEdit(desc, val) vbox = QVBoxLayout() for desc, val in settings: widget = create_control(desc, val) vbox.addWidget(widget) self._controls.append(widget) edit_sort_options = QPushButton( translate("GenSettings", '&Edit sort options')) self._lang_combo = QComboBox() self._lang_combo.addItems([ translate('GenSettings', '<Autodetect>'), translate('GenSettings', 'Default') ]) self._lang_combo.setCurrentIndex(0) lang = PuddleConfig().get('main', 'lang', u'auto') self._lang_combo.addItems(list(get_languages([TRANSDIR]))) if lang != u'auto': i = self._lang_combo.findText(lang, Qt.MatchFixedString) if i > 0: self._lang_combo.setCurrentIndex(i) self.connect(edit_sort_options, SIGNAL('clicked()'), self.editSortOptions) hbox = QHBoxLayout() hbox.addWidget(edit_sort_options) hbox.addStretch() vbox.addLayout(hbox) if self._lang_combo.count() > 2: vbox.addLayout( create_buddy( translate('GenSettings', 'Language (Requires a restart)'), self._lang_combo)) else: self._lang_combo.setCurrentIndex(0) vbox.addStretch() self.setLayout(vbox)
def create_actions(parent): enable_preview = QAction('Enabl&e Preview Mode', parent) enable_preview.setShortcut('Ctrl+Shift+P') obj.connect(enable_preview, SIGNAL('triggered()'), toggle_preview_mode) clear_selection = PreviewAction('Clear Selected &Files', parent) clear_selection.setShortcut('Ctrl+Shift+F') obj.connect(clear_selection, SIGNAL('triggered()'), clear_selected) write = PreviewAction('&Write Previews', parent) write.setShortcut('Ctrl+W') obj.connect(write, SIGNAL('triggered()'), lambda: emit('writepreview')) revert = PreviewAction('&Undo Last Clear', parent) revert.setShortcut('Ctrl+Shift+Z') obj.connect(revert, SIGNAL('triggered()'), undo_last) sort = QAction('Sort &By', parent) obj.connect(sort, SIGNAL('triggered()'), sort_by_fields) clear_cells = PreviewAction('Clear Selected &Cells', parent) obj.connect(clear_cells, SIGNAL('triggered()'), clear_selected_cells) cparser = PuddleConfig() options = cparser.get('table', 'sortoptions', ['__filename,track,__dirpath','track, album', '__filename,album,__dirpath']) global _sort_action _sort_action = sort sort_actions = set_sort_options(options) preview_actions = [clear_selection, write, revert, clear_cells] toggle = partial(toggle_preview_display, enable_preview, preview_actions) obj.receives.append(['previewModeChanged', toggle]) [connect_shortcut(z, FILESSELECTED) for z in preview_actions] return [enable_preview, clear_selection, write, revert, sort, clear_cells] + sort_actions
def applySettings(self, control = None): from puddlestuff.puddletag import remove_shortcuts, add_shortcuts remove_shortcuts('&Actions', self._names) f = open(FILENAME, 'w') f.close() cparser = PuddleConfig(FILENAME) for i, item in enumerate(self._listbox.items()): section = SHORTCUT_SECTION + unicode(i) cparser.set(section, NAME, item.actionName) cparser.set(section, FILENAMES, item.filenames) from puddlestuff.mainwin.funcs import applyaction shortcuts = create_action_shortcuts(applyaction, control) for item, shortcut in zip(self._listbox.items(), shortcuts): if item.shortcut: shortcut.setShortcut(item.shortcut) add_shortcuts('&Actions', shortcuts, save=True)
def clipboard_to_tag(parent=None): win = helperwin.ImportTextFile(parent, clipboard=True) win.setModal(True) win.patterncombo.addItems(status['patterns']) cparser = PuddleConfig() last_dir = cparser.get('importwindow', 'lastdir', HOMEDIR) win.lastDir = last_dir last_pattern = cparser.get('importwindow', 'lastpattern', u'') if last_pattern: win.patterncombo.setEditText(last_pattern) def fin_edit(taglist, pattern): cparser.set('importwindow', 'lastdir', win.lastDir) cparser.set('importwindow', 'lastpattern', pattern) emit('writeselected', taglist) win.connect(win, SIGNAL("Newtags"), fin_edit) win.show()
def clipboard_to_tag(parent=None): win = helperwin.ImportTextFile(parent, clipboard = True) win.setModal(True) win.patterncombo.addItems(status['patterns']) cparser = PuddleConfig() last_dir = cparser.get('importwindow', 'lastdir', HOMEDIR) win.lastDir = last_dir last_pattern = cparser.get('importwindow', 'lastpattern', u'') if last_pattern: win.patterncombo.setEditText(last_pattern) def fin_edit(taglist, pattern): cparser.set('importwindow', 'lastdir', win.lastDir) cparser.set('importwindow', 'lastpattern', pattern) emit('writeselected', taglist) win.connect(win, SIGNAL("Newtags"), fin_edit) win.show()
def closeEvent(self, e): preview_msg = translate( 'Previews', 'Some files have uncommited previews. ' 'These changes will be lost once you exit puddletag. <br />' 'Do you want to exit without writing those changes?<br />') if tagmodel.has_previews(parent=self, msg=preview_msg): e.ignore() return False controls = PuddleDock._controls for control in PuddleDock._controls.values(): if hasattr(control, 'saveSettings'): try: control.saveSettings(self) except TypeError: control.saveSettings() cparser = PuddleConfig() settings = QSettings(constants.QT_CONFIG, QSettings.IniFormat) if self._lastdir: cparser.set('main', 'lastfolder', unicode(self._lastdir[0], 'utf8')) cparser.set("main", "maximized", self.isMaximized()) settings.setValue('main/state', QVariant(self.saveState())) headstate = self._table.horizontalHeader().saveState() settings.setValue('table/header', QVariant(headstate)) genres.save_genres(status['genres']) e.accept()
def mtp_from_file(filename=CONFIG, tag_sources=None): if tag_sources is None: tag_sources = {} else: tag_sources = dict((z.name, z) for z in tag_sources) cparser = PuddleConfig(filename) info_section = 'info' name = cparser.get(info_section, NAME, '') numsources = cparser.get(info_section, 'numsources', 0) album_bound = cparser.get(info_section, ALBUM_BOUND, 70) / 100.0 track_bound = cparser.get(info_section, TRACK_BOUND, 80) / 100.0 match_fields = cparser.get(info_section, FIELDS, ['artist', 'title']) pattern = cparser.get(info_section, PATTERN, '%artist% - %album%/%track% - %title%') jfdi = cparser.get(info_section, JFDI, True) desc = cparser.get(info_section, DESC, u'') leave_existing = cparser.get(info_section, EXISTING_ONLY, False) regexps = u'' ts_profiles = [] for num in range(numsources): section = 'config%s' % num get = lambda key, default: cparser.get(section, key, default) source = tag_sources.get(get('source', u''), None) no_result = get('no_match', 0) fields = fields_from_text(get('fields', u'')) replace_fields = fields_from_text(get('replace_fields', u'')) ts_profiles.append(TagSourceProfile(None, source, fields, no_result, replace_fields)) mtp = MassTagProfile(name, desc, match_fields, None, pattern, ts_profiles, album_bound, track_bound, jfdi, leave_existing, regexps) return mtp
def __init__(self, parent=None): super(PluginConfig, self).__init__(parent) winsettings('pluginconfig', self) self._listbox = QListWidget() info_display = InfoWidget() hbox = QHBoxLayout() hbox.addWidget(self._listbox, 0) hbox.addWidget(info_display, 1) vbox = QVBoxLayout() vbox.addLayout(hbox) vbox.addWidget( QLabel( translate( "Plugin Settings", '<b>Loading/unloading plugins requires a restart.</b>'))) self.setLayout(vbox) plugins = [] [plugins.extend(get_plugins(d)) for d in PLUGIN_DIRS] cparser = PuddleConfig() to_load = cparser.get('plugins', 'to_load', []) plugins.sort(key=lambda d: d.get(NAME, u'')) for plugin in plugins: item = QListWidgetItem() item.setText(plugin[NAME]) if plugin[MODULE_NAME] in to_load: item.setCheckState(Qt.Checked) else: item.setCheckState(Qt.Unchecked) item.plugin = plugin self._listbox.addItem(item) self.connect( self._listbox, SIGNAL('currentItemChanged(QListWidgetItem*, QListWidgetItem *)'), lambda item, previous: info_display.changeInfo(item.plugin))
def __init__(self, parent=None): QWidget.__init__(self, parent) def inttocheck(value): if value: return Qt.Checked return Qt.Unchecked cparser = PuddleConfig() self.extpattern = QLineEdit() self.extpattern.setText( cparser.load('playlist', 'extpattern', '%artist% - %title%')) self.extinfo = QCheckBox( translate("Playlist Settings", '&Write extended info'), self) self.connect(self.extinfo, SIGNAL('stateChanged(int)'), self.extpattern.setEnabled) self.extinfo.setCheckState( inttocheck(cparser.load('playlist', 'extinfo', 1, True))) self.extpattern.setEnabled(self.extinfo.checkState()) self.reldir = QCheckBox( translate("Playlist Settings", 'Entries &relative to working directory')) self.reldir.setCheckState( inttocheck(cparser.load('playlist', 'reldir', 0, True))) self.windows_separator = QCheckBox( translate("Playlist Settings", 'Use windows path separator (\\)')) self.windows_separator.setCheckState( inttocheck(cparser.load('playlist', 'windows_separator', 0, True))) self.filename = QLineEdit() self.filename.setText( cparser.load('playlist', 'filepattern', 'puddletag.m3u')) label = QLabel(translate("Playlist Settings", '&Filename pattern.')) label.setBuddy(self.filename) hbox = QHBoxLayout() hbox.addSpacing(10) hbox.addWidget(self.extpattern) vbox = QVBoxLayout() [ vbox.addWidget(z) for z in (self.extinfo, self.reldir, self.windows_separator, label, self.filename) ] vbox.insertLayout(1, hbox) vbox.addStretch() vbox.insertSpacing(3, 5) vbox.insertSpacing(5, 5) self.setLayout(vbox)
def __init__(self, parent=None): filename = os.path.join(PuddleConfig().savedir, 'mappings') self._edited = deepcopy(audioinfo.mapping) self._mappings = audioinfo.mapping QWidget.__init__(self, parent) tooltip = translate( "Mapping Settings", '''<ul><li>Tag is the format that the mapping applies to. One of <b>ID3, APEv2, MP4, or VorbisComment</b>. </li><li>Fields will be mapped from Source to Target, meaning that if Source is found in a tag, it'll be editable in puddletag using Target.</li> <li>Eg. For <b>Tag=VorbisComment, Source=organization, and Target=publisher</b> means that writing to the publisher field for VorbisComments in puddletag will in actuality write to the organization field.</li><li>Mappings for tag sources are also supported, just use the name of the tag source as Tag, eg. <b>Tag=MusicBrainz, Source=artist,Target=performer</b>.</li></ul>''') self._table = QTableWidget() self._table.setToolTip(tooltip) self._table.setColumnCount(3) self._table.setHorizontalHeaderLabels([ translate("Mapping Settings", 'Tag'), translate("Mapping Settings", 'Original Field'), translate("Mapping Settings", 'Target') ]) header = self._table.horizontalHeader() header.setVisible(True) self._table.verticalHeader().setVisible(False) header.setStretchLastSection(True) buttons = ListButtons() buttons.connectToWidget(self) buttons.moveup.setVisible(False) buttons.movedown.setVisible(False) self.connect(buttons, SIGNAL('duplicate'), self.duplicate) hbox = QHBoxLayout() hbox.addWidget(self._table, 1) hbox.addLayout(buttons, 0) self._setMappings(self._mappings) label = QLabel( translate("Mapping Settings", '<b>A restart is required to apply these settings.</b>')) vbox = QVBoxLayout() vbox.addLayout(hbox, 1) vbox.addWidget(label) self.setLayout(vbox)
def saveset(setname, disp, algs, maintag): cparser = PuddleConfig() filename = os.path.join(DUPEDIR, setname) open(filename, 'w').close() #I have to clear the file because if a previous #set had more algos then the extra algos will get loaded. cparser.filename = filename algs = [{'tags': a.tags, 'threshold': a.threshold, 'func': a.func.__name__, 'matchcase': a.matchcase, 'maintag': maintag} for a in algs] cparser.set('info', 'name', setname) cparser.set('info', 'disp', disp) for i, a in enumerate(algs): setname = u'alg' + unicode(i) for key, val in a.items(): cparser.set(setname, key, val)
def text_file_to_tag(parent=None): dirpath = status['selectedfiles'][0].dirpath win = helperwin.ImportTextFile(parent) cparser = PuddleConfig() last_dir = cparser.get('importwindow', 'lastdir', HOMEDIR) if win.openFile(dirpath=last_dir): win.close() return win.setModal(True) win.patterncombo.addItems(status['patterns']) last_pattern = cparser.get('importwindow', 'lastpattern', u'') if last_pattern: win.patterncombo.setEditText(last_pattern) def fin_edit(taglist, pattern): cparser.set('importwindow', 'lastdir', win.lastDir) cparser.set('importwindow', 'lastpattern', pattern) emit('writeselected', taglist) win.connect(win, SIGNAL("Newtags"), fin_edit) win.show()
def __init__(self, parent = None): super(PluginConfig, self).__init__(parent) winsettings('pluginconfig', self) self._listbox = QListWidget() info_display = InfoWidget() hbox = QHBoxLayout() hbox.addWidget(self._listbox, 0) hbox.addWidget(info_display, 1) vbox = QVBoxLayout() vbox.addLayout(hbox) vbox.addWidget( QLabel(translate("Plugin Settings", '<b>Loading/unloading plugins requires a restart.</b>'))) self.setLayout(vbox) plugins = [] [plugins.extend(get_plugins(d)) for d in PLUGIN_DIRS] cparser = PuddleConfig() to_load = cparser.get('plugins', 'to_load', []) plugins.sort(key=lambda d: d.get(NAME, u'')) for plugin in plugins: item = QListWidgetItem() item.setText(plugin[NAME]) if plugin[MODULE_NAME] in to_load: item.setCheckState(Qt.Checked) else: item.setCheckState(Qt.Unchecked) item.plugin = plugin self._listbox.addItem(item) self.connect(self._listbox, SIGNAL('currentItemChanged(QListWidgetItem*, QListWidgetItem *)'), lambda item, previous: info_display.changeInfo(item.plugin))
def applySettings(self, controls): cparser = PuddleConfig() index = self._lang_combo.currentIndex() if index > 1: cparser.set('main', 'lang', unicode(self._lang_combo.currentText())) elif index == 0: cparser.set('main', 'lang', u'auto') elif index == 1: cparser.set('main', 'lang', u'default') vals = dict([c.settingValue for c in self._controls]) for c in controls: if hasattr(c, 'applyGenSettings'): c.applyGenSettings(vals) save_gen_settings(vals)