Ejemplo n.º 1
0
    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()
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
    def applySettings(self, *args):
        cparser = PuddleConfig(CONFIGPATH)
        fields = self.getItems()
        cparser.set('view_all_fields', 'fields', fields)

        if state:
            show_all_fields()
Ejemplo n.º 5
0
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)
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
    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)
Ejemplo n.º 8
0
    def applySettings(self, *args):
        cparser = PuddleConfig(CONFIGPATH)
        fields = self.getItems()
        cparser.set('view_all_fields', 'fields', fields)

        if state:
            show_all_fields()
Ejemplo n.º 9
0
 def changeProfile(self, index):
     try:
         self.profile = self.profiles[index]
     except IndexError:
         return
     cparser = PuddleConfig()
     cparser.set('masstagging', 'lastindex', index)
Ejemplo n.º 10
0
    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()
Ejemplo n.º 11
0
    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)
Ejemplo n.º 12
0
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)
Ejemplo n.º 13
0
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'')
Ejemplo n.º 14
0
 def saveSettings(self):
     patterns = [
         unicode(self.listbox.item(row).text())
         for row in xrange(self.listbox.count())
     ]
     cparser = PuddleConfig()
     cparser.setSection('editor', 'patterns', patterns)
Ejemplo n.º 15
0
    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))
Ejemplo n.º 16
0
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)]
Ejemplo n.º 17
0
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
Ejemplo n.º 18
0
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
Ejemplo n.º 19
0
 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))]
Ejemplo n.º 20
0
    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)
Ejemplo n.º 21
0
    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()
Ejemplo n.º 22
0
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])
Ejemplo n.º 23
0
 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))]
Ejemplo n.º 24
0
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
Ejemplo n.º 25
0
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
Ejemplo n.º 26
0
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
Ejemplo n.º 27
0
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)
    ]
Ejemplo n.º 28
0
    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()
Ejemplo n.º 29
0
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
    }
Ejemplo n.º 30
0
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])
Ejemplo n.º 31
0
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}
Ejemplo n.º 32
0
 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)
Ejemplo n.º 33
0
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
Ejemplo n.º 34
0
    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)
Ejemplo n.º 35
0
 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)
Ejemplo n.º 36
0
    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)
Ejemplo n.º 37
0
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
Ejemplo n.º 38
0
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
Ejemplo n.º 39
0
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
Ejemplo n.º 40
0
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)
Ejemplo n.º 41
0
    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)
Ejemplo n.º 42
0
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
Ejemplo n.º 43
0
    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)
Ejemplo n.º 44
0
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()
Ejemplo n.º 45
0
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()
Ejemplo n.º 46
0
    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()
Ejemplo n.º 47
0
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
Ejemplo n.º 48
0
    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))
Ejemplo n.º 49
0
    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)
Ejemplo n.º 50
0
    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)
Ejemplo n.º 51
0
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)
Ejemplo n.º 52
0
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()
Ejemplo n.º 53
0
    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))
Ejemplo n.º 54
0
    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)