예제 #1
0
    def __init__(self, status, parent = None):
        QWidget.__init__(self, parent)
        self.settingsdialog = SettingsDialog

        connect = lambda obj, sig, slot: self.connect(obj, SIGNAL(sig), slot)

        self.setWindowTitle("Tag Sources")

        self.receives = []
        self.emits = ['writepreview', 'setpreview', 'clearpreview',
            'enable_preview_mode', 'logappend', 'disable_preview_mode']

        self.fieldMapping = audioinfo.mapping

        self._status = status
        self.__sources = [z() for z in tagsources]
        self.__sources.extend(load_mp3tag_sources())

        for ts in self.__sources:
            if hasattr(ts, 'preferences') and not isinstance(ts, QWidget):
                try:
                    ts.applyPrefs(load_source_prefs(ts.name, ts.preferences))
                except:
                    continue

        status['initialized_tagsources'] = self.__sources

        self.curSource = self.__sources[0]
        self.__sourceFields = [[] for z in self.__sources]

        self.sourcelist = QComboBox()
        self.sourcelist.addItems([ts.name for ts in self.__sources])
        connect(self.sourcelist, 'currentIndexChanged (int)', self.changeSource)

        sourcelabel = QLabel(translate("WebDB", 'Sour&ce: '))
        sourcelabel.setBuddy(self.sourcelist)

        preferences = QToolButton()
        preferences.setIcon(QIcon(':/preferences.png'))
        preferences.setToolTip(translate("WebDB", 'Configure'))
        self.__preferencesButton = preferences
        connect(preferences, 'clicked()', self.configure)

        self.searchEdit = QLineEdit()
        self.searchEdit.setToolTip(DEFAULT_SEARCH_TIP)
        connect(self.searchEdit, 'returnPressed()', self.search)

        self.searchButton = QPushButton(translate("WebDB", "&Search"))
        self.searchButton.setDefault(True)
        self.searchButton.setAutoDefault(True)
        connect(self.searchButton, "clicked()", self.search)

        self.submitButton = QPushButton(translate("WebDB",
            "S&ubmit Tags"))
        connect(self.submitButton, "clicked()", self.submit)

        write_preview = QPushButton(translate("WebDB", '&Write'))
        connect(write_preview, "clicked()", self.writePreview)
        
        clear = QPushButton(translate("Previews", "Clea&r preview"))
        connect(clear, "clicked()",
            lambda: self.emit(SIGNAL('disable_preview_mode')))

        self.label = QLabel(translate("WebDB",
            "Select files and click on Search to retrieve metadata."))
        connect(status_obj, 'statusChanged', self.label.setText)

        self.listbox = ReleaseWidget(status, self.curSource)
        self.__updateEmpty = QCheckBox(translate("WebDB",
            'Update empty fields only.'))
        connect(self.listbox, 'statusChanged', self.label.setText)
        connect(self.listbox, 'preview', self.emit_preview)
        connect(self.listbox, 'exactMatches', self.emitExact)

        self.__autoRetrieve = QCheckBox(translate("WebDB",
            'Automatically retrieve matches.'))

        self.__fieldsEdit = FieldsEdit()
        self.__fieldsEdit.setToolTip(FIELDLIST_TIP)
        connect(self.__fieldsEdit, 'fieldsChanged', self.__changeFields)

        infolabel = QLabel()
        infolabel.setOpenExternalLinks(True)
        connect(self.listbox, 'infoChanged', infolabel.setText)

        connect(status_obj, 'logappend', SIGNAL('logappend'))

        sourcebox = QHBoxLayout()
        sourcebox.addWidget(sourcelabel)
        sourcebox.addWidget(self.sourcelist, 1)
        sourcebox.addWidget(preferences)

        hbox = QHBoxLayout()
        hbox.addWidget(self.searchButton, 0)
        hbox.addWidget(self.searchEdit, 1)

        vbox = QVBoxLayout()
        vbox.addLayout(sourcebox)
        vbox.addLayout(hbox)

        vbox.addWidget(self.label)
        vbox.addWidget(self.listbox, 1)
        hbox = QHBoxLayout()
        hbox.addWidget(infolabel, 1)
        hbox.addStretch()
        hbox.addWidget(self.submitButton)
        hbox.addWidget(write_preview)
        hbox.addWidget(clear)
        vbox.addLayout(hbox)

        vbox.addWidget(self.__fieldsEdit)
        vbox.addWidget(self.__updateEmpty)
        vbox.addWidget(self.__autoRetrieve)
        self.setLayout(vbox)
        self.changeSource(0)
