diff --git a/NEWS.txt b/NEWS.txt
index d657aa179..cffa363dd 100644
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -4,6 +4,8 @@ Version 0.9.0alpha10 - 2007-05-XX
* Don't compress huge ID3 frames. (#2850)
* Move "Add Cluster As Release" to a plugin.
* Allow horizontal scrollbar in the file browser panel. (#2856)
+ * Removed "Basic" tab from the "Details" window, "Advanced" tab renamed to "Metadata".
+ * The tag editor can be used to edit multiple files. (#2893)
* Bug Fixes:
* F1 for Help instead of CTRL+H on Windows and Linux. (#2485, Nikolai Prokoschenko)
* Tabbing focus transition from search isn't as expected. (#2546, Nikolai Prokoschenko)
diff --git a/picard/tagger.py b/picard/tagger.py
index dc5e2ec0f..a976f0c70 100644
--- a/picard/tagger.py
+++ b/picard/tagger.py
@@ -227,8 +227,13 @@ class Tagger(QtGui.QApplication):
self.log.debug("Loading gettext translation, localedir=%r", localedir)
self.translation = gettext.translation("picard", localedir)
self.translation.install(True)
+ ngettext = self.translations.ngettext
except IOError:
__builtin__.__dict__['_'] = lambda a: a
+ def ngettext(a, b, c):
+ if c == 1: return a
+ else: return b
+ __builtin__.__dict__['ngettext'] = ngettext
def move_files_to_album(self, files, albumid=None, album=None):
"""Move `files` to tracks on album `albumid`."""
diff --git a/picard/ui/itemviews.py b/picard/ui/itemviews.py
index bca0f6c02..c37cf9161 100644
--- a/picard/ui/itemviews.py
+++ b/picard/ui/itemviews.py
@@ -409,7 +409,7 @@ class BaseTreeView(QtGui.QTreeWidget):
def activate_item(self, index):
obj = self.panel.object_from_item(self.itemFromIndex(index))
if obj.can_edit_tags():
- self.window.edit_tags(obj)
+ self.window.edit_tags([obj])
def add_cluster(self, cluster, parent_item=None):
if parent_item is None:
diff --git a/picard/ui/mainwindow.py b/picard/ui/mainwindow.py
index f9d0ee76e..1979447dc 100644
--- a/picard/ui/mainwindow.py
+++ b/picard/ui/mainwindow.py
@@ -508,13 +508,12 @@ class MainWindow(QtGui.QMainWindow):
def analyze(self):
self.tagger.analyze(self.panel.selected_objects())
- def edit_tags(self, obj=None):
- if not obj:
- obj = self.selected_objects[0]
- if isinstance(obj, Track):
- obj = obj.linked_file
- tagedit = TagEditor(obj, self)
- tagedit.exec_()
+ def edit_tags(self, objs=None):
+ if not objs:
+ objs = self.selected_objects
+ objs = self.tagger.get_files_from_objects(objs)
+ dialog = TagEditor(objs, self)
+ dialog.exec_()
def cluster(self):
self.tagger.cluster(self.panel.selected_objects())
diff --git a/picard/ui/tageditor.py b/picard/ui/tageditor.py
index 150457592..80f7c6db6 100644
--- a/picard/ui/tageditor.py
+++ b/picard/ui/tageditor.py
@@ -22,8 +22,10 @@ from PyQt4 import QtCore, QtGui
from picard.util import sanitize_date, format_time, encode_filename
from picard.ui.util import StandardButton
from picard.util.tags import tag_names, display_tag_name
+from picard.ui.ui_tageditor import Ui_TagEditorDialog
from picard.ui.ui_edittagdialog import Ui_EditTagDialog
+
class EditTagDialog(QtGui.QDialog):
"""Single tag editor."""
@@ -40,49 +42,47 @@ class EditTagDialog(QtGui.QDialog):
self.ui.name.setEditText(name)
if value:
self.ui.value.document().setPlainText(value)
+ self.ui.value.selectAll()
+ self.ui.value.setFocus(QtCore.Qt.OtherFocusReason)
+ else:
+ self.ui.name.lineEdit().selectAll()
def accept(self):
self.name = unicode(self.ui.name.currentText())
self.value = self.ui.value.document().toPlainText()
QtGui.QDialog.accept(self)
+
class TagEditor(QtGui.QDialog):
- fields = [
- ("title", None),
- ("album", None),
- ("artist", None),
- ("tracknumber", None),
- ("totaltracks", None),
- ("discnumber", None),
- ("totaldiscs", None),
- ("date", sanitize_date),
- ("albumartist", None),
- ]
-
- def __init__(self, file, parent=None):
+ def __init__(self, files, parent=None):
QtGui.QDialog.__init__(self, parent)
- from picard.ui.ui_tageditor import Ui_TagEditorDialog
self.ui = Ui_TagEditorDialog()
self.ui.setupUi(self)
- self.setWindowTitle(_("Details - %s") % os.path.basename(file.filename))
+
+ title = _("Details") + " - "
+ total = len(files)
+ if total == 1:
+ title += files[0].base_filename
+ else:
+ title += ngettext("%d file", "%d files", total) % total
+ self.setWindowTitle(title)
self.ui.buttonbox.addButton(StandardButton(StandardButton.OK), QtGui.QDialogButtonBox.AcceptRole)
self.ui.buttonbox.addButton(StandardButton(StandardButton.CANCEL), QtGui.QDialogButtonBox.RejectRole)
self.connect(self.ui.buttonbox, QtCore.SIGNAL('accepted()'), self, QtCore.SLOT('accept()'))
self.connect(self.ui.buttonbox, QtCore.SIGNAL('rejected()'), self, QtCore.SLOT('reject()'))
- self.ui.tags.setHeaderLabels([_("Name"), _("Value")])
- self.connect(self.ui.tags, QtCore.SIGNAL("itemActivated (QTreeWidgetItem*, int)"), self.edit_tag)
self.connect(self.ui.tags_add, QtCore.SIGNAL('clicked()'), self.add_tag)
self.connect(self.ui.tags_delete, QtCore.SIGNAL('clicked()'), self.delete_tag)
- if hasattr(self.ui.tags, 'setSortingEnabled'): # Qt 4.2
- self.ui.tags.setSortingEnabled(True)
- self.ui.tags.sortByColumn(0, QtCore.Qt.AscendingOrder)
- self.file = file
- self.metadata = file.metadata
- self.__names = []
+ self.connect(self.ui.tags, QtCore.SIGNAL("itemActivated (QTreeWidgetItem*, int)"), self.edit_tag)
+
+ self.ui.tags.setSortingEnabled(True)
+ self.ui.tags.sortByColumn(0, QtCore.Qt.AscendingOrder)
+
+ self.changed = set()
+ self.files = files
self.load()
self.load_info()
@@ -90,96 +90,82 @@ class TagEditor(QtGui.QDialog):
self.save()
QtGui.QDialog.accept(self)
- def load_info(self):
- info = []
- info.append((_('Filename:'), self.file.filename))
- if '~format' in self.file.orig_metadata:
- info.append((_('Format:'), self.file.orig_metadata['~format']))
- try:
- size = os.path.getsize(encode_filename(self.file.filename))
- if size < 1024:
- size = '%d B' % size
- elif size < 1024 * 1024:
- size = '%0.1f kB' % (size / 1024.0)
- else:
- size = '%0.1f MB' % (size / 1024.0 / 1024.0)
- info.append((_('Size:'), size))
- except:
- pass
- if '~#length' in self.file.orig_metadata:
- info.append((_('Length:'), format_time(self.file.orig_metadata['~#length'])))
- if '~#bitrate' in self.file.orig_metadata:
- info.append((_('Bitrate:'), '%d kbps' % self.file.orig_metadata['~#bitrate']))
- if '~#sample_rate' in self.file.orig_metadata:
- info.append((_('Sample rate:'), '%d Hz' % self.file.orig_metadata['~#sample_rate']))
- if '~#bits_per_sample' in self.file.orig_metadata:
- info.append((_('Bits per sample:'), str(self.file.orig_metadata['~#bits_per_sample'])))
- if '~#channels' in self.file.orig_metadata:
- ch = self.file.orig_metadata['~#channels']
- if ch == 1: ch = _('Mono')
- elif ch == 2: ch = _('Stereo')
- else: ch = str(ch)
- info.append((_('Channels:'), ch))
- text = '
'.join(map(lambda i: '%s
%s' % i, info))
- self.ui.info.setText(text)
-
def load(self):
- self.__names = []
- for name, convert in self.fields:
- text = self.metadata[name]
- getattr(self.ui, name).setText(text)
- self.__names.append(name)
+ all_tag_names = set()
+ common_tags = None
+ counts = dict()
+ for file in self.files:
+ tags = set()
+ for name, values in file.metadata.rawitems():
+ if not name.startswith("~"):
+ tags.add((name, tuple(sorted(values))))
+ all_tag_names.add(name)
+ counts[name] = counts.get(name, 0) + 1
+ if common_tags is None:
+ common_tags = tags
+ else:
+ common_tags = common_tags.intersection(tags)
- items = self.metadata.items()
- items = filter(lambda i: i[0] not in self.__names, items)
- for name, value in items:
- if not name.startswith("~"):
+ common_tag_names = set([a for (a, b) in common_tags])
+ different_tag_names = all_tag_names.difference(common_tag_names)
+
+ total = len(self.files)
+ for name in different_tag_names:
+ item = QtGui.QTreeWidgetItem(self.ui.tags)
+ item.setText(0, display_tag_name(name))
+ item.setData(0, QtCore.Qt.UserRole, QtCore.QVariant(name))
+ font = item.font(1)
+ font.setItalic(True)
+ item.setFont(1, font)
+ missing = total - counts[name]
+ if not missing:
+ value = ngettext("(different across %d file)",
+ "(different across %d files)", total) % total
+ else:
+ value = ngettext("(missing from %d file)",
+ "(missing from %d files)", missing) % missing
+ item.setText(1, value)
+
+ for name, values in common_tags:
+ for value in values:
item = QtGui.QTreeWidgetItem(self.ui.tags)
item.setText(0, display_tag_name(name))
item.setData(0, QtCore.Qt.UserRole, QtCore.QVariant(name))
item.setText(1, value)
- self.__names.append(name)
-
- if "~artwork" in self.metadata:
- pictures = self.metadata.getall("~artwork")
- for mime, data in pictures:
- item = QtGui.QListWidgetItem()
- pixmap = QtGui.QPixmap()
- pixmap.loadFromData(data)
- icon = QtGui.QIcon(pixmap)
- item.setIcon(icon)
- self.ui.artwork_list.addItem(item)
def save(self):
- for name in self.__names:
- try: del self.metadata[name]
- except KeyError: pass
-
- for name, convert in self.fields:
- text = unicode(getattr(self.ui, name).text())
- if convert:
- text = convert(text)
- if text or name in self.metadata:
- self.metadata[name] = text
-
+ metadata = Metadata()
for i in range(self.ui.tags.topLevelItemCount()):
item = self.ui.tags.topLevelItem(i)
name = unicode(item.data(0, QtCore.Qt.UserRole).toString())
- value = unicode(item.text(1))
- self.metadata.add(name, value)
+ if name in self.changed:
+ value = unicode(item.text(1))
+ metadata.add(name, value)
- self.file.update()
+ for file in self.files:
+ for name in self.changed:
+ try:
+ del file.metadata[name]
+ except KeyError:
+ pass
+ file.metadata.update(metadata)
+ file.update()
def edit_tag(self, item, column):
name = unicode(item.data(0, QtCore.Qt.UserRole).toString())
value = item.text(1)
dialog = EditTagDialog(name, value, self)
if dialog.exec_():
- name = dialog.name
- value = dialog.value
- item.setText(0, display_tag_name(name))
- item.setData(0, QtCore.Qt.UserRole, QtCore.QVariant(name))
- item.setText(1, value)
+ if value != dialog.value:
+ name = dialog.name
+ value = dialog.value
+ item.setText(0, display_tag_name(name))
+ item.setData(0, QtCore.Qt.UserRole, QtCore.QVariant(name))
+ font = item.font(1)
+ font.setItalic(False)
+ item.setFont(1, font)
+ item.setText(1, value)
+ self.changed.add(name)
def add_tag(self):
dialog = EditTagDialog('', None, self)
@@ -190,9 +176,50 @@ class TagEditor(QtGui.QDialog):
item.setText(0, display_tag_name(name))
item.setData(0, QtCore.Qt.UserRole, QtCore.QVariant(name))
item.setText(1, value)
+ self.changed.add(name)
def delete_tag(self):
items = self.ui.tags.selectedItems()
for item in items:
+ name = unicode(item.data(0, QtCore.Qt.UserRole).toString())
index = self.ui.tags.indexOfTopLevelItem(item)
self.ui.tags.takeTopLevelItem(index)
+ self.changed.add(name)
+
+ def load_info(self):
+ total = len(self.files)
+ if total == 1:
+ file = self.files[0]
+ info = []
+ info.append((_('Filename:'), file.filename))
+ if '~format' in file.orig_metadata:
+ info.append((_('Format:'), file.orig_metadata['~format']))
+ try:
+ size = os.path.getsize(encode_filename(file.filename))
+ if size < 1024:
+ size = '%d B' % size
+ elif size < 1024 * 1024:
+ size = '%0.1f kB' % (size / 1024.0)
+ else:
+ size = '%0.1f MB' % (size / 1024.0 / 1024.0)
+ info.append((_('Size:'), size))
+ except:
+ pass
+ if '~#length' in file.orig_metadata:
+ info.append((_('Length:'), format_time(file.orig_metadata['~#length'])))
+ if '~#bitrate' in file.orig_metadata:
+ info.append((_('Bitrate:'), '%d kbps' % file.orig_metadata['~#bitrate']))
+ if '~#sample_rate' in file.orig_metadata:
+ info.append((_('Sample rate:'), '%d Hz' % file.orig_metadata['~#sample_rate']))
+ if '~#bits_per_sample' in file.orig_metadata:
+ info.append((_('Bits per sample:'), str(file.orig_metadata['~#bits_per_sample'])))
+ if '~#channels' in file.orig_metadata:
+ ch = file.orig_metadata['~#channels']
+ if ch == 1: ch = _('Mono')
+ elif ch == 2: ch = _('Stereo')
+ else: ch = str(ch)
+ info.append((_('Channels:'), ch))
+ text = '
'.join(map(lambda i: '%s
%s' % i, info))
+ self.ui.info.setText(text)
+ else:
+ self.ui.info.setText(ngettext("%d file", "%d files", total) % total)
diff --git a/picard/ui/ui_edittagdialog.py b/picard/ui/ui_edittagdialog.py
index 53d240f63..a563130bc 100644
--- a/picard/ui/ui_edittagdialog.py
+++ b/picard/ui/ui_edittagdialog.py
@@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'ui/edittagdialog.ui'
#
-# Created: Mon Apr 30 08:24:39 2007
+# Created: Sat May 26 19:27:45 2007
# by: PyQt4 UI code generator 4.1
#
# WARNING! All changes made in this file will be lost!
@@ -38,6 +38,8 @@ class Ui_EditTagDialog(object):
self.retranslateUi(EditTagDialog)
QtCore.QMetaObject.connectSlotsByName(EditTagDialog)
+ EditTagDialog.setTabOrder(self.buttonbox,self.name)
+ EditTagDialog.setTabOrder(self.name,self.value)
def retranslateUi(self, EditTagDialog):
EditTagDialog.setWindowTitle(_(u"Edit Tag"))
diff --git a/picard/ui/ui_tageditor.py b/picard/ui/ui_tageditor.py
index c75a50fd7..295c918cf 100644
--- a/picard/ui/ui_tageditor.py
+++ b/picard/ui/ui_tageditor.py
@@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'ui/tageditor.ui'
#
-# Created: Sat Mar 3 19:09:31 2007
+# Created: Sat May 26 20:06:01 2007
# by: PyQt4 UI code generator 4.1
#
# WARNING! All changes made in this file will be lost!
@@ -13,7 +13,7 @@ from PyQt4 import QtCore, QtGui
class Ui_TagEditorDialog(object):
def setupUi(self, TagEditorDialog):
TagEditorDialog.setObjectName("TagEditorDialog")
- TagEditorDialog.resize(QtCore.QSize(QtCore.QRect(0,0,455,355).size()).expandedTo(TagEditorDialog.minimumSizeHint()))
+ TagEditorDialog.resize(QtCore.QSize(QtCore.QRect(0,0,535,436).size()).expandedTo(TagEditorDialog.minimumSizeHint()))
self.vboxlayout = QtGui.QVBoxLayout(TagEditorDialog)
self.vboxlayout.setMargin(9)
@@ -23,160 +23,6 @@ class Ui_TagEditorDialog(object):
self.tabWidget = QtGui.QTabWidget(TagEditorDialog)
self.tabWidget.setObjectName("tabWidget")
- self.tab = QtGui.QWidget()
- self.tab.setObjectName("tab")
-
- self.gridlayout = QtGui.QGridLayout(self.tab)
- self.gridlayout.setMargin(9)
- self.gridlayout.setSpacing(2)
- self.gridlayout.setObjectName("gridlayout")
-
- spacerItem = QtGui.QSpacerItem(20,40,QtGui.QSizePolicy.Minimum,QtGui.QSizePolicy.Expanding)
- self.gridlayout.addItem(spacerItem,7,0,1,2)
-
- self.label_7 = QtGui.QLabel(self.tab)
- self.label_7.setObjectName("label_7")
- self.gridlayout.addWidget(self.label_7,5,0,1,1)
-
- self.label_4 = QtGui.QLabel(self.tab)
- self.label_4.setObjectName("label_4")
- self.gridlayout.addWidget(self.label_4,4,0,1,1)
-
- self.albumartist = QtGui.QLineEdit(self.tab)
- self.albumartist.setObjectName("albumartist")
- self.gridlayout.addWidget(self.albumartist,3,1,1,1)
-
- self.label_2 = QtGui.QLabel(self.tab)
- self.label_2.setObjectName("label_2")
- self.gridlayout.addWidget(self.label_2,3,0,1,1)
-
- self.label_3 = QtGui.QLabel(self.tab)
- self.label_3.setObjectName("label_3")
- self.gridlayout.addWidget(self.label_3,1,0,1,1)
-
- self.title = QtGui.QLineEdit(self.tab)
- self.title.setObjectName("title")
- self.gridlayout.addWidget(self.title,0,1,1,1)
-
- self.artist = QtGui.QLineEdit(self.tab)
- self.artist.setObjectName("artist")
- self.gridlayout.addWidget(self.artist,1,1,1,1)
-
- self.album = QtGui.QLineEdit(self.tab)
- self.album.setObjectName("album")
- self.gridlayout.addWidget(self.album,2,1,1,1)
-
- self.hboxlayout = QtGui.QHBoxLayout()
- self.hboxlayout.setMargin(0)
- self.hboxlayout.setSpacing(2)
- self.hboxlayout.setObjectName("hboxlayout")
-
- self.tracknumber = QtGui.QLineEdit(self.tab)
-
- sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Policy(1),QtGui.QSizePolicy.Policy(0))
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.tracknumber.sizePolicy().hasHeightForWidth())
- self.tracknumber.setSizePolicy(sizePolicy)
- self.tracknumber.setMaximumSize(QtCore.QSize(40,16777215))
- self.tracknumber.setObjectName("tracknumber")
- self.hboxlayout.addWidget(self.tracknumber)
-
- self.label_5 = QtGui.QLabel(self.tab)
-
- sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Policy(1),QtGui.QSizePolicy.Policy(0))
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.label_5.sizePolicy().hasHeightForWidth())
- self.label_5.setSizePolicy(sizePolicy)
- self.label_5.setObjectName("label_5")
- self.hboxlayout.addWidget(self.label_5)
-
- self.totaltracks = QtGui.QLineEdit(self.tab)
-
- sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Policy(1),QtGui.QSizePolicy.Policy(0))
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.totaltracks.sizePolicy().hasHeightForWidth())
- self.totaltracks.setSizePolicy(sizePolicy)
- self.totaltracks.setMaximumSize(QtCore.QSize(40,16777215))
- self.totaltracks.setObjectName("totaltracks")
- self.hboxlayout.addWidget(self.totaltracks)
-
- spacerItem1 = QtGui.QSpacerItem(241,20,QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Minimum)
- self.hboxlayout.addItem(spacerItem1)
- self.gridlayout.addLayout(self.hboxlayout,4,1,1,1)
-
- self.hboxlayout1 = QtGui.QHBoxLayout()
- self.hboxlayout1.setMargin(0)
- self.hboxlayout1.setSpacing(2)
- self.hboxlayout1.setObjectName("hboxlayout1")
-
- self.discnumber = QtGui.QLineEdit(self.tab)
-
- sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Policy(1),QtGui.QSizePolicy.Policy(0))
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.discnumber.sizePolicy().hasHeightForWidth())
- self.discnumber.setSizePolicy(sizePolicy)
- self.discnumber.setMaximumSize(QtCore.QSize(40,16777215))
- self.discnumber.setBaseSize(QtCore.QSize(50,0))
- self.discnumber.setObjectName("discnumber")
- self.hboxlayout1.addWidget(self.discnumber)
-
- self.label_6 = QtGui.QLabel(self.tab)
- self.label_6.setObjectName("label_6")
- self.hboxlayout1.addWidget(self.label_6)
-
- self.totaldiscs = QtGui.QLineEdit(self.tab)
-
- sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Policy(1),QtGui.QSizePolicy.Policy(0))
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.totaldiscs.sizePolicy().hasHeightForWidth())
- self.totaldiscs.setSizePolicy(sizePolicy)
- self.totaldiscs.setMaximumSize(QtCore.QSize(40,16777215))
- self.totaldiscs.setBaseSize(QtCore.QSize(50,0))
- self.totaldiscs.setObjectName("totaldiscs")
- self.hboxlayout1.addWidget(self.totaldiscs)
-
- spacerItem2 = QtGui.QSpacerItem(241,20,QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Minimum)
- self.hboxlayout1.addItem(spacerItem2)
- self.gridlayout.addLayout(self.hboxlayout1,5,1,1,1)
-
- self.hboxlayout2 = QtGui.QHBoxLayout()
- self.hboxlayout2.setMargin(0)
- self.hboxlayout2.setSpacing(2)
- self.hboxlayout2.setObjectName("hboxlayout2")
-
- self.date = QtGui.QLineEdit(self.tab)
-
- sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Policy(1),QtGui.QSizePolicy.Policy(0))
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.date.sizePolicy().hasHeightForWidth())
- self.date.setSizePolicy(sizePolicy)
- self.date.setMaximumSize(QtCore.QSize(80,16777215))
- self.date.setObjectName("date")
- self.hboxlayout2.addWidget(self.date)
-
- spacerItem3 = QtGui.QSpacerItem(61,20,QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Minimum)
- self.hboxlayout2.addItem(spacerItem3)
- self.gridlayout.addLayout(self.hboxlayout2,6,1,1,1)
-
- self.label_9 = QtGui.QLabel(self.tab)
- self.label_9.setObjectName("label_9")
- self.gridlayout.addWidget(self.label_9,2,0,1,1)
-
- self.label_8 = QtGui.QLabel(self.tab)
- self.label_8.setObjectName("label_8")
- self.gridlayout.addWidget(self.label_8,6,0,1,1)
-
- self.label = QtGui.QLabel(self.tab)
- self.label.setObjectName("label")
- self.gridlayout.addWidget(self.label,0,0,1,1)
- self.tabWidget.addTab(self.tab,"")
-
self.tab_4 = QtGui.QWidget()
self.tab_4.setObjectName("tab_4")
@@ -190,22 +36,22 @@ class Ui_TagEditorDialog(object):
self.tags.setObjectName("tags")
self.vboxlayout1.addWidget(self.tags)
- self.hboxlayout3 = QtGui.QHBoxLayout()
- self.hboxlayout3.setMargin(0)
- self.hboxlayout3.setSpacing(6)
- self.hboxlayout3.setObjectName("hboxlayout3")
+ self.hboxlayout = QtGui.QHBoxLayout()
+ self.hboxlayout.setMargin(0)
+ self.hboxlayout.setSpacing(6)
+ self.hboxlayout.setObjectName("hboxlayout")
self.tags_add = QtGui.QPushButton(self.tab_4)
self.tags_add.setObjectName("tags_add")
- self.hboxlayout3.addWidget(self.tags_add)
+ self.hboxlayout.addWidget(self.tags_add)
self.tags_delete = QtGui.QPushButton(self.tab_4)
self.tags_delete.setObjectName("tags_delete")
- self.hboxlayout3.addWidget(self.tags_delete)
+ self.hboxlayout.addWidget(self.tags_delete)
- spacerItem4 = QtGui.QSpacerItem(151,20,QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Minimum)
- self.hboxlayout3.addItem(spacerItem4)
- self.vboxlayout1.addLayout(self.hboxlayout3)
+ spacerItem = QtGui.QSpacerItem(151,20,QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Minimum)
+ self.hboxlayout.addItem(spacerItem)
+ self.vboxlayout1.addLayout(self.hboxlayout)
self.tabWidget.addTab(self.tab_4,"")
self.tab_2 = QtGui.QWidget()
@@ -253,39 +99,17 @@ class Ui_TagEditorDialog(object):
self.retranslateUi(TagEditorDialog)
self.tabWidget.setCurrentIndex(0)
QtCore.QMetaObject.connectSlotsByName(TagEditorDialog)
- TagEditorDialog.setTabOrder(self.title,self.artist)
- TagEditorDialog.setTabOrder(self.artist,self.album)
- TagEditorDialog.setTabOrder(self.album,self.albumartist)
- TagEditorDialog.setTabOrder(self.albumartist,self.tracknumber)
- TagEditorDialog.setTabOrder(self.tracknumber,self.totaltracks)
- TagEditorDialog.setTabOrder(self.totaltracks,self.discnumber)
- TagEditorDialog.setTabOrder(self.discnumber,self.totaldiscs)
- TagEditorDialog.setTabOrder(self.totaldiscs,self.date)
- TagEditorDialog.setTabOrder(self.date,self.tags)
TagEditorDialog.setTabOrder(self.tags,self.tags_add)
TagEditorDialog.setTabOrder(self.tags_add,self.tags_delete)
TagEditorDialog.setTabOrder(self.tags_delete,self.tabWidget)
TagEditorDialog.setTabOrder(self.tabWidget,self.artwork_list)
def retranslateUi(self, TagEditorDialog):
- self.label_7.setText(_(u"Disc:"))
- self.label_4.setText(_(u"Track:"))
- self.label_2.setText(_(u"Album artist:"))
- self.label_3.setText(_(u"Artist:"))
- self.tracknumber.setInputMask(_(u"000; "))
- self.label_5.setText(_(u"of"))
- self.totaltracks.setInputMask(_(u"000; "))
- self.discnumber.setInputMask(_(u"000; "))
- self.label_6.setText(_(u"of"))
- self.totaldiscs.setInputMask(_(u"000; "))
- self.date.setInputMask(_(u"0000-00-00; "))
- self.label_9.setText(_(u"Album:"))
- self.label_8.setText(_(u"Date:"))
- self.label.setText(_(u"Title:"))
- self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _(u"&Basic"))
+ self.tags.headerItem().setText(0,_(u"Name"))
+ self.tags.headerItem().setText(1,_(u"Value"))
self.tags_add.setText(_(u"&Add..."))
self.tags_delete.setText(_(u"Delete"))
- self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_4), _(u"&Advanced"))
+ self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_4), _(u"&Metadata"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _(u"A&rtwork"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_5), _(u"&Info"))
diff --git a/picard/util/tags.py b/picard/util/tags.py
index c168167ba..028538347 100644
--- a/picard/util/tags.py
+++ b/picard/util/tags.py
@@ -22,6 +22,7 @@ tag_names = {
'artist': N_('Artist'),
'title': N_('Title'),
'date': N_('Date'),
+ 'albumartist': N_('Album Artist'),
'tracknumber': N_('Track Number'),
'totaltracks': N_('Total Tracks'),
'discnumber': N_('Disc Number'),
diff --git a/ui/edittagdialog.ui b/ui/edittagdialog.ui
index 198764e3e..c1211d75c 100644
--- a/ui/edittagdialog.ui
+++ b/ui/edittagdialog.ui
@@ -45,6 +45,11 @@
+
+ buttonbox
+ name
+ value
+
diff --git a/ui/tageditor.ui b/ui/tageditor.ui
index a03c6f5e5..5e629f335 100644
--- a/ui/tageditor.ui
+++ b/ui/tageditor.ui
@@ -5,8 +5,8 @@
0
0
- 455
- 355
+ 535
+ 436
@@ -21,307 +21,9 @@
0
-
-
- &Basic
-
-
-
- 9
-
-
- 2
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
- -
-
-
- Disc:
-
-
-
- -
-
-
- Track:
-
-
-
- -
-
-
- -
-
-
- Album artist:
-
-
-
- -
-
-
- Artist:
-
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- 0
-
-
- 2
-
-
-
-
-
-
- 1
- 0
- 0
- 0
-
-
-
-
- 40
- 16777215
-
-
-
- 000;
-
-
-
- -
-
-
-
- 1
- 0
- 0
- 0
-
-
-
- of
-
-
-
- -
-
-
-
- 1
- 0
- 0
- 0
-
-
-
-
- 40
- 16777215
-
-
-
- 000;
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 241
- 20
-
-
-
-
-
-
- -
-
-
- 0
-
-
- 2
-
-
-
-
-
-
- 1
- 0
- 0
- 0
-
-
-
-
- 40
- 16777215
-
-
-
-
- 50
- 0
-
-
-
- 000;
-
-
-
- -
-
-
- of
-
-
-
- -
-
-
-
- 1
- 0
- 0
- 0
-
-
-
-
- 40
- 16777215
-
-
-
-
- 50
- 0
-
-
-
- 000;
-
-
-
- -
-
-
- Qt::Horizontal
-
-
- QSizePolicy::Expanding
-
-
-
- 241
- 20
-
-
-
-
-
-
- -
-
-
- 0
-
-
- 2
-
-
-
-
-
-
- 1
- 0
- 0
- 0
-
-
-
-
- 80
- 16777215
-
-
-
- 0000-00-00;
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 61
- 20
-
-
-
-
-
-
- -
-
-
- Album:
-
-
-
- -
-
-
- Date:
-
-
-
- -
-
-
- Title:
-
-
-
-
-
- &Advanced
+ &Metadata
@@ -335,6 +37,16 @@
false
+
+
+ Name
+
+
+
+
+ Value
+
+
-
@@ -458,15 +170,6 @@
- title
- artist
- album
- albumartist
- tracknumber
- totaltracks
- discnumber
- totaldiscs
- date
tags
tags_add
tags_delete