diff --git a/picard/ui/metadatabox.py b/picard/ui/metadatabox.py index ae9074672..883717c53 100644 --- a/picard/ui/metadatabox.py +++ b/picard/ui/metadatabox.py @@ -96,18 +96,19 @@ class TagCounter(dict): class TagDiff(object): - __slots__ = ("tag_names", "new", "orig", "status", "objects") + __slots__ = ("tag_names", "new", "orig", "status", "objects", "max_length_delta_ms") - def __init__(self): + def __init__(self, max_length_diff=2): self.tag_names = [] self.new = TagCounter(self) self.orig = TagCounter(self) self.status = defaultdict(lambda: 0) self.objects = 0 + self.max_length_delta_ms = max_length_diff * 1000 def __tag_ne(self, tag, orig, new): if tag == "~length": - return abs(float(orig) - float(new)) > 2000 + return abs(float(orig) - float(new)) > self.max_length_delta_ms else: return orig != new @@ -427,7 +428,7 @@ class MetadataBox(QtWidgets.QTableWidget): if not (files or tracks): return None - tag_diff = TagDiff() + tag_diff = TagDiff(max_length_diff=config.setting["ignore_track_duration_difference_under"]) orig_tags = tag_diff.orig new_tags = tag_diff.new # existing_tags are orig_tags that would not be overwritten by diff --git a/picard/ui/options/advanced.py b/picard/ui/options/advanced.py index 4502341f3..fd46b4d06 100644 --- a/picard/ui/options/advanced.py +++ b/picard/ui/options/advanced.py @@ -34,6 +34,7 @@ class AdvancedOptionsPage(OptionsPage): config.TextOption("setting", "ignore_regex", ""), config.BoolOption("setting", "ignore_hidden_files", False), config.BoolOption("setting", "recursively_add_files", True), + config.IntOption("setting", "ignore_track_duration_difference_under", 2), config.BoolOption("setting", "completeness_ignore_videos", False), config.BoolOption("setting", "completeness_ignore_pregap", False), config.BoolOption("setting", "completeness_ignore_data", False), @@ -50,6 +51,7 @@ class AdvancedOptionsPage(OptionsPage): self.ui.ignore_regex.setText(config.setting["ignore_regex"]) self.ui.ignore_hidden_files.setChecked(config.setting["ignore_hidden_files"]) self.ui.recursively_add_files.setChecked(config.setting["recursively_add_files"]) + self.ui.ignore_track_duration_difference_under.setValue(config.setting["ignore_track_duration_difference_under"]) self.ui.completeness_ignore_videos.setChecked(config.setting["completeness_ignore_videos"]) self.ui.completeness_ignore_pregap.setChecked(config.setting["completeness_ignore_pregap"]) self.ui.completeness_ignore_data.setChecked(config.setting["completeness_ignore_data"]) @@ -59,6 +61,7 @@ class AdvancedOptionsPage(OptionsPage): config.setting["ignore_regex"] = self.ui.ignore_regex.text() config.setting["ignore_hidden_files"] = self.ui.ignore_hidden_files.isChecked() config.setting["recursively_add_files"] = self.ui.recursively_add_files.isChecked() + config.setting["ignore_track_duration_difference_under"] = self.ui.ignore_track_duration_difference_under.value() config.setting["completeness_ignore_videos"] = self.ui.completeness_ignore_videos.isChecked() config.setting["completeness_ignore_pregap"] = self.ui.completeness_ignore_pregap.isChecked() config.setting["completeness_ignore_data"] = self.ui.completeness_ignore_data.isChecked() diff --git a/picard/ui/ui_options_advanced.py b/picard/ui/ui_options_advanced.py index f094fa872..0148076ac 100644 --- a/picard/ui/ui_options_advanced.py +++ b/picard/ui/ui_options_advanced.py @@ -16,22 +16,51 @@ class Ui_AdvancedOptionsPage(object): self.gridlayout = QtWidgets.QGridLayout(self.groupBox) self.gridlayout.setSpacing(2) self.gridlayout.setObjectName("gridlayout") + self.recursively_add_files = QtWidgets.QCheckBox(self.groupBox) + self.recursively_add_files.setObjectName("recursively_add_files") + self.gridlayout.addWidget(self.recursively_add_files, 5, 0, 1, 1) + self.horizontalLayout = QtWidgets.QHBoxLayout() + self.horizontalLayout.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint) + self.horizontalLayout.setObjectName("horizontalLayout") + self.label_track_duration_diff = QtWidgets.QLabel(self.groupBox) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_track_duration_diff.sizePolicy().hasHeightForWidth()) + self.label_track_duration_diff.setSizePolicy(sizePolicy) + self.label_track_duration_diff.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.label_track_duration_diff.setObjectName("label_track_duration_diff") + self.horizontalLayout.addWidget(self.label_track_duration_diff) + self.ignore_track_duration_difference_under = QtWidgets.QSpinBox(self.groupBox) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.ignore_track_duration_difference_under.sizePolicy().hasHeightForWidth()) + self.ignore_track_duration_difference_under.setSizePolicy(sizePolicy) + self.ignore_track_duration_difference_under.setButtonSymbols(QtWidgets.QAbstractSpinBox.UpDownArrows) + self.ignore_track_duration_difference_under.setAccelerated(True) + self.ignore_track_duration_difference_under.setSuffix("") + self.ignore_track_duration_difference_under.setMinimum(1) + self.ignore_track_duration_difference_under.setMaximum(7200) + self.ignore_track_duration_difference_under.setProperty("value", 2) + self.ignore_track_duration_difference_under.setObjectName("ignore_track_duration_difference_under") + self.horizontalLayout.addWidget(self.ignore_track_duration_difference_under) + spacerItem = QtWidgets.QSpacerItem(4000, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.horizontalLayout.addItem(spacerItem) + self.gridlayout.addLayout(self.horizontalLayout, 6, 0, 2, 1) + self.label_ignore_regex = QtWidgets.QLabel(self.groupBox) + self.label_ignore_regex.setObjectName("label_ignore_regex") + self.gridlayout.addWidget(self.label_ignore_regex, 1, 0, 1, 1) self.regex_error = QtWidgets.QLabel(self.groupBox) self.regex_error.setText("") self.regex_error.setObjectName("regex_error") self.gridlayout.addWidget(self.regex_error, 3, 0, 1, 1) - self.label_ignore_regex = QtWidgets.QLabel(self.groupBox) - self.label_ignore_regex.setObjectName("label_ignore_regex") - self.gridlayout.addWidget(self.label_ignore_regex, 1, 0, 1, 1) self.ignore_hidden_files = QtWidgets.QCheckBox(self.groupBox) self.ignore_hidden_files.setObjectName("ignore_hidden_files") self.gridlayout.addWidget(self.ignore_hidden_files, 4, 0, 1, 1) self.ignore_regex = QtWidgets.QLineEdit(self.groupBox) self.ignore_regex.setObjectName("ignore_regex") self.gridlayout.addWidget(self.ignore_regex, 2, 0, 1, 1) - self.recursively_add_files = QtWidgets.QCheckBox(self.groupBox) - self.recursively_add_files.setObjectName("recursively_add_files") - self.gridlayout.addWidget(self.recursively_add_files, 5, 0, 1, 1) self.vboxlayout.addWidget(self.groupBox) self.groupBox_completeness = QtWidgets.QGroupBox(AdvancedOptionsPage) self.groupBox_completeness.setObjectName("groupBox_completeness") @@ -51,18 +80,26 @@ class Ui_AdvancedOptionsPage(object): self.completeness_ignore_silence.setObjectName("completeness_ignore_silence") self.verticalLayout_2.addWidget(self.completeness_ignore_silence) self.vboxlayout.addWidget(self.groupBox_completeness) - spacerItem = QtWidgets.QSpacerItem(181, 21, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.vboxlayout.addItem(spacerItem) + spacerItem1 = QtWidgets.QSpacerItem(181, 21, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + self.vboxlayout.addItem(spacerItem1) self.retranslateUi(AdvancedOptionsPage) QtCore.QMetaObject.connectSlotsByName(AdvancedOptionsPage) + AdvancedOptionsPage.setTabOrder(self.ignore_regex, self.ignore_hidden_files) + AdvancedOptionsPage.setTabOrder(self.ignore_hidden_files, self.recursively_add_files) + AdvancedOptionsPage.setTabOrder(self.recursively_add_files, self.ignore_track_duration_difference_under) + AdvancedOptionsPage.setTabOrder(self.ignore_track_duration_difference_under, self.completeness_ignore_videos) + AdvancedOptionsPage.setTabOrder(self.completeness_ignore_videos, self.completeness_ignore_pregap) + AdvancedOptionsPage.setTabOrder(self.completeness_ignore_pregap, self.completeness_ignore_data) + AdvancedOptionsPage.setTabOrder(self.completeness_ignore_data, self.completeness_ignore_silence) def retranslateUi(self, AdvancedOptionsPage): _translate = QtCore.QCoreApplication.translate self.groupBox.setTitle(_("Advanced options")) + self.recursively_add_files.setText(_("Recursively add files and folders from directory")) + self.label_track_duration_diff.setText(_("Ignore track duration difference under this number of seconds")) self.label_ignore_regex.setText(_("Ignore file paths matching the following regular expression:")) self.ignore_hidden_files.setText(_("Ignore hidden files")) - self.recursively_add_files.setText(_("Recursively add files and folders from directory")) self.groupBox_completeness.setTitle(_("Ignore the following tracks when determining whether a release is complete")) self.completeness_ignore_videos.setText(_("Video tracks")) self.completeness_ignore_pregap.setText(_("Pregap tracks")) diff --git a/ui/options_advanced.ui b/ui/options_advanced.ui index 2438d0f95..7c146efd0 100644 --- a/ui/options_advanced.ui +++ b/ui/options_advanced.ui @@ -20,13 +20,80 @@ 2 - - + + - + Recursively add files and folders from directory + + + + QLayout::SetDefaultConstraint + + + + + + 0 + 0 + + + + Ignore track duration difference under this number of seconds + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + QAbstractSpinBox::UpDownArrows + + + true + + + + + + 1 + + + 7200 + + + 2 + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 4000 + 20 + + + + + + @@ -34,6 +101,13 @@ + + + + + + + @@ -44,13 +118,6 @@ - - - - Recursively add files and folders from directory - - - @@ -111,6 +178,13 @@ ignore_regex + ignore_hidden_files + recursively_add_files + ignore_track_duration_difference_under + completeness_ignore_videos + completeness_ignore_pregap + completeness_ignore_data + completeness_ignore_silence