Skip to content

Commit

Permalink
Support showing unsupported fields when displaying tag info
Browse files Browse the repository at this point in the history
  • Loading branch information
Martchus committed May 12, 2018
1 parent 3148873 commit 4edeaa1
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 35 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ set(META_APP_DESCRIPTION "A tageditor with Qt GUI and command line interface. Su
set(META_GUI_OPTIONAL true)
set(META_JS_SRC_DIR renamingutility)
set(META_VERSION_MAJOR 3)
set(META_VERSION_MINOR 0)
set(META_VERSION_PATCH 1)
set(META_VERSION_MINOR 1)
set(META_VERSION_PATCH 0)

# add project files
set(HEADER_FILES
Expand Down
6 changes: 4 additions & 2 deletions application/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,10 @@ int main(int argc, char *argv[])
fieldsArg.setImplicit(true);
OperationArgument displayTagInfoArg("get", 'g', "displays the values of all specified tag fields (displays all fields if none specified)",
PROJECT_NAME " get title album artist -f /some/dir/*.m4a");
displayTagInfoArg.setCallback(std::bind(Cli::displayTagInfo, std::cref(fieldsArg), std::cref(filesArg), std::cref(verboseArg)));
displayTagInfoArg.setSubArguments({ &fieldsArg, &filesArg, &verboseArg });
ConfigValueArgument showUnsupportedArg("show-unsupported", 'u', "shows unsupported fields (has only effect when no field names specified)");
displayTagInfoArg.setCallback(
std::bind(Cli::displayTagInfo, std::cref(fieldsArg), std::cref(showUnsupportedArg), std::cref(filesArg), std::cref(verboseArg)));
displayTagInfoArg.setSubArguments({ &fieldsArg, &showUnsupportedArg, &filesArg, &verboseArg });
// set tag info
Cli::SetTagInfoArgs setTagInfoArgs(filesArg, verboseArg);
// extract cover
Expand Down
59 changes: 52 additions & 7 deletions cli/helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,11 +213,27 @@ void printFieldName(const char *fieldName, size_t fieldNameLen)
{
cout << " " << fieldName;
// also write padding
if (fieldNameLen >= 18) {
// write at least one space
cout << ' ';
return;
}
for (auto i = fieldNameLen; i < 18; ++i) {
cout << ' ';
}
}

void printTagValue(const TagValue &value)
{
try {
cout << value.toString(TagTextEncoding::Utf8);
} catch (const ConversionException &) {
// handle case when value can not be displayed as string
cout << "can't display as string (see --extract)";
}
cout << '\n';
}

void printField(const FieldScope &scope, const Tag *tag, TagType tagType, bool skipEmpty)
{
// write field name
Expand All @@ -243,13 +259,7 @@ void printField(const FieldScope &scope, const Tag *tag, TagType tagType, bool s
// print values
for (const auto &value : values) {
printFieldName(fieldName, fieldNameLen);
try {
cout << value->toString(TagTextEncoding::Utf8);
} catch (const ConversionException &) {
// handle case when value can not be displayed as string
cout << "can't display as string (see --extract)";
}
cout << '\n';
printTagValue(*value);
}

} catch (const ConversionException &e) {
Expand All @@ -259,6 +269,41 @@ void printField(const FieldScope &scope, const Tag *tag, TagType tagType, bool s
}
}

template <typename ConcreteTag> void printNativeFields(const Tag *tag)
{
const auto *const concreteTag = static_cast<const ConcreteTag *>(tag);
for (const auto &field : concreteTag->fields()) {
// skip all fields which are supported anyways
if (concreteTag->knownField(field.first) != KnownField::Invalid) {
continue;
}

const auto fieldId(ConcreteTag::FieldType::fieldIdToString(field.first));
printFieldName(fieldId.data(), fieldId.size());
printTagValue(field.second.value());
}
}

void printNativeFields(const Tag *tag)
{
switch (tag->type()) {
case TagType::Id3v2Tag:
printNativeFields<Id3v2Tag>(tag);
break;
case TagType::Mp4Tag:
printNativeFields<Mp4Tag>(tag);
break;
case TagType::MatroskaTag:
printNativeFields<MatroskaTag>(tag);
break;
case TagType::VorbisComment:
case TagType::OggVorbisComment:
printNativeFields<VorbisComment>(tag);
break;
default:;
}
}

TimeSpanOutputFormat parseTimeSpanOutputFormat(const Argument &timeSpanFormatArg, TimeSpanOutputFormat defaultFormat)
{
if (timeSpanFormatArg.isPresent()) {
Expand Down
3 changes: 2 additions & 1 deletion cli/helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ inline void printProperty(
}
}

template <typename NumberType, Traits::EnableIfAny<std::is_integral<NumberType>, std::is_floating_point<NumberType>>* = nullptr>
template <typename NumberType, Traits::EnableIfAny<std::is_integral<NumberType>, std::is_floating_point<NumberType>> * = nullptr>
inline void printProperty(
const char *propName, const NumberType value, const char *suffix = nullptr, bool force = false, ApplicationUtilities::Indentation indentation = 4)
{
Expand All @@ -289,6 +289,7 @@ inline void printProperty(
}

void printField(const FieldScope &scope, const Tag *tag, TagType tagType, bool skipEmpty);
void printNativeFields(const Tag *tag);

ChronoUtilities::TimeSpanOutputFormat parseTimeSpanOutputFormat(
const ApplicationUtilities::Argument &usageArg, ChronoUtilities::TimeSpanOutputFormat defaultFormat);
Expand Down
45 changes: 24 additions & 21 deletions cli/mainfeatures.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ void displayFileInfo(const ArgumentOccurrence &, const Argument &filesArg, const
}
}

void displayTagInfo(const Argument &fieldsArg, const Argument &filesArg, const Argument &verboseArg)
void displayTagInfo(const Argument &fieldsArg, const Argument &showUnsupportedArg, const Argument &filesArg, const Argument &verboseArg)
{
CMD_UTILS_START_CONSOLE;

Expand All @@ -325,29 +325,32 @@ void displayTagInfo(const Argument &fieldsArg, const Argument &filesArg, const A
fileInfo.parseTags(diag);
cout << "Tag information for \"" << file << "\":\n";
const auto tags = fileInfo.tags();
if (!tags.empty()) {
// iterate through all tags
for (const auto *tag : tags) {
// determine tag type
const TagType tagType = tag->type();
// write tag name and target, eg. MP4/iTunes tag
cout << " - " << TextAttribute::Bold << tagName(tag) << TextAttribute::Reset << '\n';
// iterate through fields specified by the user
if (fields.empty()) {
for (auto field = firstKnownField; field != KnownField::Invalid; field = nextKnownField(field)) {
printField(FieldScope(field), tag, tagType, true);
}
} else {
for (const auto &fieldDenotation : fields) {
const FieldScope &denotedScope = fieldDenotation.first;
if (denotedScope.tagType == TagType::Unspecified || (denotedScope.tagType | tagType) != TagType::Unspecified) {
printField(denotedScope, tag, tagType, false);
}
if (tags.empty()) {
cout << " - File has no (supported) tag information.\n";
continue;
}
// iterate through all tags
for (const auto *tag : tags) {
// determine tag type
const TagType tagType = tag->type();
// write tag name and target, eg. MP4/iTunes tag
cout << " - " << TextAttribute::Bold << tagName(tag) << TextAttribute::Reset << '\n';
// iterate through fields specified by the user
if (fields.empty()) {
for (auto field = firstKnownField; field != KnownField::Invalid; field = nextKnownField(field)) {
printField(FieldScope(field), tag, tagType, true);
}
if (showUnsupportedArg.isPresent()) {
printNativeFields(tag);
}
} else {
for (const auto &fieldDenotation : fields) {
const FieldScope &denotedScope = fieldDenotation.first;
if (denotedScope.tagType == TagType::Unspecified || (denotedScope.tagType | tagType) != TagType::Unspecified) {
printField(denotedScope, tag, tagType, false);
}
}
}
} else {
cout << " - File has no (supported) tag information.\n";
}
} catch (const TagParser::Failure &) {
cerr << Phrases::Error << "A parsing failure occured when reading the file \"" << file << "\"." << Phrases::EndFlush;
Expand Down
4 changes: 2 additions & 2 deletions cli/mainfeatures.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ void displayFileInfo(const ApplicationUtilities::ArgumentOccurrence &, const App
const ApplicationUtilities::Argument &verboseArg);
void generateFileInfo(const ApplicationUtilities::ArgumentOccurrence &, const ApplicationUtilities::Argument &inputFileArg,
const ApplicationUtilities::Argument &outputFileArg, const ApplicationUtilities::Argument &validateArg);
void displayTagInfo(const ApplicationUtilities::Argument &fieldsArg, const ApplicationUtilities::Argument &filesArg,
const ApplicationUtilities::Argument &verboseArg);
void displayTagInfo(const ApplicationUtilities::Argument &fieldsArg, const ApplicationUtilities::Argument &showUnsupportedArg,
const ApplicationUtilities::Argument &filesArg, const ApplicationUtilities::Argument &verboseArg);
void setTagInfo(const Cli::SetTagInfoArgs &args);
void extractField(const ApplicationUtilities::Argument &fieldArg, const ApplicationUtilities::Argument &attachmentArg,
const ApplicationUtilities::Argument &inputFilesArg, const ApplicationUtilities::Argument &outputFileArg,
Expand Down

0 comments on commit 4edeaa1

Please sign in to comment.