From 22aa2f0851e4e75166568983f1dcec74ef99e9fe Mon Sep 17 00:00:00 2001 From: Martchus Date: Tue, 27 Feb 2024 02:58:47 +0100 Subject: [PATCH] Handle TRACKTOTAL/DISCTOTAL/PARTTOTAL fields in Vorbis Comments See the corresponding tagparser commit --- application/main.cpp | 6 +++++- application/settings.cpp | 2 ++ application/settings.h | 1 + cli/mainfeatures.cpp | 6 +++++- cli/mainfeatures.h | 1 + gui/settingsdialog.cpp | 2 ++ gui/tageditorwidget.cpp | 16 ++++++++++------ gui/tagprocessinggeneraloptionpage.ui | 10 ++++++++++ 8 files changed, 36 insertions(+), 8 deletions(-) diff --git a/application/main.cpp b/application/main.cpp index 579f993..8f56bb2 100644 --- a/application/main.cpp +++ b/application/main.cpp @@ -85,6 +85,9 @@ SetTagInfoArgs::SetTagInfoArgs(Argument &filesArg, Argument &verboseArg, Argumen , preserveModificationTimeArg("preserve-modification-time", '\0', "preserves the file's modification time") , preserveMuxingAppArg("preserve-muxing-app", '\0', "preserves the file's muxing app meta-data value") , preserveWritingAppArg("preserve-writing-app", '\0', "preserves the file's writing app meta-data value") + , preserveTotalFieldsArg("preserve-total-fields", '\0', + "preserves the TRACKTOTAL/DISCTOTAL/PARTTOTAL fields in Vorbis Comments (which are otherwise automatically included into the " + "TRACKNUMBER/DISCNUMBER/PARTNUMBER fields)") , jsArg("script", 'j', "modifies tag fields via the specified JavaScript", { "path" }) , jsSettingsArg("script-settings", '\0', "passes settings to the JavaScript specified via --script", { "key=value" }) , setTagInfoArg("set", 's', "sets the specified tag information and attachments") @@ -142,7 +145,8 @@ SetTagInfoArgs::SetTagInfoArgs(Argument &filesArg, Argument &verboseArg, Argumen &id3v2UsageArg, &id3InitOnCreateArg, &id3TransferOnRemovalArg, &mergeMultipleSuccessiveTagsArg, &id3v2VersionArg, &encodingArg, &removeTargetArg, &addAttachmentArg, &updateAttachmentArg, &removeAttachmentArg, &removeExistingAttachmentsArg, &minPaddingArg, &maxPaddingArg, &prefPaddingArg, &tagPosArg, &indexPosArg, &forceRewriteArg, &backupDirArg, &layoutOnlyArg, &preserveModificationTimeArg, - &preserveMuxingAppArg, &preserveWritingAppArg, &jsArg, &jsSettingsArg, &verboseArg, &pedanticArg, &quietArg, &outputFilesArg }); + &preserveMuxingAppArg, &preserveWritingAppArg, &preserveTotalFieldsArg, &jsArg, &jsSettingsArg, &verboseArg, &pedanticArg, &quietArg, + &outputFilesArg }); } } // namespace Cli diff --git a/application/settings.cpp b/application/settings.cpp index 9ae8443..9c6aa5e 100644 --- a/application/settings.cpp +++ b/application/settings.cpp @@ -131,6 +131,7 @@ void restore() = settings.value(QStringLiteral("preservemodificationtime"), v.tagPocessing.preserveModificationTime).toBool(); v.tagPocessing.preserveMuxingApp = settings.value(QStringLiteral("preservemuxingapp"), v.tagPocessing.preserveMuxingApp).toBool(); v.tagPocessing.preserveWritingApp = settings.value(QStringLiteral("preservewritingapp"), v.tagPocessing.preserveWritingApp).toBool(); + v.tagPocessing.convertTotalFields = settings.value(QStringLiteral("converttotalfields"), v.tagPocessing.convertTotalFields).toBool(); settings.beginGroup(QStringLiteral("id3v1")); switch (settings.value(QStringLiteral("usage"), 0).toInt()) { case 1: @@ -270,6 +271,7 @@ void save() settings.setValue(QStringLiteral("preservemodificationtime"), v.tagPocessing.preserveModificationTime); settings.setValue(QStringLiteral("preservemuxingapp"), v.tagPocessing.preserveMuxingApp); settings.setValue(QStringLiteral("preservewritingapp"), v.tagPocessing.preserveWritingApp); + settings.setValue(QStringLiteral("converttotalfields"), v.tagPocessing.convertTotalFields); settings.beginGroup(QStringLiteral("id3v1")); settings.setValue(QStringLiteral("usage"), static_cast(v.tagPocessing.creationSettings.id3v1usage)); settings.endGroup(); diff --git a/application/settings.h b/application/settings.h index f3530a7..5a3c833 100644 --- a/application/settings.h +++ b/application/settings.h @@ -82,6 +82,7 @@ struct TagProcessing { bool preserveModificationTime = false; bool preserveMuxingApp = false; bool preserveWritingApp = false; + bool convertTotalFields = true; TagParser::TagCreationSettings creationSettings; FileLayout fileLayout; }; diff --git a/cli/mainfeatures.cpp b/cli/mainfeatures.cpp index f0f076a..a9fd5e1 100644 --- a/cli/mainfeatures.cpp +++ b/cli/mainfeatures.cpp @@ -391,7 +391,8 @@ void displayTagInfo( // parse specified fields const auto fields = parseFieldDenotations(fieldsArg, true); - MediaFileInfo fileInfo; + auto fileInfo = MediaFileInfo(); + fileInfo.setFileHandlingFlags(fileInfo.fileHandlingFlags() | MediaFileHandlingFlags::ConvertTotalFields); for (const char *file : filesArg.values()) { Diagnostics diag; AbortableProgressFeedback progress; // FIXME: actually use the progress object @@ -709,6 +710,9 @@ void setTagInfo(const SetTagInfoArgs &args) if (args.preserveWritingAppArg.isPresent()) { fileInfo.setFileHandlingFlags(fileInfo.fileHandlingFlags() | MediaFileHandlingFlags::PreserveWritingApplication); } + if (!args.preserveTotalFieldsArg.isPresent()) { + fileInfo.setFileHandlingFlags(fileInfo.fileHandlingFlags() | MediaFileHandlingFlags::ConvertTotalFields); + } // set backup path if (args.backupDirArg.isPresent()) { diff --git a/cli/mainfeatures.h b/cli/mainfeatures.h index 22b41ab..ebbd725 100644 --- a/cli/mainfeatures.h +++ b/cli/mainfeatures.h @@ -50,6 +50,7 @@ struct SetTagInfoArgs { CppUtilities::ConfigValueArgument preserveModificationTimeArg; CppUtilities::ConfigValueArgument preserveMuxingAppArg; CppUtilities::ConfigValueArgument preserveWritingAppArg; + CppUtilities::ConfigValueArgument preserveTotalFieldsArg; CppUtilities::ConfigValueArgument jsArg; CppUtilities::ConfigValueArgument jsSettingsArg; CppUtilities::OperationArgument setTagInfoArg; diff --git a/gui/settingsdialog.cpp b/gui/settingsdialog.cpp index 359dad8..288ccb3 100644 --- a/gui/settingsdialog.cpp +++ b/gui/settingsdialog.cpp @@ -360,6 +360,7 @@ bool TagProcessingGeneralOptionPage::apply() settings.preserveModificationTime = ui()->preserveModificationTimeCheckBox->isChecked(); settings.preserveMuxingApp = ui()->preserveMuxingAppCheckBox->isChecked(); settings.preserveWritingApp = ui()->preserveWritingAppCheckBox->isChecked(); + settings.convertTotalFields = ui()->convertTotalFieldsCheckBox->isChecked(); } return true; } @@ -397,6 +398,7 @@ void TagProcessingGeneralOptionPage::reset() ui()->preserveModificationTimeCheckBox->setChecked(settings.preserveModificationTime); ui()->preserveMuxingAppCheckBox->setChecked(settings.preserveMuxingApp); ui()->preserveWritingAppCheckBox->setChecked(settings.preserveWritingApp); + ui()->convertTotalFieldsCheckBox->setChecked(settings.convertTotalFields); } } diff --git a/gui/tageditorwidget.cpp b/gui/tageditorwidget.cpp index 3b4bbd3..7937962 100644 --- a/gui/tageditorwidget.cpp +++ b/gui/tageditorwidget.cpp @@ -835,6 +835,11 @@ bool TagEditorWidget::startParsing(const QString &path, bool forceRefresh) m_currentDir = fileInfo.absolutePath(); m_fileName = fileInfo.fileName(); } + // set flags that are also important when parsing + auto &generalSettings = Settings::values().tagPocessing; + auto flags = m_fileInfo.fileHandlingFlags(); + CppUtilities::modFlagEnum(flags, MediaFileHandlingFlags::ConvertTotalFields, generalSettings.convertTotalFields); + m_fileInfo.setFileHandlingFlags(flags); // write diagnostics to m_diagReparsing if making results are available m_makingResultsAvailable &= sameFile; Diagnostics &diag = m_makingResultsAvailable ? m_diagReparsing : m_diag; @@ -1166,12 +1171,11 @@ bool TagEditorWidget::startSaving() m_fileInfo.setMaxPadding(fileLayoutSettings.maxPadding); m_fileInfo.setPreferredPadding(fileLayoutSettings.preferredPadding); m_fileInfo.setBackupDirectory(settings.editor.backupDirectory); - if (generalSettings.preserveMuxingApp) { - m_fileInfo.setFileHandlingFlags(m_fileInfo.fileHandlingFlags() | MediaFileHandlingFlags::PreserveMuxingApplication); - } - if (generalSettings.preserveWritingApp) { - m_fileInfo.setFileHandlingFlags(m_fileInfo.fileHandlingFlags() | MediaFileHandlingFlags::PreserveWritingApplication); - } + auto flags = m_fileInfo.fileHandlingFlags(); + CppUtilities::modFlagEnum(flags, MediaFileHandlingFlags::PreserveMuxingApplication, generalSettings.preserveMuxingApp); + CppUtilities::modFlagEnum(flags, MediaFileHandlingFlags::PreserveWritingApplication, generalSettings.preserveWritingApp); + CppUtilities::modFlagEnum(flags, MediaFileHandlingFlags::ConvertTotalFields, generalSettings.convertTotalFields); + m_fileInfo.setFileHandlingFlags(flags); const auto startThread = [this, preserveModificationTime = settings.tagPocessing.preserveModificationTime] { // define functions to show the saving progress and to actually applying the changes auto showPercentage([this](AbortableProgressFeedback &progress) { diff --git a/gui/tagprocessinggeneraloptionpage.ui b/gui/tagprocessinggeneraloptionpage.ui index 02645b7..71c1590 100644 --- a/gui/tagprocessinggeneraloptionpage.ui +++ b/gui/tagprocessinggeneraloptionpage.ui @@ -159,6 +159,16 @@ + + + + Ensures fields usually holding values like "3/15" such as the track position are actually stored as such (and <i>not</i> as two separate fields for the position and total values). This is required for the tag editor to support handling such separately stored total values at all. So far this only affects Vorbis Comments where it will convert the fields TRACKTOTAL/DISCTOTAL/PARTTOTAL to be included in the TRACKNUMBER/DISCNUMBER/PARTNUMBER fields. + + + Convert total fields (see tooltip for details) + + +