예제 #2
0
파일: webdb.py 프로젝트: korala1968/tago
    def __init__(self, status, parent=None):
        QWidget.__init__(self, parent)
        self.settingsdialog = SettingsDialog

        connect = lambda obj, sig, slot: self.connect(obj, SIGNAL(sig), slot)

        self.setWindowTitle("Tag Sources")

        self.receives = []
        self.emits = [
            'writepreview', 'setpreview', 'clearpreview',
            'enable_preview_mode', 'logappend', 'disable_preview_mode'
        ]

        self.fieldMapping = audioinfo.mapping

        self._status = status
        self.__sources = [z() for z in tagsources]
        self.__sources.extend(load_mp3tag_sources())

        for ts in self.__sources:
            if hasattr(ts, 'preferences') and not isinstance(ts, QWidget):
                try:
                    ts.applyPrefs(load_source_prefs(ts.name, ts.preferences))
                except:
                    continue

        status['initialized_tagsources'] = self.__sources

        self.curSource = self.__sources[0]
        self.__sourceFields = [[] for z in self.__sources]

        self.sourcelist = QComboBox()
        self.sourcelist.addItems([ts.name for ts in self.__sources])
        connect(self.sourcelist, 'currentIndexChanged (int)',
                self.changeSource)

        sourcelabel = QLabel(translate("WebDB", 'Sour&ce: '))
        sourcelabel.setBuddy(self.sourcelist)

        preferences = QToolButton()
        preferences.setIcon(QIcon(':/preferences.png'))
        preferences.setToolTip(translate("WebDB", 'Configure'))
        self.__preferencesButton = preferences
        connect(preferences, 'clicked()', self.configure)

        self.searchEdit = QLineEdit()
        self.searchEdit.setToolTip(DEFAULT_SEARCH_TIP)
        connect(self.searchEdit, 'returnPressed()', self.search)

        self.searchButton = QPushButton(translate("WebDB", "&Search"))
        self.searchButton.setDefault(True)
        self.searchButton.setAutoDefault(True)
        connect(self.searchButton, "clicked()", self.search)

        self.submitButton = QPushButton(translate("WebDB", "S&ubmit Tags"))
        connect(self.submitButton, "clicked()", self.submit)

        write_preview = QPushButton(translate("WebDB", '&Write'))
        connect(write_preview, "clicked()", self.writePreview)

        clear = QPushButton(translate("Previews", "Clea&r preview"))
        connect(clear, "clicked()",
                lambda: self.emit(SIGNAL('disable_preview_mode')))

        self.label = QLabel(
            translate(
                "WebDB",
                "Select files and click on Search to retrieve metadata."))
        connect(status_obj, 'statusChanged', self.label.setText)

        self.listbox = ReleaseWidget(status, self.curSource)
        self.__updateEmpty = QCheckBox(
            translate("WebDB", 'Update empty fields only.'))
        connect(self.listbox, 'statusChanged', self.label.setText)
        connect(self.listbox, 'preview', self.emit_preview)
        connect(self.listbox, 'exactMatches', self.emitExact)

        self.__autoRetrieve = QCheckBox(
            translate("WebDB", 'Automatically retrieve matches.'))

        self.__fieldsEdit = FieldsEdit()
        self.__fieldsEdit.setToolTip(FIELDLIST_TIP)
        connect(self.__fieldsEdit, 'fieldsChanged', self.__changeFields)

        infolabel = QLabel()
        infolabel.setOpenExternalLinks(True)
        connect(self.listbox, 'infoChanged', infolabel.setText)

        connect(status_obj, 'logappend', SIGNAL('logappend'))

        sourcebox = QHBoxLayout()
        sourcebox.addWidget(sourcelabel)
        sourcebox.addWidget(self.sourcelist, 1)
        sourcebox.addWidget(preferences)

        hbox = QHBoxLayout()
        hbox.addWidget(self.searchButton, 0)
        hbox.addWidget(self.searchEdit, 1)

        vbox = QVBoxLayout()
        vbox.addLayout(sourcebox)
        vbox.addLayout(hbox)

        vbox.addWidget(self.label)
        vbox.addWidget(self.listbox, 1)
        hbox = QHBoxLayout()
        hbox.addWidget(infolabel, 1)
        hbox.addStretch()
        hbox.addWidget(self.submitButton)
        hbox.addWidget(write_preview)
        hbox.addWidget(clear)
        vbox.addLayout(hbox)

        vbox.addWidget(self.__fieldsEdit)
        vbox.addWidget(self.__updateEmpty)
        vbox.addWidget(self.__autoRetrieve)
        self.setLayout(vbox)
        self.changeSource(0)
