Add Tag::supportsMultipleValues()

This commit is contained in:
Martchus 2018-07-13 12:25:00 +02:00
parent 0e99bd25d1
commit 7d709ce9af
7 changed files with 107 additions and 4 deletions

View File

@ -20,6 +20,43 @@ namespace TagParser {
* \brief Implementation of TagParser::Tag for ID3v2 tags.
*/
/*!
* \brief Allows multiple values for some fields.
* \remarks The standard defines no general rule applicable to all fields.
*/
bool Id3v2Tag::supportsMultipleValues(KnownField field) const
{
switch (field) {
case KnownField::Album:
case KnownField::Artist:
case KnownField::Year:
case KnownField::RecordDate:
case KnownField::Title:
case KnownField::Genre:
case KnownField::TrackPosition:
case KnownField::DiskPosition:
case KnownField::Encoder:
case KnownField::Bpm:
case KnownField::Lyricist:
case KnownField::Length:
case KnownField::Language:
case KnownField::EncoderSettings:
case KnownField::Grouping:
case KnownField::RecordLabel:
case KnownField::Composer:
return m_majorVersion > 3;
case KnownField::Rating:
case KnownField::Comment:
case KnownField::Cover:
case KnownField::Lyrics:
case KnownField::SynchronizedLyrics:
return true;
default:
return false;
;
}
}
/*!
* \brief Works like the default implementation but adds additional values as well.
*/

View File

@ -71,6 +71,7 @@ public:
bool canEncodingBeUsed(TagTextEncoding encoding) const override;
bool supportsDescription(KnownField field) const override;
bool supportsMimeType(KnownField field) const override;
bool supportsMultipleValues(KnownField field) const override;
void parse(std::istream &sourceStream, const uint64 maximalSize, Diagnostics &diag);
Id3v2TagMaker prepareMaking(Diagnostics &diag);
@ -130,7 +131,14 @@ inline bool Id3v2Tag::canEncodingBeUsed(TagTextEncoding encoding) const
inline bool Id3v2Tag::supportsDescription(KnownField field) const
{
return field == KnownField::Cover;
switch (field) {
case KnownField::Cover:
case KnownField::Lyrics:
case KnownField::SynchronizedLyrics:
return true;
default:
return false;
}
}
inline bool Id3v2Tag::supportsMimeType(KnownField field) const

View File

@ -64,9 +64,10 @@ public:
static constexpr TagType tagType = TagType::MatroskaTag;
static constexpr const char *tagName = "Matroska tag";
static constexpr TagTextEncoding defaultTextEncoding = TagTextEncoding::Utf8;
bool canEncodingBeUsed(TagTextEncoding encoding) const;
bool supportsTarget() const;
TagTargetLevel targetLevel() const;
bool canEncodingBeUsed(TagTextEncoding encoding) const override;
bool supportsTarget() const override;
bool supportsMultipleValues(KnownField field) const override;
TagTargetLevel targetLevel() const override;
void parse(EbmlElement &tagElement, Diagnostics &diag);
MatroskaTagMaker prepareMaking(Diagnostics &diag);
@ -92,6 +93,16 @@ inline bool MatroskaTag::supportsTarget() const
return true;
}
/*!
* \brief Allows multiple values for all fields.
* \remarks "Multiple items should never be stored as a list in a single TagString. If there is
* more than one tag of a certain type to be stored, then more than one SimpleTag should be used."
*/
inline bool MatroskaTag::supportsMultipleValues(KnownField) const
{
return true;
}
inline TagTargetLevel MatroskaTag::targetLevel() const
{
return matroskaTagTargetLevel(m_target.level());

View File

@ -120,6 +120,7 @@ public:
bool setValue(const char *mean, const char *name, const TagValue &value);
using FieldMapBasedTag<Mp4Tag>::hasField;
bool hasField(KnownField value) const override;
bool supportsMultipleValues(KnownField) const override;
void parse(Mp4Atom &metaAtom, Diagnostics &diag);
Mp4TagMaker prepareMaking(Diagnostics &diag);
@ -163,6 +164,16 @@ inline bool Mp4Tag::setValue(const std::string &mean, const std::string &name, c
return setValue(mean.data(), name.data(), value);
}
/*!
* \brief Returns false for all fields (for now).
* \remarks Not sure whether iTunes-style MP4 tags allow this. Let's return false for now.
* \todo Do some research whether it is supported or not.
*/
inline bool Mp4Tag::supportsMultipleValues(KnownField) const
{
return false;
}
} // namespace TagParser
#endif // TAG_PARSER_MP4TAG_H

20
tag.cpp
View File

@ -288,6 +288,26 @@ unsigned int Tag::insertValues(const Tag &from, bool overwrite)
* when subclassing.
*/
/*!
* \fn Tag::supportsMultipleValues()
* \brief Returns an indications whether the specified field supports multiple values.
* \remarks
* - If you assign multiple values to a field which doesn't support multiple values,
* the tag implementation might just ignore additional values. It might also try
* to preserve the values nevertheless by bending the rules of the tag format
* specification when it is safe to do so. (Usually it is safe because additional
* values would be simply ignored by other applications.)
* - So it is not really mandatory to check this before adding multiple values. Nothing
* bad will happen otherwise. However, a GUI application could use this method to
* determine which widget to use.
* - In case it is not known whether multiple values are supported, this method returns
* false. If you know better, you can try to assign multiple values anyways.
* - If this method returns true, there might be further constraints, though. Eg. only
* one cover of a certain type may be present at a time in an ID3v2 tag.
* - The default implementation returns false for all fields. This might be overwritten
* when subclassing.
*/
/*!
* \fn Tag::supportsField()
* \brief Returns an indication whether the specified \a field

6
tag.h
View File

@ -121,6 +121,7 @@ public:
virtual TagDataType proposedDataType(KnownField field) const;
virtual bool supportsDescription(KnownField field) const;
virtual bool supportsMimeType(KnownField field) const;
virtual bool supportsMultipleValues(KnownField field) const;
virtual unsigned int insertValues(const Tag &from, bool overwrite);
virtual void ensureTextValuesAreProperlyEncoded() = 0;
@ -230,6 +231,11 @@ inline bool Tag::supportsMimeType(KnownField) const
return false;
}
inline bool Tag::supportsMultipleValues(KnownField) const
{
return false;
}
} // namespace TagParser
#endif // TAG_PARSER_TAG_H

View File

@ -44,6 +44,7 @@ public:
const TagValue &vendor() const;
void setVendor(const TagValue &vendor);
bool supportsMultipleValues(KnownField) const override;
protected:
IdentifierType internallyGetFieldId(KnownField field) const;
@ -86,6 +87,15 @@ inline void VorbisComment::setVendor(const TagValue &vendor)
m_vendor = vendor;
}
/*!
* \brief Allows multiple values for all fields.
* \remarks "Field names are not required to be unique (occur once) within a comment header."
*/
inline bool VorbisComment::supportsMultipleValues(KnownField) const
{
return true;
}
} // namespace TagParser
#endif // TAG_PARSER_VORBISCOMMENT_H