From bd3b953b088384116dbe6df0fd29cdcdf81924ec Mon Sep 17 00:00:00 2001 From: Martin Babutzka Date: Mon, 27 Jul 2015 22:52:29 +0200 Subject: [PATCH] Softened the metadata-editor behavior to not deliberately delete additional, valid frames which are stored in mp3-files. Stashed commit of the following: e54bcd2f058d186c2c919a84152ed5e8526047fc Fixed bugs/comments from John Maguire 01c71c4c67be44dd6889498abc323a6d2d20dd99 Added description "Clementine editor" to new created lyrics frames. 70dfa0d1f177523ff897985ae022979cd052a6ed Updated the SetTextFrame method as well: Existing frames are cached and only the first frame (which is actually shown in the metadata editor) will be updated. Prevents the cruel deletion of all other existing frames in a well defined mp3-file. dfddf76eda417442c8c168eb8868038b0675cb10 Updated behavior of metadata-editor concerning lyrics (might follow for other id3v2-tag properties): Existing further frames in the tags are not deleted but cached so only the true changes by the metadata-editor are applied on the edited frame. Further frames in the metadata are preserved. --- ext/libclementine-tagreader/tagreader.cpp | 56 ++++++++++++++++++----- 1 file changed, 44 insertions(+), 12 deletions(-) diff --git a/ext/libclementine-tagreader/tagreader.cpp b/ext/libclementine-tagreader/tagreader.cpp index b32d3ee66..490aa23c8 100644 --- a/ext/libclementine-tagreader/tagreader.cpp +++ b/ext/libclementine-tagreader/tagreader.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -893,36 +894,67 @@ void TagReader::SetTextFrame(const char* id, const QString& value, void TagReader::SetTextFrame(const char* id, const std::string& value, TagLib::ID3v2::Tag* tag) const { TagLib::ByteVector id_vector(id); + QVector frames_buffer; - // Remove the frame if it already exists + // Store and clear existing frames while (tag->frameListMap().contains(id_vector) && tag->frameListMap()[id_vector].size() != 0) { + frames_buffer.push_back(tag->frameListMap()[id_vector].front()->render()); tag->removeFrame(tag->frameListMap()[id_vector].front()); } - // Create and add a new frame - TagLib::ID3v2::TextIdentificationFrame* frame = - new TagLib::ID3v2::TextIdentificationFrame(id_vector, + // If no frames stored create empty frame + if (frames_buffer.isEmpty()) { + TagLib::ID3v2::TextIdentificationFrame frame(id_vector, TagLib::String::UTF8); - frame->setText(StdStringToTaglibString(value)); - tag->addFrame(frame); + frames_buffer.push_back(frame.render()); + } + + // Update and add the frames + for (int lyrics_index = 0; lyrics_index < frames_buffer.size(); + lyrics_index++) { + TagLib::ID3v2::TextIdentificationFrame* frame = + new TagLib::ID3v2::TextIdentificationFrame( + frames_buffer.at(lyrics_index)); + if (lyrics_index == 0) { + frame->setText(StdStringToTaglibString(value)); + } + // add frame takes ownership and clears the memory + tag->addFrame(frame); + } } void TagReader::SetUnsyncLyricsFrame(const std::string& value, TagLib::ID3v2::Tag* tag) const { TagLib::ByteVector id_vector("USLT"); + QVector frames_buffer; - // Remove the frame if it already exists + // Store and clear existing frames while (tag->frameListMap().contains(id_vector) && tag->frameListMap()[id_vector].size() != 0) { + frames_buffer.push_back(tag->frameListMap()[id_vector].front()->render()); tag->removeFrame(tag->frameListMap()[id_vector].front()); } - // Create and add a new frame - TagLib::ID3v2::UnsynchronizedLyricsFrame* frame = - new TagLib::ID3v2::UnsynchronizedLyricsFrame(TagLib::String::UTF8); - frame->setText(StdStringToTaglibString(value)); - tag->addFrame(frame); + // If no frames stored create empty frame + if (frames_buffer.isEmpty()) { + TagLib::ID3v2::UnsynchronizedLyricsFrame frame(TagLib::String::UTF8); + frame.setDescription("Clementine editor"); + frames_buffer.push_back(frame.render()); + } + + // Update and add the frames + for (int lyrics_index = 0; lyrics_index < frames_buffer.size(); + lyrics_index++) { + TagLib::ID3v2::UnsynchronizedLyricsFrame* frame = + new TagLib::ID3v2::UnsynchronizedLyricsFrame( + frames_buffer.at(lyrics_index)); + if (lyrics_index == 0) { + frame->setText(StdStringToTaglibString(value)); + } + // add frame takes ownership and clears the memory + tag->addFrame(frame); + } } bool TagReader::IsMediaFile(const QString& filename) const {