예제 #3
0
class MainWin(QWidget):
    def __init__(self, status, parent = None):
        QWidget.__init__(self, parent)
        self.settingsdialog = SettingsDialog

        connect = lambda obj, sig, slot: self.connect(obj, SIGNAL(sig), slot)

        self.setWindowTitle("Tag Sources")

        self.receives = []
        self.emits = ['writepreview', 'setpreview', 'clearpreview',
            'enable_preview_mode', 'logappend', 'disable_preview_mode']

        self.fieldMapping = audioinfo.mapping

        self._status = status
        self.__sources = [z() for z in tagsources]
        self.__sources.extend(load_mp3tag_sources())

        for ts in self.__sources:
            if hasattr(ts, 'preferences') and not isinstance(ts, QWidget):
                try:
                    ts.applyPrefs(load_source_prefs(ts.name, ts.preferences))
                except:
                    continue

        status['initialized_tagsources'] = self.__sources

        self.curSource = self.__sources[0]
        self.__sourceFields = [[] for z in self.__sources]

        self.sourcelist = QComboBox()
        self.sourcelist.addItems([ts.name for ts in self.__sources])
        connect(self.sourcelist, 'currentIndexChanged (int)', self.changeSource)

        sourcelabel = QLabel(translate("WebDB", 'Sour&ce: '))
        sourcelabel.setBuddy(self.sourcelist)

        preferences = QToolButton()
        preferences.setIcon(QIcon(':/preferences.png'))
        preferences.setToolTip(translate("WebDB", 'Configure'))
        self.__preferencesButton = preferences
        connect(preferences, 'clicked()', self.configure)

        self.searchEdit = QLineEdit()
        self.searchEdit.setToolTip(DEFAULT_SEARCH_TIP)
        connect(self.searchEdit, 'returnPressed()', self.search)

        self.searchButton = QPushButton(translate("WebDB", "&Search"))
        self.searchButton.setDefault(True)
        self.searchButton.setAutoDefault(True)
        connect(self.searchButton, "clicked()", self.search)

        self.submitButton = QPushButton(translate("WebDB",
            "S&ubmit Tags"))
        connect(self.submitButton, "clicked()", self.submit)

        write_preview = QPushButton(translate("WebDB", '&Write'))
        connect(write_preview, "clicked()", self.writePreview)
        
        clear = QPushButton(translate("Previews", "Clea&r preview"))
        connect(clear, "clicked()",
            lambda: self.emit(SIGNAL('disable_preview_mode')))

        self.label = QLabel(translate("WebDB",
            "Select files and click on Search to retrieve metadata."))
        connect(status_obj, 'statusChanged', self.label.setText)

        self.listbox = ReleaseWidget(status, self.curSource)
        self.__updateEmpty = QCheckBox(translate("WebDB",
            'Update empty fields only.'))
        connect(self.listbox, 'statusChanged', self.label.setText)
        connect(self.listbox, 'preview', self.emit_preview)
        connect(self.listbox, 'exactMatches', self.emitExact)

        self.__autoRetrieve = QCheckBox(translate("WebDB",
            'Automatically retrieve matches.'))

        self.__fieldsEdit = FieldsEdit()
        self.__fieldsEdit.setToolTip(FIELDLIST_TIP)
        connect(self.__fieldsEdit, 'fieldsChanged', self.__changeFields)

        infolabel = QLabel()
        infolabel.setOpenExternalLinks(True)
        connect(self.listbox, 'infoChanged', infolabel.setText)

        connect(status_obj, 'logappend', SIGNAL('logappend'))

        sourcebox = QHBoxLayout()
        sourcebox.addWidget(sourcelabel)
        sourcebox.addWidget(self.sourcelist, 1)
        sourcebox.addWidget(preferences)

        hbox = QHBoxLayout()
        hbox.addWidget(self.searchButton, 0)
        hbox.addWidget(self.searchEdit, 1)

        vbox = QVBoxLayout()
        vbox.addLayout(sourcebox)
        vbox.addLayout(hbox)

        vbox.addWidget(self.label)
        vbox.addWidget(self.listbox, 1)
        hbox = QHBoxLayout()
        hbox.addWidget(infolabel, 1)
        hbox.addStretch()
        hbox.addWidget(self.submitButton)
        hbox.addWidget(write_preview)
        hbox.addWidget(clear)
        vbox.addLayout(hbox)

        vbox.addWidget(self.__fieldsEdit)
        vbox.addWidget(self.__updateEmpty)
        vbox.addWidget(self.__autoRetrieve)
        self.setLayout(vbox)
        self.changeSource(0)
        
    def _applyPrefs(self, prefs):
        self.curSource.applyPrefs(prefs)
        cparser = PuddleConfig(TAGSOURCE_CONFIG)
        name = self.curSource.name
        for section, value in zip(self.curSource.preferences, prefs):
            cparser.set(name, section[0], value)

    def __changeFields(self, fields):
        self.listbox.tagsToWrite = fields
        self.__sourceFields[self.sourcelist.currentIndex()] = fields

    def changeSource(self, index):
        self.curSource = self.__sources[index]
        self.searchEdit.setToolTip(
            getattr(self.curSource, 'tooltip', DEFAULT_SEARCH_TIP))
        self.listbox.tagSource = self.curSource

        self.__preferencesButton.setVisible(
            not (getattr(self.curSource, 'preferences', False) is False))

        self.__fieldsEdit.setTags(self.__sourceFields[index])

        self.listbox.setMapping(self.fieldMapping.get(self.curSource.name, {}))

        self.searchEdit.setEnabled(hasattr(self.curSource, 'keyword_search'))

        self.submitButton.setVisible(hasattr(self.curSource, 'submit'))
            

    def configure(self):
        config = getattr(self.curSource, 'preferences', None)
        if config is None:
            return

        if isinstance(config, QWidget):
            win = config(parent=self)
        else:
            defaults = load_source_prefs(self.curSource.name, config)
            prefs = deepcopy(config)
            for pref, value in zip(prefs, defaults):
                if pref[1] == SPINBOX:
                    try:
                        pref[2][2] = int(value)
                    except ValueError:
                        pass
                elif pref[1] == COMBO:
                    pref[2][1] = value
                else:
                    pref[2] = value
            win = SimpleDialog(self.curSource.name, prefs, self)
        win.setModal(True)
        self.connect(win, SIGNAL('editingFinished'), self._applyPrefs)
        win.show()
    
    def emit_preview(self, tags):
        if not self.__updateEmpty.isChecked():
            self.emit(SIGNAL('enable_preview_mode'))
            self.emit(SIGNAL('setpreview'), tags)
        else:
            files = self._status['selectedfiles']
            previews = []
            for f, r in zip(files, tags):
                temp = {}
                for field in r:
                    if field not in f:
                        temp[field] = r[field]
                previews.append(temp)
            self.emit(SIGNAL('enable_preview_mode'))
            self.emit(SIGNAL('setpreview'), previews)

    def emitExact(self, d):
        if not self.__updateEmpty.isChecked():
            self.emit(SIGNAL('enable_preview_mode'))
            self.emit(SIGNAL('setpreview'), d)
        else:
            previews = []
            for f, r in d.items():
                temp = {}
                for field in r:
                    if field not in f:
                        temp[field] = r[field]
                previews.append(temp)
            self.emit(SIGNAL('enable_preview_mode'))
            self.emit(SIGNAL('setpreview'), previews)

    def loadSettings(self):
        settings = PuddleConfig(os.path.join(CONFIGDIR, 'tagsources.conf'))
        get = lambda s, k, i=False: settings.get('tagsources', s, k, i)

        source = get('lastsource', 'Musicbrainz')
        self.__sourceFields = [settings.get('tagsourcetags', ts.name, [])
            for ts in self.__sources]

        index = self.sourcelist.findText(source)
        if index == -1:
            index = 0
        self.sourcelist.setCurrentIndex(index)
        self.__fieldsEdit.setTags(self.__sourceFields[index])
        df = get('trackpattern', u'%track% - %title%')
        self.listbox.trackPattern = df

        albumformat = get('albumpattern',
            u'%artist% - %album%$if(%__numtracks%, [%__numtracks%], "")')
        self.listbox.albumPattern = albumformat

        sort_options = get('sortoptions',
            [u'artist, album', u'album, artist'])
        sort_options = split_strip(sort_options)
        self.listbox.setSortOptions(sort_options)

        sortindex = get('lastsort', 0)
        self.listbox.sort(sort_options[sortindex])

        filepath = os.path.join(CONFIGDIR, 'mappings')
        self.setMapping(audioinfo.loadmapping(filepath))

        useragent = get('useragent', '')
        if useragent:
            set_useragent(useragent)

        checkstate = get('existing', False)
        self.__updateEmpty.setChecked(checkstate)

        checkstate = get('autoretrieve', False)
        self.__autoRetrieve.setChecked(checkstate)

        self.listbox.albumBound = get('album_bound', 70, True) / 100.0
        self.listbox.trackBound = get('track_bound', 80, True) / 100.0
        self.listbox.jfdi = bool(get('jfdi', True, True))
        self.listbox.matchFields = get('match_fields', ['artist', 'title'])

    def setResults(self, retval):
        self.searchButton.setEnabled(True)
        if isinstance(retval, (basestring, QString)):
            self.label.setText(retval)
        else:
            releases, files = retval
            if releases:
                self.label.setText(translate("WebDB",
                    'Searching complete.'))
            else:
                self.label.setText(translate("WebDB",
                    'No matching albums were found.'))
            if files and self.__autoRetrieve.isChecked():
                self.listbox.setReleases(releases, files)
            else:
                self.listbox.setReleases(releases)
            self.listbox.emit(SIGNAL('infoChanged'), '')

    def search(self):
        if not self.searchButton.isEnabled():
            return
        files = self._status['selectedfiles']
        if self.curSource.group_by:
            group = split_by_field(files, *self.curSource.group_by)
        self.label.setText(translate("WebDB", 'Searching...'))
        text = None
        if self.searchEdit.text() and self.searchEdit.isEnabled():
            text = unicode(self.searchEdit.text())
        elif not files:
            self.label.setText(translate("WebDB",
                '<b>Select some files or enter search paramaters.</b>'))
            return

        def search():
            try:
                ret = []
                if text:
                    return self.curSource.keyword_search(text), None
                else:
                    return tag_source_search(self.curSource, group, files)
            except RetrievalError, e:
                return translate('WebDB',
                    'An error occured: %1').arg(unicode(e))
            except Exception, e:
                traceback.print_exc()
                return translate('WebDB',
                    'An unhandled error occurred: %1').arg(unicode(e))
