Compare commits
24 Commits
Author | SHA1 | Date |
---|---|---|
Martchus | 12620c5768 | |
Martchus | 854bd13efc | |
Martchus | 22aa2f0851 | |
Martchus | abc80c24ff | |
Martchus | 6e66b6aa0b | |
Martchus | 934b955837 | |
Martchus | 959b0f0032 | |
Martchus | d8f542d3e4 | |
Martchus | a8281f323a | |
Martchus | b3f576a354 | |
Martchus | c26d3e7be8 | |
Martchus | 63ec653df5 | |
Martchus | 2cd47777a3 | |
Martchus | 88989ff986 | |
Martchus | e1e979f9f5 | |
Martchus | 04bd9563c0 | |
Martchus | dd0bbd74c5 | |
Martchus | f82bf04c66 | |
Martchus | a87e431e04 | |
Martchus | 72dcbbbd81 | |
Martchus | b5f9158106 | |
Martchus | f1b785337d | |
Martchus | 09e2fe20f7 | |
Martchus | c7df780281 |
|
@ -14,7 +14,7 @@ set(META_GUI_OPTIONAL true)
|
|||
set(META_JS_SRC_DIR renamingutility)
|
||||
set(META_VERSION_MAJOR 3)
|
||||
set(META_VERSION_MINOR 9)
|
||||
set(META_VERSION_PATCH 0)
|
||||
set(META_VERSION_PATCH 1)
|
||||
set(META_RELEASE_DATE "2023-09-05")
|
||||
set(META_ADD_DEFAULT_CPP_UNIT_TEST_APPLICATION ON)
|
||||
|
||||
|
@ -204,7 +204,7 @@ if (WIDGETS_GUI OR QUICK_GUI)
|
|||
endif ()
|
||||
|
||||
# find tagparser
|
||||
find_package(tagparser${CONFIGURATION_PACKAGE_SUFFIX} 12.1.0 REQUIRED)
|
||||
find_package(tagparser${CONFIGURATION_PACKAGE_SUFFIX} 12.2.0 REQUIRED)
|
||||
use_tag_parser()
|
||||
|
||||
# enable experimental JSON export
|
||||
|
|
52
README.md
52
README.md
|
@ -93,6 +93,19 @@ much as possible, set the following in the GUI's "File layout" settings:
|
|||
When using the CLI, you just need to add `--max-padding 429496729` to the CLI arguments (and avoid any of the other
|
||||
arguments mentioned in previous sections).
|
||||
|
||||
### Improve performance
|
||||
Editing big files (especially Matroska files) can take some time. To improve the performance, put the index at the
|
||||
end of the file (CLI option `--index-pos back`) because then the size of the index will never have to be recalculated.
|
||||
Also follow the advice from the "Backup/temporary files" section to force rewriting and to put the temporary directory
|
||||
on the same filesystem as the file you are editing. Forcing a rewrite can improve the performance because then the tag
|
||||
editor will not even try to see whether it could be avoided and can thus skip computations that can take a notable
|
||||
time for big Matroska files.
|
||||
|
||||
Of course being able to avoid a rewrite would still be more optimal. Checkout the previous section for how to achieve
|
||||
that. To improve performance further when avoiding a rewrite, put the tag at the end (CLI option `--tag-pos back`).
|
||||
Then the tag editor will not even try to put tags at the front and can thus skip a few computations. (Avoiding a
|
||||
rewrite is still not a good idea in general.)
|
||||
|
||||
## Download
|
||||
### Source
|
||||
See the release section on GitHub.
|
||||
|
@ -129,12 +142,19 @@ See the release section on GitHub.
|
|||
the package `libopengl0` is installed on Debian/Ubuntu)
|
||||
* Supports X11 and Wayland (set the environment variable `QT_QPA_PLATFORM=xcb` to disable
|
||||
native Wayland support if it does not work on your system)
|
||||
* Binaries are signed with the GPG key
|
||||
[`B9E36A7275FC61B464B67907E06FE8F53CDC6A4C`](https://keyserver.ubuntu.com/pks/lookup?search=B9E36A7275FC61B464B67907E06FE8F53CDC6A4C&fingerprint=on&op=index).
|
||||
* Windows
|
||||
* for binaries checkout the [release section on GitHub](https://github.com/Martchus/tageditor/releases)
|
||||
* Windows SmartScreen will likely block the execution (you'll get a window saying "Windows protected your PC");
|
||||
right click on the executable, select properties and tick the checkbox to allow the execution
|
||||
* the Qt 6 based version is stable and preferable but only supports Windows 10 and newer
|
||||
* Antivirus software often **wrongly** considers the executable harmful. This is a known problem. Please don't create
|
||||
issues about it.
|
||||
* the Qt 6 based version is stable and preferable but only supports Windows 10 version 1809 and newer
|
||||
* the Qt 5 based version should still work on older versions down to Windows 7 although this is not regularly checked
|
||||
* Binaries are signed with the GPG key
|
||||
[`B9E36A7275FC61B464B67907E06FE8F53CDC6A4C`](https://keyserver.ubuntu.com/pks/lookup?search=B9E36A7275FC61B464B67907E06FE8F53CDC6A4C&fingerprint=on&op=index).
|
||||
* there is also a [Chocolatey package](https://community.chocolatey.org/packages/tageditor) maintained by bcurran3
|
||||
* for mingw-w64 PKGBUILDs checkout [my GitHub repository](https://github.com/Martchus/PKGBUILDs)
|
||||
|
||||
## Usage
|
||||
|
@ -353,12 +373,14 @@ Here are some Bash examples which illustrate getting and setting tag information
|
|||
- The script needs to be ECMAScript as supported by the Qt framework.
|
||||
- This feature requires the tag editor to be configured with Qt QML as JavaScript provider at
|
||||
compile time. Checkout the build instructions under "Building with Qt GUI" for details.
|
||||
- The script needs to export a `main()` function. This function gets executed for every file and
|
||||
passed an object representing this file as first argument.
|
||||
- The script needs to export a `main()` function. This function is invoked for every file and
|
||||
passed an object representing the current file as first argument.
|
||||
- Checkout the file `testfiles/set-tags.js` in this repository for an example that applies basic
|
||||
fixes and tries to fetch lyrics and cover art.
|
||||
- The option `--pedantic debug` is not required but useful for debugging. You may also add
|
||||
`--script-settings dryRun=1` and use that setting within the script as shown in the example.
|
||||
fixes and tries to fetch lyrics and cover art when according settings are passed (e.g.
|
||||
`--script-settings addCover=1 addLyrics=1`).
|
||||
- For debugging, the option `--pedantic debug` is very useful. You may also add
|
||||
`--script-settings dryRun=1` and check for that setting within the script as shown in the
|
||||
mentioned example script.
|
||||
- Common tag fields are exposed as object properties as shown in the mentioned example.
|
||||
- Only properties for fields that are supported by the tag are added to the "fields" object.
|
||||
- Adding properties of unsupported fields manually does not work; those will just be ignored.
|
||||
|
@ -378,6 +400,16 @@ Here are some Bash examples which illustrate getting and setting tag information
|
|||
- The script is executed before any other modifications are applied. So if you also specify
|
||||
values as usual (via `--values`) then these values have precedence over values set by the
|
||||
script.
|
||||
- It is also possible to rename the file (via e.g. `file.rename(newPath)`). This will be done
|
||||
immediately and also if `main()` returns a falsy value (so it is possible to only rename a
|
||||
file without modifying it by returning a falsy value). If the specified path is relative, it
|
||||
is interpreted relative to current directory of the file (and *not* to the current working
|
||||
directory of the tag editor).
|
||||
- It is also possible to open another file via `utility.openFile(path)`. This makes it possible
|
||||
to copy tags over from another file, e.g. to insert tags back from original files that have
|
||||
been lost when converting to a different format. The mentioned example script `set-tags.js`
|
||||
also demonstrates this for covers and lyrics when according script settings are passed (e.g.
|
||||
`--script-settings addCover=1 originalDir=… originalExt=…`).
|
||||
|
||||
##### Further useful commands
|
||||
* Let the tag editor return with a non-zero exit code even if only non-fatal problems have been encountered
|
||||
|
@ -521,11 +553,13 @@ by selecting the Fusion style.
|
|||
|
||||
---
|
||||
|
||||
Per monitor DPI awareness (v2) is not working out of the box but experimental support
|
||||
[can be enabled](https://github.com/Martchus/syncthingtray#enable-experimental-support-for-windows-per-monitor-dpi-awareness-v2).
|
||||
Tag Editor supports
|
||||
[PMv2](https://docs.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows#per-monitor-and-per-monitor-v2-dpi-awareness)
|
||||
out of the box as of Qt 6. You may tweak settings according to the
|
||||
[Qt documentation](https://doc.qt.io/qt-6/highdpi.html#configuring-windows).
|
||||
|
||||
## Copyright notice and license
|
||||
Copyright © 2015-2023 Marius Kittler
|
||||
Copyright © 2015-2024 Marius Kittler
|
||||
|
||||
All code is licensed under [GPL-2-or-later](LICENSE).
|
||||
|
||||
|
|
|
@ -209,6 +209,8 @@ const char *KnownFieldModel::fieldName(KnownField field)
|
|||
return QT_TR_NOOP("License");
|
||||
case KnownField::TermsOfUse:
|
||||
return QT_TR_NOOP("Terms of use");
|
||||
case KnownField::PublisherWebpage:
|
||||
return QT_TR_NOOP("Publisher webpage");
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
@ -327,6 +329,7 @@ KnownFieldModel::KnownFieldModel(QObject *parent, DefaultSelection defaultSelect
|
|||
mkItem(KnownField::ProductionCopyright, Qt::Unchecked),
|
||||
mkItem(KnownField::License, Qt::Unchecked),
|
||||
mkItem(KnownField::TermsOfUse, Qt::Unchecked),
|
||||
mkItem(KnownField::PublisherWebpage, Qt::Unchecked),
|
||||
});
|
||||
// clang-format on
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<int>(v.tagPocessing.creationSettings.id3v1usage));
|
||||
settings.endGroup();
|
||||
|
|
|
@ -82,6 +82,7 @@ struct TagProcessing {
|
|||
bool preserveModificationTime = false;
|
||||
bool preserveMuxingApp = false;
|
||||
bool preserveWritingApp = false;
|
||||
bool convertTotalFields = true;
|
||||
TagParser::TagCreationSettings creationSettings;
|
||||
FileLayout fileLayout;
|
||||
};
|
||||
|
|
|
@ -8,7 +8,7 @@ using namespace TagParser;
|
|||
namespace Cli {
|
||||
namespace FieldMapping {
|
||||
|
||||
static constexpr auto fieldMapping = std::array<Mapping, 99>{ {
|
||||
static constexpr auto fieldMapping = MappingType{ {
|
||||
{ "Title", KnownField::Title },
|
||||
{ "Album", KnownField::Album },
|
||||
{ "Artist", KnownField::Artist },
|
||||
|
@ -108,6 +108,7 @@ static constexpr auto fieldMapping = std::array<Mapping, 99>{ {
|
|||
{ "ProductionCopyright", KnownField::ProductionCopyright },
|
||||
{ "License", KnownField::License },
|
||||
{ "TermsOfUse", KnownField::TermsOfUse },
|
||||
{ "PublisherWebpage", KnownField::PublisherWebpage },
|
||||
} };
|
||||
|
||||
const char *fieldDenotation(TagParser::KnownField knownField)
|
||||
|
@ -142,7 +143,7 @@ TagParser::KnownField knownField(const char *fieldDenotation, std::size_t fieldD
|
|||
return KnownField::Invalid;
|
||||
}
|
||||
|
||||
const std::array<Mapping, 99> &mapping()
|
||||
const MappingType &mapping()
|
||||
{
|
||||
return fieldMapping;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,8 @@ struct Mapping {
|
|||
|
||||
const char *fieldDenotation(TagParser::KnownField knownField);
|
||||
TagParser::KnownField knownField(const char *fieldDenotation, std::size_t fieldDenotationSize);
|
||||
const std::array<Mapping, 99> &mapping();
|
||||
using MappingType = std::array<Mapping, 100>;
|
||||
const MappingType &mapping();
|
||||
|
||||
} // namespace FieldMapping
|
||||
} // namespace Cli
|
||||
|
|
|
@ -102,7 +102,7 @@ namespace Cli {
|
|||
" purchasingdate recordinglocation compositionlocation composernationality\n" \
|
||||
" playcounter measure tuning isrc mcdi isbn barcode catalognumber labelcode\n" \
|
||||
" lccn imdb tmdb tvdb purchaseitem purchaseinfo purchaseowner purchaseprice\n" \
|
||||
" purchasecurrency copyright productioncopyright license termsofuse"
|
||||
" purchasecurrency copyright productioncopyright license termsofuse publisherwebpage"
|
||||
|
||||
#define TRACK_ATTRIBUTE_NAMES "name tracknumber enabled=yes enabled=no forced=yes forced=no default=yes default=no"
|
||||
|
||||
|
@ -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
|
||||
|
@ -494,6 +495,7 @@ public:
|
|||
private:
|
||||
static void addWarnings(Diagnostics &diag, const std::string &context, const QList<QQmlError> &warnings);
|
||||
|
||||
const SetTagInfoArgs &args;
|
||||
int argc;
|
||||
QCoreApplication app;
|
||||
Diagnostics diag;
|
||||
|
@ -510,7 +512,8 @@ private:
|
|||
* - Logs status/problems directly in accordance with other parts of the CLI.
|
||||
*/
|
||||
JavaScriptProcessor::JavaScriptProcessor(const SetTagInfoArgs &args)
|
||||
: argc(0)
|
||||
: args(args)
|
||||
, argc(0)
|
||||
, app(argc, nullptr)
|
||||
, utility(new UtilityObject(&engine))
|
||||
{
|
||||
|
@ -567,7 +570,7 @@ JavaScriptProcessor::JavaScriptProcessor(const SetTagInfoArgs &args)
|
|||
*/
|
||||
QJSValue JavaScriptProcessor::callMain(MediaFileInfo &mediaFileInfo, Diagnostics &diag)
|
||||
{
|
||||
auto fileInfoObject = MediaFileInfoObject(mediaFileInfo, diag, &engine);
|
||||
auto fileInfoObject = MediaFileInfoObject(mediaFileInfo, diag, &engine, args.quietArg.isPresent());
|
||||
auto fileInfoObjectValue = engine.newQObject(&fileInfoObject);
|
||||
auto context = argsToString("executing JavaScript for ", mediaFileInfo.fileName());
|
||||
utility->setDiag(&context, &diag);
|
||||
|
@ -707,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()) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -20,6 +20,9 @@
|
|||
|
||||
#include <c++utilities/conversion/binaryconversion.h>
|
||||
#include <c++utilities/conversion/conversionexception.h>
|
||||
#include <c++utilities/conversion/stringbuilder.h>
|
||||
#include <c++utilities/io/path.h>
|
||||
#include <c++utilities/tests/testutils.h>
|
||||
|
||||
#include <qtutilities/misc/compat.h>
|
||||
|
||||
|
@ -33,6 +36,7 @@
|
|||
#include <QJSValueIterator>
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
@ -56,6 +60,8 @@ constexpr auto nativeUtf16Encoding = TagParser::TagTextEncoding::
|
|||
#endif
|
||||
;
|
||||
|
||||
const std::string UtilityObject::s_defaultContext = std::string("executing JavaScript");
|
||||
|
||||
UtilityObject::UtilityObject(QJSEngine *engine)
|
||||
: QObject(engine)
|
||||
, m_engine(engine)
|
||||
|
@ -83,9 +89,8 @@ void UtilityObject::diag(const QString &level, const QString &message, const QSt
|
|||
{ QStringLiteral("information"), TagParser::DiagLevel::Information },
|
||||
{ QStringLiteral("debug"), TagParser::DiagLevel::Debug },
|
||||
});
|
||||
static const auto defaultContext = std::string("executing JavaScript");
|
||||
m_diag->emplace_back(mapping.value(level.toLower(), TagParser::DiagLevel::Debug), message.toStdString(),
|
||||
context.isEmpty() ? (m_context ? *m_context : defaultContext) : context.toStdString());
|
||||
context.isEmpty() ? (m_context ? *m_context : s_defaultContext) : context.toStdString());
|
||||
}
|
||||
|
||||
int UtilityObject::exec()
|
||||
|
@ -124,6 +129,65 @@ QJSValue UtilityObject::readFile(const QString &path)
|
|||
return QJSValue();
|
||||
}
|
||||
|
||||
QJSValue UtilityObject::openFile(const QString &path)
|
||||
{
|
||||
if (!m_diag) {
|
||||
return QJSValue();
|
||||
}
|
||||
auto mediaFileInfo = std::make_unique<TagParser::MediaFileInfo>(path.toStdString());
|
||||
auto feedback = TagParser::AbortableProgressFeedback();
|
||||
try {
|
||||
mediaFileInfo->open(true);
|
||||
mediaFileInfo->parseEverything(*m_diag, feedback);
|
||||
} catch (const std::exception &e) {
|
||||
m_diag->emplace_back(TagParser::DiagLevel::Critical, CppUtilities::argsToString("Unable to open \"", mediaFileInfo->path(), "\": ", e.what()),
|
||||
m_context ? *m_context : s_defaultContext);
|
||||
return QJSValue();
|
||||
}
|
||||
auto mediaFileInfoObj = new MediaFileInfoObject(std::move(mediaFileInfo), *m_diag, m_engine, false, m_engine);
|
||||
return m_engine->newQObject(mediaFileInfoObj);
|
||||
}
|
||||
|
||||
QJSValue UtilityObject::runProcess(const QString &path, const QJSValue &args, int timeout)
|
||||
{
|
||||
auto res = m_engine->newObject();
|
||||
#ifdef CPP_UTILITIES_HAS_EXEC_APP
|
||||
auto pathUtf8 = path.toUtf8();
|
||||
auto argsUtf8 = QByteArrayList();
|
||||
auto argsUtf8Array = std::vector<const char *>();
|
||||
if (args.isArray()) {
|
||||
const auto size = args.property(QStringLiteral("length")).toUInt();
|
||||
argsUtf8.reserve(size);
|
||||
argsUtf8Array.reserve(static_cast<std::size_t>(size) + 2);
|
||||
for (auto i = quint32(); i != size; ++i) {
|
||||
argsUtf8.append(args.property(i).toString().toUtf8());
|
||||
}
|
||||
}
|
||||
argsUtf8Array.emplace_back(pathUtf8.data());
|
||||
for (const auto &argUtf8 : argsUtf8) {
|
||||
argsUtf8Array.emplace_back(argUtf8.data());
|
||||
}
|
||||
argsUtf8Array.emplace_back(nullptr);
|
||||
auto output = std::string(), errors = std::string();
|
||||
try {
|
||||
auto exitStatus = CppUtilities::execHelperAppInSearchPath(pathUtf8.data(), argsUtf8Array.data(), output, errors, false, timeout);
|
||||
#ifndef CPP_UTILITIES_BOOST_PROCESS
|
||||
if (WIFEXITED(exitStatus)) {
|
||||
exitStatus = WEXITSTATUS(exitStatus);
|
||||
res.setProperty(QStringLiteral("status"), exitStatus);
|
||||
}
|
||||
#else
|
||||
res.setProperty(QStringLiteral("status"), exitStatus);
|
||||
#endif
|
||||
} catch (const std::runtime_error &e) {
|
||||
res.setProperty(QStringLiteral("error"), QString::fromUtf8(e.what()));
|
||||
}
|
||||
res.setProperty(QStringLiteral("stdout"), QString::fromStdString(output));
|
||||
res.setProperty(QStringLiteral("stderr"), QString::fromStdString(errors));
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
QString UtilityObject::formatName(const QString &str) const
|
||||
{
|
||||
return Utility::formatName(str);
|
||||
|
@ -558,14 +622,23 @@ void TagObject::applyChanges()
|
|||
}
|
||||
}
|
||||
|
||||
MediaFileInfoObject::MediaFileInfoObject(TagParser::MediaFileInfo &mediaFileInfo, TagParser::Diagnostics &diag, QJSEngine *engine, QObject *parent)
|
||||
MediaFileInfoObject::MediaFileInfoObject(
|
||||
TagParser::MediaFileInfo &mediaFileInfo, TagParser::Diagnostics &diag, QJSEngine *engine, bool quiet, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_f(mediaFileInfo)
|
||||
, m_diag(diag)
|
||||
, m_engine(engine)
|
||||
, m_quiet(quiet)
|
||||
{
|
||||
}
|
||||
|
||||
MediaFileInfoObject::MediaFileInfoObject(
|
||||
std::unique_ptr<TagParser::MediaFileInfo> &&mediaFileInfo, TagParser::Diagnostics &diag, QJSEngine *engine, bool quiet, QObject *parent)
|
||||
: MediaFileInfoObject(*mediaFileInfo.get(), diag, engine, quiet, parent)
|
||||
{
|
||||
m_f_owned = std::move(mediaFileInfo);
|
||||
}
|
||||
|
||||
MediaFileInfoObject::~MediaFileInfoObject()
|
||||
{
|
||||
}
|
||||
|
@ -575,11 +648,21 @@ QString MediaFileInfoObject::path() const
|
|||
return QString::fromStdString(m_f.path());
|
||||
}
|
||||
|
||||
bool MediaFileInfoObject::isPathRelative() const
|
||||
{
|
||||
return QFileInfo(path()).isRelative();
|
||||
}
|
||||
|
||||
QString MediaFileInfoObject::name() const
|
||||
{
|
||||
return QString::fromStdString(m_f.fileName());
|
||||
}
|
||||
|
||||
QString MediaFileInfoObject::nameWithoutExtension() const
|
||||
{
|
||||
return QString::fromStdString(m_f.fileName(true));
|
||||
}
|
||||
|
||||
QString MediaFileInfoObject::extension() const
|
||||
{
|
||||
return QString::fromStdString(m_f.extension());
|
||||
|
@ -621,4 +704,27 @@ void MediaFileInfoObject::applyChanges()
|
|||
}
|
||||
}
|
||||
|
||||
bool MediaFileInfoObject::rename(const QString &newPath)
|
||||
{
|
||||
const auto from = m_f.path();
|
||||
const auto fromNative = std::filesystem::path(CppUtilities::makeNativePath(from));
|
||||
const auto toRelUtf8 = newPath.toUtf8();
|
||||
const auto toRelView = CppUtilities::PathStringView(toRelUtf8.data(), static_cast<std::size_t>(toRelUtf8.size()));
|
||||
const auto toNative = fromNative.parent_path().append(CppUtilities::makeNativePath(toRelView));
|
||||
const auto toView = CppUtilities::extractNativePath(toNative.native());
|
||||
try {
|
||||
m_f.stream().close();
|
||||
std::filesystem::rename(fromNative, toNative);
|
||||
m_f.reportPathChanged(toView);
|
||||
m_f.stream().open(m_f.path(), std::ios_base::in | std::ios_base::out | std::ios_base::binary);
|
||||
} catch (const std::runtime_error &e) {
|
||||
m_diag.emplace_back(TagParser::DiagLevel::Critical, e.what(), CppUtilities::argsToString("renaming \"", from, "\" to \"", toView));
|
||||
return false;
|
||||
}
|
||||
if (!m_quiet) {
|
||||
std::cout << " - Renamed \"" << from << "\" to \"" << toView << "\"\n";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Cli
|
||||
|
|
|
@ -54,6 +54,8 @@ public Q_SLOTS:
|
|||
QJSValue readEnvironmentVariable(const QString &variable, const QJSValue &defaultValue = QJSValue()) const;
|
||||
QJSValue readDirectory(const QString &path);
|
||||
QJSValue readFile(const QString &path);
|
||||
QJSValue openFile(const QString &path);
|
||||
QJSValue runProcess(const QString &path, const QJSValue &args, int timeout = -1);
|
||||
|
||||
QString formatName(const QString &str) const;
|
||||
QString fixUmlauts(const QString &str) const;
|
||||
|
@ -63,13 +65,14 @@ public Q_SLOTS:
|
|||
QJSValue queryMakeItPersonal(const QJSValue &songDescription);
|
||||
QJSValue queryTekstowo(const QJSValue &songDescription);
|
||||
|
||||
QByteArray convertImage(const QByteArray &imageData, const QSize &maxSize, const QString &format);
|
||||
QByteArray convertImage(const QByteArray &imageData, const QSize &maxSize, const QString &format = QString());
|
||||
|
||||
private:
|
||||
static QtGui::SongDescription makeSongDescription(const QJSValue &obj);
|
||||
|
||||
QJSEngine *m_engine;
|
||||
const std::string *m_context;
|
||||
static const std::string s_defaultContext;
|
||||
TagParser::Diagnostics *m_diag;
|
||||
};
|
||||
|
||||
|
@ -186,19 +189,26 @@ inline TagParser::Tag &TagObject::tag()
|
|||
class MediaFileInfoObject : public QObject {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString path READ path)
|
||||
Q_PROPERTY(bool pathRelative READ isPathRelative)
|
||||
Q_PROPERTY(QString name READ name)
|
||||
Q_PROPERTY(QString nameWithoutExtension READ nameWithoutExtension)
|
||||
Q_PROPERTY(QString extension READ extension)
|
||||
Q_PROPERTY(QString containingDirectory READ containingDirectory)
|
||||
Q_PROPERTY(QString savePath READ savePath WRITE setSavePath)
|
||||
Q_PROPERTY(QList<TagObject *> tags READ tags)
|
||||
|
||||
public:
|
||||
explicit MediaFileInfoObject(TagParser::MediaFileInfo &mediaFileInfo, TagParser::Diagnostics &diag, QJSEngine *engine, QObject *parent = nullptr);
|
||||
explicit MediaFileInfoObject(
|
||||
TagParser::MediaFileInfo &mediaFileInfo, TagParser::Diagnostics &diag, QJSEngine *engine, bool quiet, QObject *parent = nullptr);
|
||||
explicit MediaFileInfoObject(std::unique_ptr<TagParser::MediaFileInfo> &&mediaFileInfo, TagParser::Diagnostics &diag, QJSEngine *engine,
|
||||
bool quiet, QObject *parent = nullptr);
|
||||
~MediaFileInfoObject() override;
|
||||
|
||||
TagParser::MediaFileInfo &fileInfo();
|
||||
QString path() const;
|
||||
bool isPathRelative() const;
|
||||
QString name() const;
|
||||
QString nameWithoutExtension() const;
|
||||
QString extension() const;
|
||||
QString containingDirectory() const;
|
||||
QString savePath() const;
|
||||
|
@ -207,12 +217,15 @@ public:
|
|||
|
||||
public Q_SLOTS:
|
||||
void applyChanges();
|
||||
bool rename(const QString &newPath);
|
||||
|
||||
private:
|
||||
TagParser::MediaFileInfo &m_f;
|
||||
std::unique_ptr<TagParser::MediaFileInfo> m_f_owned;
|
||||
TagParser::Diagnostics &m_diag;
|
||||
QJSEngine *m_engine;
|
||||
QList<TagObject *> m_tags;
|
||||
bool m_quiet;
|
||||
};
|
||||
|
||||
inline TagParser::MediaFileInfo &MediaFileInfoObject::fileInfo()
|
||||
|
|
|
@ -73,6 +73,13 @@
|
|||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>addPushButton</tabstop>
|
||||
<tabstop>extractPushButton</tabstop>
|
||||
<tabstop>restorePushButton</tabstop>
|
||||
<tabstop>clearPushButton</tabstop>
|
||||
<tabstop>treeView</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
|
@ -382,6 +382,19 @@
|
|||
<header location="global">qtutilities/widgets/clearspinbox.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>abortPushButton</tabstop>
|
||||
<tabstop>searchPushButton</tabstop>
|
||||
<tabstop>applyPushButton</tabstop>
|
||||
<tabstop>trackSpinBox</tabstop>
|
||||
<tabstop>titleLineEdit</tabstop>
|
||||
<tabstop>albumLineEdit</tabstop>
|
||||
<tabstop>artistLineEdit</tabstop>
|
||||
<tabstop>fieldsListView</tabstop>
|
||||
<tabstop>overrideCheckBox</tabstop>
|
||||
<tabstop>autoInsertCheckBox</tabstop>
|
||||
<tabstop>resultsTreeView</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
|
@ -160,6 +160,16 @@
|
|||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>insertTitleFromFilenameCheckBox</tabstop>
|
||||
<tabstop>trimWhitespacesCheckBox</tabstop>
|
||||
<tabstop>formatNamesCheckBox</tabstop>
|
||||
<tabstop>fixUmlautsCheckBox</tabstop>
|
||||
<tabstop>customSubstitutionGroupBox</tabstop>
|
||||
<tabstop>regularExpressionLineEdit</tabstop>
|
||||
<tabstop>replacementLineEdit</tabstop>
|
||||
<tabstop>fieldsListView</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
|
@ -60,6 +60,11 @@
|
|||
<header location="global">qtutilities/widgets/clearlineedit.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>musicBrainzUrlLineEdit</tabstop>
|
||||
<tabstop>lyricWikiUrlLineEdit</tabstop>
|
||||
<tabstop>coverArtArchiveUrlLineEdit</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
|
@ -189,7 +189,17 @@
|
|||
<extends>QLineEdit</extends>
|
||||
<header location="global">qtutilities/widgets/clearlineedit.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>levelSpinBox</tabstop>
|
||||
<tabstop>levelNameLineEdit</tabstop>
|
||||
<tabstop>tracksListView</tabstop>
|
||||
<tabstop>chaptersListView</tabstop>
|
||||
<tabstop>editionsListView</tabstop>
|
||||
<tabstop>attachmentsListView</tabstop>
|
||||
<tabstop>abortPushButton</tabstop>
|
||||
<tabstop>confirmPushButton</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
|
@ -239,6 +239,20 @@ another position would prevent rewriting the entire file</string>
|
|||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>forceRewriteCheckBox</tabstop>
|
||||
<tabstop>minPaddingSpinBox</tabstop>
|
||||
<tabstop>maxPaddingSpinBox</tabstop>
|
||||
<tabstop>preferredPaddingSpinBox</tabstop>
|
||||
<tabstop>tagPosBeforeDataRadioButton</tabstop>
|
||||
<tabstop>tagPosAfterDataRadioButton</tabstop>
|
||||
<tabstop>tagPosKeepRadioButton</tabstop>
|
||||
<tabstop>tagPosForceCheckBox</tabstop>
|
||||
<tabstop>indexPosBeforeDataRadioButton</tabstop>
|
||||
<tabstop>indexPosAfterDataRadioButton</tabstop>
|
||||
<tabstop>indexPosKeepRadioButton</tabstop>
|
||||
<tabstop>indexPosForceCheckBox</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
|
@ -169,6 +169,14 @@
|
|||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>widthSpinBox</tabstop>
|
||||
<tabstop>heightSpinBox</tabstop>
|
||||
<tabstop>formatComboBox</tabstop>
|
||||
<tabstop>aspectRatioComboBox</tabstop>
|
||||
<tabstop>abortPushButton</tabstop>
|
||||
<tabstop>confirmPushButton</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
|
@ -7,12 +7,13 @@
|
|||
#include "resources/config.h"
|
||||
#include "resources/qtconfig.h"
|
||||
|
||||
#include <QApplication> // ensure QGuiApplication is defined before resources.h for desktop file name
|
||||
|
||||
#include <qtutilities/resources/importplugin.h>
|
||||
#include <qtutilities/resources/qtconfigarguments.h>
|
||||
#include <qtutilities/resources/resources.h>
|
||||
#include <qtutilities/settingsdialog/qtsettings.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMessageBox>
|
||||
|
||||
ENABLE_QT_RESOURCES_OF_STATIC_DEPENDENCIES
|
||||
|
|
|
@ -755,6 +755,19 @@
|
|||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>includeSubdirsCheckBox</tabstop>
|
||||
<tabstop>pasteScriptPushButton</tabstop>
|
||||
<tabstop>toggleScriptSourcePushButton</tabstop>
|
||||
<tabstop>javaScriptPlainTextEdit</tabstop>
|
||||
<tabstop>currentTreeView</tabstop>
|
||||
<tabstop>previewTreeView</tabstop>
|
||||
<tabstop>abortClosePushButton</tabstop>
|
||||
<tabstop>generatePreviewPushButton</tabstop>
|
||||
<tabstop>applyChangingsPushButton</tabstop>
|
||||
<tabstop>scriptFilePathLineEdit</tabstop>
|
||||
<tabstop>selectScriptFilePushButton</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="../resources/icons.qrc"/>
|
||||
</resources>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -450,6 +450,7 @@ currently shown tag.</string>
|
|||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>renamePushButton</tabstop>
|
||||
<tabstop>tagSelectionComboBox</tabstop>
|
||||
<tabstop>keepPreviousValuesPushButton</tabstop>
|
||||
<tabstop>tagOptionsPushButton</tabstop>
|
||||
|
|
|
@ -159,6 +159,16 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="convertTotalFieldsCheckBox">
|
||||
<property name="toolTip">
|
||||
<string>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.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Convert total fields (see tooltip for details)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -137,7 +137,7 @@ if (fileInfo.currentSuffix === "tmp") {
|
|||
var fields = []
|
||||
|
||||
// get the artist (preferably album artist), remove invalid characters and add it to fields array
|
||||
var artist = validFileName(tag.albumartist || tag.artist)
|
||||
var artist = validFileName(tag.albumArtist || tag.artist)
|
||||
if (includeArtist && !isPartOfCollection(tag) && notEmpty(artist)) {
|
||||
fields.push(trailingBracketsStripped(firstValue(artist)))
|
||||
}
|
||||
|
@ -219,7 +219,7 @@ if (distDir) {
|
|||
} else if (tag.comment.includes("single")) {
|
||||
path.push("singles");
|
||||
}
|
||||
var artist = validDirectoryName(firstValue(tag.albumartist || tag.artist))
|
||||
var artist = validDirectoryName(firstValue(tag.albumArtist || tag.artist))
|
||||
if (isPartOfCollection(tag)) {
|
||||
path.push(collectionsDir)
|
||||
} else if (notEmpty(artist) && !isMiscFile(tag)) {
|
||||
|
|
|
@ -22,7 +22,7 @@ if (!fileInfo.hasAudioTracks && !fileInfo.hasVideoTracks) {
|
|||
}
|
||||
|
||||
// make new filename
|
||||
const fieldsToInclude = [tag.albumartist || tag.artist, tag.album, tag.trackPos || infoFromFileName.trackPos, tag.title || infoFromFileName.title]
|
||||
const fieldsToInclude = [tag.albumArtist || tag.artist, tag.album, tag.trackPos || infoFromFileName.trackPos, tag.title || infoFromFileName.title]
|
||||
let newName = ""
|
||||
for (let field of fieldsToInclude) {
|
||||
field = field.toString()
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
const fileCache = {};
|
||||
|
||||
export function isString(value) {
|
||||
return typeof(value) === "string" || value instanceof String;
|
||||
}
|
||||
|
@ -13,10 +15,49 @@ export function logTagInfo(file, tag) {
|
|||
utility.diag("debug", Object.keys(fields).sort().join(", "), "supported fields");
|
||||
|
||||
// log fields for debugging purposes
|
||||
for (const [key, value] of Object.entries(fields)) {
|
||||
const content = value.content;
|
||||
if (content !== undefined && content != null && !(content instanceof ArrayBuffer)) {
|
||||
utility.diag("debug", content, key + " (" + value.type + ")");
|
||||
for (const [key, values] of Object.entries(fields)) {
|
||||
for (const value of values) {
|
||||
const content = value.content;
|
||||
if (content !== undefined && content !== null && !(content instanceof ArrayBuffer)) {
|
||||
utility.diag("debug", content, key + " (" + value.type + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function readFieldContents(file, fieldName) {
|
||||
const values = [];
|
||||
for (const tag of file.tags) {
|
||||
if (tag.type === "ID3v1 tag") {
|
||||
// due to its limitations ID3v1 tags may have truncated contents; so just ignore them
|
||||
// for the sake of this script
|
||||
continue;
|
||||
}
|
||||
for (const value of tag.fields[fieldName]) {
|
||||
const content = value.content;
|
||||
if (content !== undefined && content !== null) {
|
||||
values.push(content);
|
||||
}
|
||||
}
|
||||
if (values.length) {
|
||||
// just return the contents from the first tag that has any for now
|
||||
break;
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
export function cacheValue(cache, key, generator) {
|
||||
const cachedValue = cache[key];
|
||||
return cachedValue ? cachedValue : (cache[key] = generator());
|
||||
}
|
||||
|
||||
export function openOriginalFile(file) {
|
||||
const originalDir = settings.originalDir;
|
||||
const originalExt = settings.originalExt || file.extension;
|
||||
if (originalDir && file.pathRelative) {
|
||||
const name = file.nameWithoutExtension;
|
||||
const path = [originalDir, file.containingDirectory, name + originalExt].join("/");
|
||||
return cacheValue(fileCache, path, () => utility.openFile(path));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,26 +1,23 @@
|
|||
import * as helpers from "helpers.js"
|
||||
|
||||
const lyricsCache = {};
|
||||
const coverCache = {};
|
||||
const albumColumn = 1;
|
||||
|
||||
export function queryLyrics(searchCriteria) {
|
||||
return cacheValue(lyricsCache, searchCriteria.title + "_" + searchCriteria.artist, () => {
|
||||
return helpers.cacheValue(lyricsCache, searchCriteria.title + "_" + searchCriteria.artist, () => {
|
||||
utility.log(" - Querying lyrics for '" + searchCriteria.title + "' from '" + searchCriteria.artist + "' ...");
|
||||
return queryLyricsFromProviders(["Tekstowo", "MakeItPersonal"], searchCriteria)
|
||||
});
|
||||
}
|
||||
|
||||
export function queryCover(searchCriteria) {
|
||||
return cacheValue(coverCache, searchCriteria.album + "_" + searchCriteria.artist, () => {
|
||||
return helpers.cacheValue(coverCache, searchCriteria.album + "_" + searchCriteria.artist, () => {
|
||||
utility.log(" - Querying cover art for '" + searchCriteria.album + "' from '" + searchCriteria.artist + "' ...");
|
||||
return queryCoverFromProvider("MusicBrainz", searchCriteria);
|
||||
});
|
||||
}
|
||||
|
||||
function cacheValue(cache, key, generator) {
|
||||
const cachedValue = cache[key];
|
||||
return cachedValue ? cachedValue : (cache[key] = generator());
|
||||
}
|
||||
|
||||
function waitFor(signal) {
|
||||
signal.connect(() => { utility.exit(); });
|
||||
utility.exec();
|
||||
|
|
|
@ -57,11 +57,29 @@ function addTotalNumberOfTracks(file, tag) {
|
|||
}
|
||||
}
|
||||
|
||||
function addFieldFromOriginalFile(file, tag, fieldName) {
|
||||
const originalFile = helpers.openOriginalFile(file);
|
||||
if (!originalFile) {
|
||||
return false;
|
||||
}
|
||||
utility.diag("debug", "Trying to take over " + fieldName + " from \"" + originalFile.path + "\".");
|
||||
const contents = helpers.readFieldContents(originalFile, fieldName);
|
||||
if (!contents.length) {
|
||||
utility.diag("debug", "No " + fieldName + " found in original file.");
|
||||
return false;
|
||||
}
|
||||
tag.fields[fieldName] = contents;
|
||||
return true;
|
||||
}
|
||||
|
||||
function addLyrics(file, tag) {
|
||||
const fields = tag.fields;
|
||||
if (fields.lyrics.length) {
|
||||
return; // skip if already assigned
|
||||
}
|
||||
if (addFieldFromOriginalFile(file, tag, "lyrics")) {
|
||||
return; // skip fetching via meta-data search if lyrics could be taken over from original file
|
||||
}
|
||||
const firstTitle = fields.title?.[0]?.content;
|
||||
const firstArtist = fields.artist?.[0]?.content;
|
||||
if (firstTitle && firstArtist) {
|
||||
|
@ -74,6 +92,17 @@ function addCover(file, tag) {
|
|||
if (fields.cover.length) {
|
||||
return; // skip if already assigned
|
||||
}
|
||||
if (addFieldFromOriginalFile(file, tag, "cover")) {
|
||||
// ensure the cover's resolution is below a certain size to avoid bloating the file
|
||||
const convertedCovers = [];
|
||||
const maxSizeInt = parseInt(settings.coverMaxSize || 512);
|
||||
const maxSize = Qt.size(maxSizeInt, maxSizeInt);
|
||||
for (const cover of fields.cover) {
|
||||
convertedCovers.push(utility.convertImage(cover, maxSize));
|
||||
}
|
||||
fields.cover = convertedCovers;
|
||||
return; // skip fetching via meta-data search if cover could be taken over from original file
|
||||
}
|
||||
const firstAlbum = fields.album?.[0]?.content?.replace(/ \(.*\)/, '');
|
||||
const firstArtist = fields.artist?.[0]?.content;
|
||||
if (firstAlbum && firstArtist) {
|
||||
|
|
|
@ -1164,12 +1164,12 @@ void CliTests::testJsonExport()
|
|||
cout << "\nJSON export" << endl;
|
||||
string stdout, stderr;
|
||||
|
||||
const auto file(testFilePath("matroska_wave1/test3.mkv"));
|
||||
const auto expectedJsonPath(testFilePath("matroska_wave1-test3.json"));
|
||||
const auto file = testFilePath("matroska_wave1/test3.mkv");
|
||||
const auto expectedJson = readFile(testFilePath("matroska_wave1-test3.json"));
|
||||
const char *const args[] = { "tageditor", "export", "--pretty", "-f", file.data(), nullptr };
|
||||
TESTUTILS_ASSERT_EXEC(args);
|
||||
const char *const jqArgs[]
|
||||
= { "jq", "--argfile", "expected", expectedJsonPath.data(), "--argjson", "actual", stdout.data(), "-n", "$actual == $expected", nullptr };
|
||||
= { "jq", "--argjson", "expected", expectedJson.data(), "--argjson", "actual", stdout.data(), "-n", "$actual == $expected", nullptr };
|
||||
const auto *const logJsonExport = std::getenv(PROJECT_VARNAME_UPPER "_LOG_JQ_INVOCATION");
|
||||
execHelperAppInSearchPath("jq", jqArgs, stdout, stderr, !logJsonExport || !std::strlen(logJsonExport));
|
||||
CPPUNIT_ASSERT_EQUAL(""s, stderr);
|
||||
|
|
|
@ -1787,12 +1787,12 @@ another position would prevent rewriting the entire file</source>
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/settingsdialog.cpp" line="571"/>
|
||||
<location filename="../gui/settingsdialog.cpp" line="573"/>
|
||||
<source>Minimum padding must be less or equal than maximum padding.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/settingsdialog.cpp" line="637"/>
|
||||
<location filename="../gui/settingsdialog.cpp" line="639"/>
|
||||
<source>These options might be ignored if not supported by either the format or the implementation.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -2934,17 +2934,17 @@ Error in line %1: %3</source>
|
|||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/settingsdialog.cpp" line="658"/>
|
||||
<location filename="../gui/settingsdialog.cpp" line="660"/>
|
||||
<source>Tag processing</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/settingsdialog.cpp" line="665"/>
|
||||
<location filename="../gui/settingsdialog.cpp" line="667"/>
|
||||
<source>Editor</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/settingsdialog.cpp" line="673"/>
|
||||
<location filename="../gui/settingsdialog.cpp" line="675"/>
|
||||
<source>File browser</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -3040,7 +3040,7 @@ currently shown tag.</source>
|
|||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.ui" line="323"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1341"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1345"/>
|
||||
<source>Abort</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -3202,123 +3202,123 @@ currently shown tag.</source>
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="895"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="900"/>
|
||||
<source>Unable to reload the file because the current process hasn't finished yet.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="899"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="904"/>
|
||||
<source>Currently is not file opened.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="921"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="926"/>
|
||||
<source>Opening file - </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="934"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="939"/>
|
||||
<source>There is no (supported) tag assigned.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="950"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="955"/>
|
||||
<source>File could be parsed correctly.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="954"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="959"/>
|
||||
<source>File couldn't be parsed correctly.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="963"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="968"/>
|
||||
<source>There are warnings.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="967"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="972"/>
|
||||
<source>No write access; the file has been opened in read-only mode.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="970"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="975"/>
|
||||
<source>File format is not supported (an ID3 tag can be added anyways).</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="974"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="979"/>
|
||||
<source>The file is composed of multiple segments. Dealing with such files has not been tested yet and might be broken.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1013"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1018"/>
|
||||
<source>The file %1 has been opened.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1033"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1038"/>
|
||||
<source>Unable to apply the entered tags to the file because the current process hasn't finished yet.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1043"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1048"/>
|
||||
<source>No file has been opened, so tags can not be saved.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1060"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1065"/>
|
||||
<source>Saving tags ...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1075"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1080"/>
|
||||
<source>Unable to delete all tags from the file because the current process hasn't been finished yet.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1085"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1090"/>
|
||||
<source>No file has been opened, so no tags can be deleted.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1089"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1094"/>
|
||||
<source>The selected file has no tag (at least no supported), so there is nothing to delete.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1094"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1099"/>
|
||||
<source>Do you really want to delete all tags from the file?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1103"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1108"/>
|
||||
<source>Don't show this message again</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1113"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1118"/>
|
||||
<source>Deletion aborted.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1124"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1129"/>
|
||||
<source>Deleting all tags ...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1141"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1146"/>
|
||||
<source>Unable to start saving process because there an other process hasn't finished yet.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="870"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1212"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="875"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1216"/>
|
||||
<source>unknown error</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1271"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1275"/>
|
||||
<source>Saving has been canceled and there is/are %1 warning(s) </source>
|
||||
<translation type="unfinished">
|
||||
<numerusform></numerusform>
|
||||
|
@ -3326,7 +3326,7 @@ currently shown tag.</source>
|
|||
</translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1274"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1278"/>
|
||||
<source>Saving has been canceled and there is/are %1 warning(s).</source>
|
||||
<translation type="unfinished">
|
||||
<numerusform></numerusform>
|
||||
|
@ -3334,7 +3334,7 @@ currently shown tag.</source>
|
|||
</translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1282"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1286"/>
|
||||
<source>The tags have been saved, but there is/are %1 warning(s) </source>
|
||||
<translation type="unfinished">
|
||||
<numerusform></numerusform>
|
||||
|
@ -3342,8 +3342,8 @@ currently shown tag.</source>
|
|||
</translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1272"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1283"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1276"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1287"/>
|
||||
<source>and %1 error(s).</source>
|
||||
<translation type="unfinished">
|
||||
<numerusform></numerusform>
|
||||
|
@ -3351,32 +3351,32 @@ currently shown tag.</source>
|
|||
</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="881"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="886"/>
|
||||
<source>The file is being parsed ...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="917"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="922"/>
|
||||
<source>The file could not be opened because an IO error occurred: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="923"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="928"/>
|
||||
<source>Tried to open file: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="959"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="964"/>
|
||||
<source>Errors occurred.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1276"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1280"/>
|
||||
<source>Saving tags has been canceled.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1285"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1289"/>
|
||||
<source>The tags have been saved, but there is/are %1 warning(s).</source>
|
||||
<translation type="unfinished">
|
||||
<numerusform></numerusform>
|
||||
|
@ -3384,133 +3384,133 @@ currently shown tag.</source>
|
|||
</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1290"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1294"/>
|
||||
<source>The tags have been saved.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1309"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1313"/>
|
||||
<source>The tags could not be saved. Checkout the info box for details.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1315"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1319"/>
|
||||
<source>Saving file - </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1317"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1321"/>
|
||||
<source>Tried to save file: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1336"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1340"/>
|
||||
<source>Automatic tag management</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1337"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1341"/>
|
||||
<source>The container format of the selected file is not supported. The file can be treated as MP3 file (an ID3 tag according to the settings will be created). This might break the file. Do you want to continue?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1340"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1344"/>
|
||||
<source>Treat file as MP3 file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1352"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1356"/>
|
||||
<source>The currently opened file changed on the disk.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1365"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1369"/>
|
||||
<source>Unable to close the file because the current process hasn't been finished yet.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1377"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1381"/>
|
||||
<source>Closing file - </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1378"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1382"/>
|
||||
<source>Unable to close file: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1379"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1383"/>
|
||||
<source>Tried to close file: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1386"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1390"/>
|
||||
<source>The file has been closed.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1393"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1397"/>
|
||||
<source>Unable to rename the file because the current process hasn't been finished yet.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1399"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1403"/>
|
||||
<source>Renaming file - </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1400"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1404"/>
|
||||
<source>New file name:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1435"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1439"/>
|
||||
<source>Unable to rename file: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1436"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1440"/>
|
||||
<source>Tried to rename file: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1443"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1447"/>
|
||||
<source>The file has been renamed.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1450"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1454"/>
|
||||
<source>Unable to save file information because the current process hasn't been finished yet.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1454"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1458"/>
|
||||
<source>No file is opened.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1459"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1463"/>
|
||||
<source>No file information available.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1468"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1472"/>
|
||||
<source>Unable to open file "%1".</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1476"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1480"/>
|
||||
<source>Unable to write to file "%1".
|
||||
%2</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1491"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1495"/>
|
||||
<source>Save file information - </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1493"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1497"/>
|
||||
<source>Unable to open file.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -3526,12 +3526,12 @@ currently shown tag.</source>
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1593"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1597"/>
|
||||
<source>A tag (with the selected target) already exists.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1589"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1593"/>
|
||||
<source>The tag can not be created.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -3541,42 +3541,42 @@ currently shown tag.</source>
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1310"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1314"/>
|
||||
<source>The tags could not be saved because an IO error occurred: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1579"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1583"/>
|
||||
<source>Unable to add a tag because the current process hasn't been finished yet.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1583"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1587"/>
|
||||
<source>Unable to add a tag because no file is opened.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1616"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1620"/>
|
||||
<source>Unable to remove the tag because the current process hasn't been finished yet.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1620"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1624"/>
|
||||
<source>Unable to remove the tag because no file is opened.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1680"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1684"/>
|
||||
<source>Unable to change the target because the current process hasn't been finished yet.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1684"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1688"/>
|
||||
<source>Unable to change the target because no file is opened.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1688"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1692"/>
|
||||
<source>Can not change the target of the selected tag because the tag does not support targets.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -4671,6 +4671,16 @@ currently shown tag.</source>
|
|||
<source>Preserve writing application</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tagprocessinggeneraloptionpage.ui" line="165"/>
|
||||
<source>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.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tagprocessinggeneraloptionpage.ui" line="168"/>
|
||||
<source>Convert total fields (see tooltip for details)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tagprocessinggeneraloptionpage.ui" line="119"/>
|
||||
<source>Enable automatic tag management (default)</source>
|
||||
|
@ -5375,7 +5385,12 @@ Remarks
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../application/knownfieldmodel.cpp" line="348"/>
|
||||
<location filename="../application/knownfieldmodel.cpp" line="213"/>
|
||||
<source>Publisher webpage</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../application/knownfieldmodel.cpp" line="351"/>
|
||||
<source>Field</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
|
|
@ -1838,12 +1838,12 @@ another position would prevent rewriting the entire file</source>
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/settingsdialog.cpp" line="571"/>
|
||||
<location filename="../gui/settingsdialog.cpp" line="573"/>
|
||||
<source>Minimum padding must be less or equal than maximum padding.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/settingsdialog.cpp" line="637"/>
|
||||
<location filename="../gui/settingsdialog.cpp" line="639"/>
|
||||
<source>These options might be ignored if not supported by either the format or the implementation.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -3027,17 +3027,17 @@ Error in line %1: %3</source>
|
|||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/settingsdialog.cpp" line="658"/>
|
||||
<location filename="../gui/settingsdialog.cpp" line="660"/>
|
||||
<source>Tag processing</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/settingsdialog.cpp" line="665"/>
|
||||
<location filename="../gui/settingsdialog.cpp" line="667"/>
|
||||
<source>Editor</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/settingsdialog.cpp" line="673"/>
|
||||
<location filename="../gui/settingsdialog.cpp" line="675"/>
|
||||
<source>File browser</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -3136,87 +3136,87 @@ Error in line %1: %3</source>
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="899"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="904"/>
|
||||
<source>Currently is not file opened.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="895"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="900"/>
|
||||
<source>Unable to reload the file because the current process hasn't finished yet.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="950"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="955"/>
|
||||
<source>File could be parsed correctly.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="954"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="959"/>
|
||||
<source>File couldn't be parsed correctly.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="963"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="968"/>
|
||||
<source>There are warnings.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="967"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="972"/>
|
||||
<source>No write access; the file has been opened in read-only mode.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="970"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="975"/>
|
||||
<source>File format is not supported (an ID3 tag can be added anyways).</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="974"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="979"/>
|
||||
<source>The file is composed of multiple segments. Dealing with such files has not been tested yet and might be broken.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="934"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="939"/>
|
||||
<source>There is no (supported) tag assigned.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1013"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1018"/>
|
||||
<source>The file %1 has been opened.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1060"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1065"/>
|
||||
<source>Saving tags ...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1033"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1038"/>
|
||||
<source>Unable to apply the entered tags to the file because the current process hasn't finished yet.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1094"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1099"/>
|
||||
<source>Do you really want to delete all tags from the file?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1124"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1129"/>
|
||||
<source>Deleting all tags ...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1085"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1090"/>
|
||||
<source>No file has been opened, so no tags can be deleted.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1075"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1080"/>
|
||||
<source>Unable to delete all tags from the file because the current process hasn't been finished yet.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1141"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1146"/>
|
||||
<source>Unable to start saving process because there an other process hasn't finished yet.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -3236,32 +3236,32 @@ Error in line %1: %3</source>
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="921"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="926"/>
|
||||
<source>Opening file - </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1043"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1048"/>
|
||||
<source>No file has been opened, so tags can not be saved.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1089"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1094"/>
|
||||
<source>The selected file has no tag (at least no supported), so there is nothing to delete.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1103"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1108"/>
|
||||
<source>Don't show this message again</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1113"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1118"/>
|
||||
<source>Deletion aborted.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1271"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1275"/>
|
||||
<source>Saving has been canceled and there is/are %1 warning(s) </source>
|
||||
<translation>
|
||||
<numerusform>Saving has been canceled and there is %1 warning </numerusform>
|
||||
|
@ -3269,7 +3269,7 @@ Error in line %1: %3</source>
|
|||
</translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1274"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1278"/>
|
||||
<source>Saving has been canceled and there is/are %1 warning(s).</source>
|
||||
<translation>
|
||||
<numerusform>Saving has been canceled and there is %1 warning.</numerusform>
|
||||
|
@ -3277,7 +3277,7 @@ Error in line %1: %3</source>
|
|||
</translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1282"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1286"/>
|
||||
<source>The tags have been saved, but there is/are %1 warning(s) </source>
|
||||
<translation>
|
||||
<numerusform>The tags have been saved, but there is %1 warning</numerusform>
|
||||
|
@ -3285,8 +3285,8 @@ Error in line %1: %3</source>
|
|||
</translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1272"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1283"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1276"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1287"/>
|
||||
<source>and %1 error(s).</source>
|
||||
<translation>
|
||||
<numerusform>and %1 error.</numerusform>
|
||||
|
@ -3294,38 +3294,38 @@ Error in line %1: %3</source>
|
|||
</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="870"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1212"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="875"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1216"/>
|
||||
<source>unknown error</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="881"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="886"/>
|
||||
<source>The file is being parsed ...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="917"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="922"/>
|
||||
<source>The file could not be opened because an IO error occurred: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="923"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="928"/>
|
||||
<source>Tried to open file: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="959"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="964"/>
|
||||
<source>Errors occurred.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1276"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1280"/>
|
||||
<source>Saving tags has been canceled.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1285"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1289"/>
|
||||
<source>The tags have been saved, but there is/are %1 warning(s).</source>
|
||||
<translation>
|
||||
<numerusform>The tags have been saved, but there is %1 warning.</numerusform>
|
||||
|
@ -3333,133 +3333,133 @@ Error in line %1: %3</source>
|
|||
</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1290"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1294"/>
|
||||
<source>The tags have been saved.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1309"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1313"/>
|
||||
<source>The tags could not be saved. Checkout the info box for details.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1315"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1319"/>
|
||||
<source>Saving file - </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1317"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1321"/>
|
||||
<source>Tried to save file: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1336"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1340"/>
|
||||
<source>Automatic tag management</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1337"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1341"/>
|
||||
<source>The container format of the selected file is not supported. The file can be treated as MP3 file (an ID3 tag according to the settings will be created). This might break the file. Do you want to continue?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1340"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1344"/>
|
||||
<source>Treat file as MP3 file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1352"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1356"/>
|
||||
<source>The currently opened file changed on the disk.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1365"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1369"/>
|
||||
<source>Unable to close the file because the current process hasn't been finished yet.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1377"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1381"/>
|
||||
<source>Closing file - </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1378"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1382"/>
|
||||
<source>Unable to close file: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1379"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1383"/>
|
||||
<source>Tried to close file: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1386"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1390"/>
|
||||
<source>The file has been closed.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1393"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1397"/>
|
||||
<source>Unable to rename the file because the current process hasn't been finished yet.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1399"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1403"/>
|
||||
<source>Renaming file - </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1400"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1404"/>
|
||||
<source>New file name:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1435"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1439"/>
|
||||
<source>Unable to rename file: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1436"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1440"/>
|
||||
<source>Tried to rename file: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1443"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1447"/>
|
||||
<source>The file has been renamed.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1450"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1454"/>
|
||||
<source>Unable to save file information because the current process hasn't been finished yet.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1454"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1458"/>
|
||||
<source>No file is opened.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1459"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1463"/>
|
||||
<source>No file information available.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1468"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1472"/>
|
||||
<source>Unable to open file "%1".</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1476"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1480"/>
|
||||
<source>Unable to write to file "%1".
|
||||
%2</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1491"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1495"/>
|
||||
<source>Save file information - </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1493"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1497"/>
|
||||
<source>Unable to open file.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -3475,52 +3475,52 @@ Error in line %1: %3</source>
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1593"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1597"/>
|
||||
<source>A tag (with the selected target) already exists.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1589"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1593"/>
|
||||
<source>The tag can not be created.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1620"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1624"/>
|
||||
<source>Unable to remove the tag because no file is opened.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1616"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1620"/>
|
||||
<source>Unable to remove the tag because the current process hasn't been finished yet.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1310"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1314"/>
|
||||
<source>The tags could not be saved because an IO error occurred: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1579"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1583"/>
|
||||
<source>Unable to add a tag because the current process hasn't been finished yet.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1583"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1587"/>
|
||||
<source>Unable to add a tag because no file is opened.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1684"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1688"/>
|
||||
<source>Unable to change the target because no file is opened.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1688"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1692"/>
|
||||
<source>Can not change the target of the selected tag because the tag does not support targets.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1680"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1684"/>
|
||||
<source>Unable to change the target because the current process hasn't been finished yet.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -3600,7 +3600,7 @@ currently shown tag.</source>
|
|||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tageditorwidget.ui" line="323"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1341"/>
|
||||
<location filename="../gui/tageditorwidget.cpp" line="1345"/>
|
||||
<source>Abort</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -4776,6 +4776,16 @@ currently shown tag.</source>
|
|||
<source>Preserve writing application</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tagprocessinggeneraloptionpage.ui" line="165"/>
|
||||
<source>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.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tagprocessinggeneraloptionpage.ui" line="168"/>
|
||||
<source>Convert total fields (see tooltip for details)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/tagprocessinggeneraloptionpage.ui" line="119"/>
|
||||
<source>Enable automatic tag management (default)</source>
|
||||
|
@ -5498,7 +5508,12 @@ Remarks
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../application/knownfieldmodel.cpp" line="348"/>
|
||||
<location filename="../application/knownfieldmodel.cpp" line="213"/>
|
||||
<source>Publisher webpage</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../application/knownfieldmodel.cpp" line="351"/>
|
||||
<source>Field</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
|
Loading…
Reference in New Issue