예제 #4
0
파일: webdb.py 프로젝트: korala1968/tago
class MainWin(QWidget):
    def __init__(self, status, parent=None):
        QWidget.__init__(self, parent)
        self.settingsdialog = SettingsDialog

        connect = lambda obj, sig, slot: self.connect(obj, SIGNAL(sig), slot)

        self.setWindowTitle("Tag Sources")

        self.receives = []
        self.emits = [
            'writepreview', 'setpreview', 'clearpreview',
            'enable_preview_mode', 'logappend', 'disable_preview_mode'
        ]

        self.fieldMapping = audioinfo.mapping

        self._status = status
        self.__sources = [z() for z in tagsources]
        self.__sources.extend(load_mp3tag_sources())

        for ts in self.__sources:
            if hasattr(ts, 'preferences') and not isinstance(ts, QWidget):
                try:
                    ts.applyPrefs(load_source_prefs(ts.name, ts.preferences))
                except:
                    continue

        status['initialized_tagsources'] = self.__sources

        self.curSource = self.__sources[0]
        self.__sourceFields = [[] for z in self.__sources]

        self.sourcelist = QComboBox()
        self.sourcelist.addItems([ts.name for ts in self.__sources])
        connect(self.sourcelist, 'currentIndexChanged (int)',
                self.changeSource)

        sourcelabel = QLabel(translate("WebDB", 'Sour&ce: '))
        sourcelabel.setBuddy(self.sourcelist)

        preferences = QToolButton()
        preferences.setIcon(QIcon(':/preferences.png'))
        preferences.setToolTip(translate("WebDB", 'Configure'))
        self.__preferencesButton = preferences
        connect(preferences, 'clicked()', self.configure)

        self.searchEdit = QLineEdit()
        self.searchEdit.setToolTip(DEFAULT_SEARCH_TIP)
        connect(self.searchEdit, 'returnPressed()', self.search)

        self.searchButton = QPushButton(translate("WebDB", "&Search"))
        self.searchButton.setDefault(True)
        self.searchButton.setAutoDefault(True)
        connect(self.searchButton, "clicked()", self.search)

        self.submitButton = QPushButton(translate("WebDB", "S&ubmit Tags"))
        connect(self.submitButton, "clicked()", self.submit)

        write_preview = QPushButton(translate("WebDB", '&Write'))
        connect(write_preview, "clicked()", self.writePreview)

        clear = QPushButton(translate("Previews", "Clea&r preview"))
        connect(clear, "clicked()",
                lambda: self.emit(SIGNAL('disable_preview_mode')))

        self.label = QLabel(
            translate(
                "WebDB",
                "Select files and click on Search to retrieve metadata."))
        connect(status_obj, 'statusChanged', self.label.setText)

        self.listbox = ReleaseWidget(status, self.curSource)
        self.__updateEmpty = QCheckBox(
            translate("WebDB", 'Update empty fields only.'))
        connect(self.listbox, 'statusChanged', self.label.setText)
        connect(self.listbox, 'preview', self.emit_preview)
        connect(self.listbox, 'exactMatches', self.emitExact)

        self.__autoRetrieve = QCheckBox(
            translate("WebDB", 'Automatically retrieve matches.'))

        self.__fieldsEdit = FieldsEdit()
        self.__fieldsEdit.setToolTip(FIELDLIST_TIP)
        connect(self.__fieldsEdit, 'fieldsChanged', self.__changeFields)

        infolabel = QLabel()
        infolabel.setOpenExternalLinks(True)
        connect(self.listbox, 'infoChanged', infolabel.setText)

        connect(status_obj, 'logappend', SIGNAL('logappend'))

        sourcebox = QHBoxLayout()
        sourcebox.addWidget(sourcelabel)
        sourcebox.addWidget(self.sourcelist, 1)
        sourcebox.addWidget(preferences)

        hbox = QHBoxLayout()
        hbox.addWidget(self.searchButton, 0)
        hbox.addWidget(self.searchEdit, 1)

        vbox = QVBoxLayout()
        vbox.addLayout(sourcebox)
        vbox.addLayout(hbox)

        vbox.addWidget(self.label)
        vbox.addWidget(self.listbox, 1)
        hbox = QHBoxLayout()
        hbox.addWidget(infolabel, 1)
        hbox.addStretch()
        hbox.addWidget(self.submitButton)
        hbox.addWidget(write_preview)
        hbox.addWidget(clear)
        vbox.addLayout(hbox)

        vbox.addWidget(self.__fieldsEdit)
        vbox.addWidget(self.__updateEmpty)
        vbox.addWidget(self.__autoRetrieve)
        self.setLayout(vbox)
        self.changeSource(0)

    def _applyPrefs(self, prefs):
        self.curSource.applyPrefs(prefs)
        cparser = PuddleConfig(TAGSOURCE_CONFIG)
        name = self.curSource.name
        for section, value in zip(self.curSource.preferences, prefs):
            cparser.set(name, section[0], value)

    def __changeFields(self, fields):
        self.listbox.tagsToWrite = fields
        self.__sourceFields[self.sourcelist.currentIndex()] = fields

    def changeSource(self, index):
        self.curSource = self.__sources[index]
        self.searchEdit.setToolTip(
            getattr(self.curSource, 'tooltip', DEFAULT_SEARCH_TIP))
        self.listbox.tagSource = self.curSource

        self.__preferencesButton.setVisible(not (
            getattr(self.curSource, 'preferences', False) is False))

        self.__fieldsEdit.setTags(self.__sourceFields[index])

        self.listbox.setMapping(self.fieldMapping.get(self.curSource.name, {}))

        self.searchEdit.setEnabled(hasattr(self.curSource, 'keyword_search'))

        self.submitButton.setVisible(hasattr(self.curSource, 'submit'))

    def configure(self):
        config = getattr(self.curSource, 'preferences', None)
        if config is None:
            return

        if isinstance(config, QWidget):
            win = config(parent=self)
        else:
            defaults = load_source_prefs(self.curSource.name, config)
            prefs = deepcopy(config)
            for pref, value in zip(prefs, defaults):
                if pref[1] == SPINBOX:
                    try:
                        pref[2][2] = int(value)
                    except ValueError:
                        pass
                elif pref[1] == COMBO:
                    pref[2][1] = value
                else:
                    pref[2] = value
            win = SimpleDialog(self.curSource.name, prefs, self)
        win.setModal(True)
        self.connect(win, SIGNAL('editingFinished'), self._applyPrefs)
        win.show()

    def emit_preview(self, tags):
        if not self.__updateEmpty.isChecked():
            self.emit(SIGNAL('enable_preview_mode'))
            self.emit(SIGNAL('setpreview'), tags)
        else:
            files = self._status['selectedfiles']
            previews = []
            for f, r in zip(files, tags):
                temp = {}
                for field in r:
                    if field not in f:
                        temp[field] = r[field]
                previews.append(temp)
            self.emit(SIGNAL('enable_preview_mode'))
            self.emit(SIGNAL('setpreview'), previews)

    def emitExact(self, d):
        if not self.__updateEmpty.isChecked():
            self.emit(SIGNAL('enable_preview_mode'))
            self.emit(SIGNAL('setpreview'), d)
        else:
            previews = []
            for f, r in d.items():
                temp = {}
                for field in r:
                    if field not in f:
                        temp[field] = r[field]
                previews.append(temp)
            self.emit(SIGNAL('enable_preview_mode'))
            self.emit(SIGNAL('setpreview'), previews)

    def loadSettings(self):
        settings = PuddleConfig(os.path.join(CONFIGDIR, 'tagsources.conf'))
        get = lambda s, k, i=False: settings.get('tagsources', s, k, i)

        source = get('lastsource', 'Musicbrainz')
        self.__sourceFields = [
            settings.get('tagsourcetags', ts.name, []) for ts in self.__sources
        ]

        index = self.sourcelist.findText(source)
        if index == -1:
            index = 0
        self.sourcelist.setCurrentIndex(index)
        self.__fieldsEdit.setTags(self.__sourceFields[index])
        df = get('trackpattern', u'%track% - %title%')
        self.listbox.trackPattern = df

        albumformat = get(
            'albumpattern',
            u'%artist% - %album%$if(%__numtracks%, [%__numtracks%], "")')
        self.listbox.albumPattern = albumformat

        sort_options = get('sortoptions', [u'artist, album', u'album, artist'])
        sort_options = split_strip(sort_options)
        self.listbox.setSortOptions(sort_options)

        sortindex = get('lastsort', 0)
        self.listbox.sort(sort_options[sortindex])

        filepath = os.path.join(CONFIGDIR, 'mappings')
        self.setMapping(audioinfo.loadmapping(filepath))

        useragent = get('useragent', '')
        if useragent:
            set_useragent(useragent)

        checkstate = get('existing', False)
        self.__updateEmpty.setChecked(checkstate)

        checkstate = get('autoretrieve', False)
        self.__autoRetrieve.setChecked(checkstate)

        self.listbox.albumBound = get('album_bound', 70, True) / 100.0
        self.listbox.trackBound = get('track_bound', 80, True) / 100.0
        self.listbox.jfdi = bool(get('jfdi', True, True))
        self.listbox.matchFields = get('match_fields', ['artist', 'title'])

    def setResults(self, retval):
        self.searchButton.setEnabled(True)
        if isinstance(retval, (basestring, QString)):
            self.label.setText(retval)
        else:
            releases, files = retval
            if releases:
                self.label.setText(translate("WebDB", 'Searching complete.'))
            else:
                self.label.setText(
                    translate("WebDB", 'No matching albums were found.'))
            if files and self.__autoRetrieve.isChecked():
                self.listbox.setReleases(releases, files)
            else:
                self.listbox.setReleases(releases)
            self.listbox.emit(SIGNAL('infoChanged'), '')

    def search(self):
        if not self.searchButton.isEnabled():
            return
        files = self._status['selectedfiles']
        if self.curSource.group_by:
            group = split_by_field(files, *self.curSource.group_by)
        self.label.setText(translate("WebDB", 'Searching...'))
        text = None
        if self.searchEdit.text() and self.searchEdit.isEnabled():
            text = unicode(self.searchEdit.text())
        elif not files:
            self.label.setText(
                translate(
                    "WebDB",
                    '<b>Select some files or enter search paramaters.</b>'))
            return

        def search():
            try:
                ret = []
                if text:
                    return self.curSource.keyword_search(text), None
                else:
                    return tag_source_search(self.curSource, group, files)
            except RetrievalError, e:
                return translate('WebDB',
                                 'An error occured: %1').arg(unicode(e))
            except Exception, e:
                traceback.print_exc()
                return translate('WebDB',
                                 'An unhandled error occurred: %1').arg(
                                     unicode(e))