diff --git a/src/Makefile.am b/src/Makefile.am index 1e5754f6..adabcf1e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -40,6 +40,7 @@ ncmpcpp_SOURCES = \ status.cpp \ statusbar.cpp \ tag_editor.cpp \ + tags.cpp \ tiny_tag_editor.cpp \ title.cpp \ visualizer.cpp \ @@ -94,6 +95,7 @@ noinst_HEADERS = \ status.h \ statusbar.h \ tag_editor.h \ + tags.h \ tiny_tag_editor.h \ title.h \ visualizer.h \ diff --git a/src/actions.cpp b/src/actions.cpp index 17b8c2c8..1bc0783b 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -54,6 +54,7 @@ #include "tiny_tag_editor.h" #include "visualizer.h" #include "title.h" +#include "tags.h" #ifdef HAVE_TAGLIB_H # include "fileref.h" @@ -1343,7 +1344,7 @@ void EditLibraryTag::Run() es.setTags(set, new_tag, Config.tags_separator); Statusbar::msg("Updating tags in \"%s\"...", es.getName().c_str()); std::string path = Config.mpd_music_dir + es.getURI(); - if (!TagEditor::WriteTags(es)) + if (!Tags::write(es)) { const char msg[] = "Error while updating tags in \"%ls\""; Statusbar::msg(msg, wideShorten(ToWString(es.getURI()), COLS-const_strlen(msg)).c_str()); diff --git a/src/browser.cpp b/src/browser.cpp index 463e9929..a4a07396 100644 --- a/src/browser.cpp +++ b/src/browser.cpp @@ -37,6 +37,7 @@ #include "tag_editor.h" #include "utility/comparators.h" #include "title.h" +#include "tags.h" using namespace std::placeholders; @@ -507,7 +508,7 @@ void Browser::GetLocalDirectory(MPD::ItemList &v, const std::string &directory, new_item.song = std::shared_ptr(s); # ifdef HAVE_TAGLIB_H if (!recursively) - TagEditor::ReadTags(*s); + Tags::read(*s); # endif // HAVE_TAGLIB_H v.push_back(new_item); } diff --git a/src/tag_editor.cpp b/src/tag_editor.cpp index 3d775dd5..282551a2 100644 --- a/src/tag_editor.cpp +++ b/src/tag_editor.cpp @@ -22,20 +22,9 @@ #ifdef HAVE_TAGLIB_H +#include #include #include -#include - -// taglib includes -#include "id3v1tag.h" -#include "id3v2tag.h" -#include "textidentificationframe.h" -#include "mpegfile.h" -#include "vorbisfile.h" -#include "flacfile.h" -#include "xiphcomment.h" -#include "fileref.h" -#include "tag.h" #include "browser.h" #include "charset.h" @@ -47,6 +36,7 @@ #include "statusbar.h" #include "utility/comparators.h" #include "title.h" +#include "tags.h" using namespace std::placeholders; @@ -81,18 +71,6 @@ std::string CapitalizeFirstLetters(const std::string &s); void CapitalizeFirstLetters(MPD::MutableSong &s); void LowerAllLetters(MPD::MutableSong &s); -TagLib::StringList tagList(const MPD::MutableSong &s, MPD::Song::GetFunction f); - -void readCommonTags(MPD::MutableSong &s, TagLib::Tag *tag); -void readID3v1Tags(MPD::MutableSong &s, TagLib::ID3v1::Tag *tag); -void readID3v2Tags(MPD::MutableSong &s, TagLib::ID3v2::Tag *tag); -void readXiphComments(MPD::MutableSong &s, TagLib::Ogg::XiphComment *tag); - -void clearID3v1Tags(TagLib::ID3v1::Tag *tag); -void writeCommonTags(const MPD::MutableSong &s, TagLib::Tag *tag); -void writeID3v2Tags(const MPD::MutableSong &s, TagLib::ID3v2::Tag *tag); -void writeXiphComments(const MPD::MutableSong &s, TagLib::Ogg::XiphComment *tag); - void GetPatternList(); void SavePatternList(); @@ -607,7 +585,7 @@ void TagEditor::EnterPressed() for (auto it = EditedSongs.begin(); it != EditedSongs.end(); ++it) { Statusbar::msg("Writing tags in \"%s\"...", (*it)->getName().c_str()); - if (!WriteTags(**it)) + if (!Tags::write(**it)) { const char msg[] = "Error while writing tags in \"%ls\""; Statusbar::msg(msg, wideShorten(ToWString((*it)->getURI()), COLS-const_strlen(msg)).c_str()); @@ -1040,96 +1018,6 @@ void TagEditor::LocateSong(const MPD::Song &s) } } -void TagEditor::ReadTags(MPD::MutableSong &s) -{ - TagLib::FileRef f(s.getURI().c_str()); - if (f.isNull()) - return; - - s.setDuration(f.audioProperties()->length()); - - if (auto mpeg_file = dynamic_cast(f.file())) - { - if (auto id3v1 = mpeg_file->ID3v1Tag()) - readID3v1Tags(s, id3v1); - if (auto id3v2 = mpeg_file->ID3v2Tag()) - readID3v2Tags(s, id3v2); - } - else if (auto ogg_file = dynamic_cast(f.file())) - { - if (auto xiph = ogg_file->tag()) - readXiphComments(s, xiph); - } - else if (auto flac_file = dynamic_cast(f.file())) - { - if (auto xiph = flac_file->xiphComment()) - readXiphComments(s, xiph); - } - else - readCommonTags(s, f.tag()); -} - -bool TagEditor::WriteTags(MPD::MutableSong &s) -{ - std::string path_to_file; - bool file_is_from_db = s.isFromDatabase(); - if (file_is_from_db) - path_to_file += Config.mpd_music_dir; - path_to_file += s.getURI(); - TagLib::FileRef f(path_to_file.c_str()); - if (!f.isNull()) - { - if (auto mp3_file = dynamic_cast(f.file())) - { - clearID3v1Tags(mp3_file->ID3v1Tag()); - writeID3v2Tags(s, mp3_file->ID3v2Tag(true)); - } - else if (auto ogg_file = dynamic_cast(f.file())) - { - writeXiphComments(s, ogg_file->tag()); - } - else if (auto flac_file = dynamic_cast(f.file())) - { - writeXiphComments(s, flac_file->xiphComment(true)); - } - else - writeCommonTags(s, f.tag()); - if (!f.save()) - return false; - - if (!s.getNewURI().empty()) - { - std::string new_name; - if (file_is_from_db) - new_name += Config.mpd_music_dir; - new_name += s.getDirectory() + "/" + s.getNewURI(); - if (rename(path_to_file.c_str(), new_name.c_str()) == 0 && !file_is_from_db) - { - if (Global::myOldScreen == myPlaylist) - { - // if we rename local file, it won't get updated - // so just remove it from playlist and add again - size_t pos = myPlaylist->Items->choice(); - Mpd.StartCommandsList(); - Mpd.Delete(pos); - int id = Mpd.AddSong("file://" + new_name); - if (id >= 0) - { - s = myPlaylist->Items->back().value(); - Mpd.Move(s.getPosition(), pos); - } - Mpd.CommitCommandsList(); - } - else // only myBrowser->Main() - myBrowser->GetDirectory(myBrowser->CurrentDir()); - } - } - return true; - } - else - return false; -} - namespace {// bool isAnyModified(const NC::Menu &m) @@ -1173,138 +1061,6 @@ void LowerAllLetters(MPD::MutableSong &s) } } -TagLib::StringList tagList(const MPD::MutableSong &s, MPD::Song::GetFunction f) -{ - TagLib::StringList result; - unsigned idx = 0; - for (std::string value; !(value = (s.*f)(idx)).empty(); ++idx) - result.append(ToWString(value)); - return result; -} - -void readCommonTags(MPD::MutableSong &s, TagLib::Tag *tag) -{ - s.setTitle(tag->title().to8Bit(true)); - s.setArtist(tag->artist().to8Bit(true)); - s.setAlbum(tag->album().to8Bit(true)); - s.setDate(intTo::apply(tag->year())); - s.setTrack(intTo::apply(tag->track())); - s.setGenre(tag->genre().to8Bit(true)); - s.setComment(tag->comment().to8Bit(true)); -} - -void readID3v1Tags(MPD::MutableSong &s, TagLib::ID3v1::Tag *tag) -{ - readCommonTags(s, tag); -} - -void readID3v2Tags(MPD::MutableSong &s, TagLib::ID3v2::Tag *tag) -{ - auto readFrame = [&s](const TagLib::ID3v2::FrameList &list, MPD::MutableSong::SetFunction f) { - unsigned idx = 0; - for (auto it = list.begin(); it != list.end(); ++it, ++idx) - (s.*f)((*it)->toString().to8Bit(true), idx); - }; - auto &frames = tag->frameListMap(); - readFrame(frames["TIT2"], &MPD::MutableSong::setTitle); - readFrame(frames["TPE1"], &MPD::MutableSong::setArtist); - readFrame(frames["TPE2"], &MPD::MutableSong::setAlbumArtist); - readFrame(frames["TALB"], &MPD::MutableSong::setAlbum); - readFrame(frames["TDRC"], &MPD::MutableSong::setDate); - readFrame(frames["TRCK"], &MPD::MutableSong::setTrack); - readFrame(frames["TCON"], &MPD::MutableSong::setGenre); - readFrame(frames["TCOM"], &MPD::MutableSong::setComposer); - readFrame(frames["TPE3"], &MPD::MutableSong::setPerformer); - readFrame(frames["TPOS"], &MPD::MutableSong::setDisc); - readFrame(frames["COMM"], &MPD::MutableSong::setComment); -} - -void readXiphComments(MPD::MutableSong &s, TagLib::Ogg::XiphComment *tag) -{ - auto readField = [&s](const TagLib::StringList &list, MPD::MutableSong::SetFunction f) { - unsigned idx = 0; - for (auto it = list.begin(); it != list.end(); ++it) - (s.*f)(it->to8Bit(true), idx); - }; - auto &fields = tag->fieldListMap(); - readField(fields["TITLE"], &MPD::MutableSong::setTitle); - readField(fields["ARTIST"], &MPD::MutableSong::setArtist); - readField(fields["ALBUMARTIST"], &MPD::MutableSong::setAlbumArtist); - readField(fields["ALBUM"], &MPD::MutableSong::setAlbum); - readField(fields["DATE"], &MPD::MutableSong::setDate); - readField(fields["TRACKNUMBER"], &MPD::MutableSong::setTrack); - readField(fields["GENRE"], &MPD::MutableSong::setGenre); - readField(fields["COMPOSER"], &MPD::MutableSong::setComposer); - readField(fields["PERFORMER"], &MPD::MutableSong::setPerformer); - readField(fields["DISCNUMBER"], &MPD::MutableSong::setDisc); - readField(fields["COMMENT"], &MPD::MutableSong::setComment); -} - -void clearID3v1Tags(TagLib::ID3v1::Tag *tag) -{ - tag->setTitle(TagLib::String::null); - tag->setArtist(TagLib::String::null); - tag->setAlbum(TagLib::String::null); - tag->setYear(0); - tag->setTrack(0); - tag->setGenre(TagLib::String::null); - tag->setComment(TagLib::String::null); -} - -void writeCommonTags(const MPD::MutableSong &s, TagLib::Tag *tag) -{ - tag->setTitle(ToWString(s.getTitle())); - tag->setArtist(ToWString(s.getArtist())); - tag->setAlbum(ToWString(s.getAlbum())); - tag->setYear(stringToInt(s.getDate())); - tag->setTrack(stringToInt(s.getTrack())); - tag->setGenre(ToWString(s.getGenre())); - tag->setComment(ToWString(s.getComment())); -} - -void writeID3v2Tags(const MPD::MutableSong &s, TagLib::ID3v2::Tag *tag) -{ - auto writeID3v2 = [&](const TagLib::ByteVector &type, const TagLib::StringList &list) { - tag->removeFrames(type); - auto frame = new TagLib::ID3v2::TextIdentificationFrame(type, TagLib::String::UTF8); - frame->setText(list); - tag->addFrame(frame); - }; - writeID3v2("TIT2", tagList(s, &MPD::Song::getTitle)); - writeID3v2("TPE1", tagList(s, &MPD::Song::getArtist)); - writeID3v2("TPE2", tagList(s, &MPD::Song::getAlbumArtist)); - writeID3v2("TALB", tagList(s, &MPD::Song::getAlbum)); - writeID3v2("TDRC", tagList(s, &MPD::Song::getDate)); - writeID3v2("TRCK", tagList(s, &MPD::Song::getTrack)); - writeID3v2("TCON", tagList(s, &MPD::Song::getGenre)); - writeID3v2("TCOM", tagList(s, &MPD::Song::getComposer)); - writeID3v2("TPE3", tagList(s, &MPD::Song::getPerformer)); - writeID3v2("TPOS", tagList(s, &MPD::Song::getDisc)); - writeID3v2("COMM", tagList(s, &MPD::Song::getComment)); -} - -void writeXiphComments(const MPD::MutableSong &s, TagLib::Ogg::XiphComment *tag) -{ - auto writeXiph = [&](const TagLib::String &type, const TagLib::StringList &list) { - tag->removeField(type); - for (auto it = list.begin(); it != list.end(); ++it) - tag->addField(type, *it, false); - }; - // remove field previously used as album artist - tag->removeField("ALBUM ARTIST"); - writeXiph("TITLE", tagList(s, &MPD::Song::getTitle)); - writeXiph("ARTIST", tagList(s, &MPD::Song::getArtist)); - writeXiph("ALBUMARTIST", tagList(s, &MPD::Song::getAlbumArtist)); - writeXiph("ALBUM", tagList(s, &MPD::Song::getAlbum)); - writeXiph("DATE", tagList(s, &MPD::Song::getDate)); - writeXiph("TRACKNUMBER", tagList(s, &MPD::Song::getTrack)); - writeXiph("GENRE", tagList(s, &MPD::Song::getGenre)); - writeXiph("COMPOSER", tagList(s, &MPD::Song::getComposer)); - writeXiph("PERFORMER", tagList(s, &MPD::Song::getPerformer)); - writeXiph("DISCNUMBER", tagList(s, &MPD::Song::getDisc)); - writeXiph("COMMENT", tagList(s, &MPD::Song::getComment)); -} - void GetPatternList() { if (Patterns.empty()) diff --git a/src/tag_editor.h b/src/tag_editor.h index 8b0a3f15..869c1371 100644 --- a/src/tag_editor.h +++ b/src/tag_editor.h @@ -87,9 +87,6 @@ class TagEditor : public Screen, public Filterable, public HasColumn NC::Menu *TagTypes; NC::Menu *Tags; - static void ReadTags(MPD::MutableSong &); - static bool WriteTags(MPD::MutableSong &); - protected: virtual void Init(); virtual bool isLockable() { return true; } diff --git a/src/tags.cpp b/src/tags.cpp new file mode 100644 index 00000000..ac77a577 --- /dev/null +++ b/src/tags.cpp @@ -0,0 +1,280 @@ +/*************************************************************************** + * Copyright (C) 2008-2012 by Andrzej Rybczak * + * electricityispower@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "tags.h" + +#ifdef HAVE_TAGLIB_H + +// taglib includes +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "browser.h" +#include "playlist.h" + +#include "global.h" +#include "settings.h" +#include "utility/numeric_conversions.h" +#include "utility/wide_string.h" + +namespace {// + +TagLib::StringList tagList(const MPD::MutableSong &s, MPD::Song::GetFunction f) +{ + TagLib::StringList result; + unsigned idx = 0; + for (std::string value; !(value = (s.*f)(idx)).empty(); ++idx) + result.append(ToWString(value)); + return result; +} + +void readCommonTags(MPD::MutableSong &s, TagLib::Tag *tag) +{ + s.setTitle(tag->title().to8Bit(true)); + s.setArtist(tag->artist().to8Bit(true)); + s.setAlbum(tag->album().to8Bit(true)); + s.setDate(intTo::apply(tag->year())); + s.setTrack(intTo::apply(tag->track())); + s.setGenre(tag->genre().to8Bit(true)); + s.setComment(tag->comment().to8Bit(true)); +} + +void readID3v1Tags(MPD::MutableSong &s, TagLib::ID3v1::Tag *tag) +{ + readCommonTags(s, tag); +} + +void readID3v2Tags(MPD::MutableSong &s, TagLib::ID3v2::Tag *tag) +{ + auto readFrame = [&s](const TagLib::ID3v2::FrameList &list, MPD::MutableSong::SetFunction f) { + unsigned idx = 0; + for (auto it = list.begin(); it != list.end(); ++it, ++idx) + (s.*f)((*it)->toString().to8Bit(true), idx); + }; + auto &frames = tag->frameListMap(); + readFrame(frames["TIT2"], &MPD::MutableSong::setTitle); + readFrame(frames["TPE1"], &MPD::MutableSong::setArtist); + readFrame(frames["TPE2"], &MPD::MutableSong::setAlbumArtist); + readFrame(frames["TALB"], &MPD::MutableSong::setAlbum); + readFrame(frames["TDRC"], &MPD::MutableSong::setDate); + readFrame(frames["TRCK"], &MPD::MutableSong::setTrack); + readFrame(frames["TCON"], &MPD::MutableSong::setGenre); + readFrame(frames["TCOM"], &MPD::MutableSong::setComposer); + readFrame(frames["TPE3"], &MPD::MutableSong::setPerformer); + readFrame(frames["TPOS"], &MPD::MutableSong::setDisc); + readFrame(frames["COMM"], &MPD::MutableSong::setComment); +} + +void readXiphComments(MPD::MutableSong &s, TagLib::Ogg::XiphComment *tag) +{ + auto readField = [&s](const TagLib::StringList &list, MPD::MutableSong::SetFunction f) { + unsigned idx = 0; + for (auto it = list.begin(); it != list.end(); ++it) + (s.*f)(it->to8Bit(true), idx); + }; + auto &fields = tag->fieldListMap(); + readField(fields["TITLE"], &MPD::MutableSong::setTitle); + readField(fields["ARTIST"], &MPD::MutableSong::setArtist); + readField(fields["ALBUMARTIST"], &MPD::MutableSong::setAlbumArtist); + readField(fields["ALBUM"], &MPD::MutableSong::setAlbum); + readField(fields["DATE"], &MPD::MutableSong::setDate); + readField(fields["TRACKNUMBER"], &MPD::MutableSong::setTrack); + readField(fields["GENRE"], &MPD::MutableSong::setGenre); + readField(fields["COMPOSER"], &MPD::MutableSong::setComposer); + readField(fields["PERFORMER"], &MPD::MutableSong::setPerformer); + readField(fields["DISCNUMBER"], &MPD::MutableSong::setDisc); + readField(fields["COMMENT"], &MPD::MutableSong::setComment); +} + +void clearID3v1Tags(TagLib::ID3v1::Tag *tag) +{ + tag->setTitle(TagLib::String::null); + tag->setArtist(TagLib::String::null); + tag->setAlbum(TagLib::String::null); + tag->setYear(0); + tag->setTrack(0); + tag->setGenre(TagLib::String::null); + tag->setComment(TagLib::String::null); +} + +void writeCommonTags(const MPD::MutableSong &s, TagLib::Tag *tag) +{ + tag->setTitle(ToWString(s.getTitle())); + tag->setArtist(ToWString(s.getArtist())); + tag->setAlbum(ToWString(s.getAlbum())); + tag->setYear(stringToInt(s.getDate())); + tag->setTrack(stringToInt(s.getTrack())); + tag->setGenre(ToWString(s.getGenre())); + tag->setComment(ToWString(s.getComment())); +} + +void writeID3v2Tags(const MPD::MutableSong &s, TagLib::ID3v2::Tag *tag) +{ + auto writeID3v2 = [&](const TagLib::ByteVector &type, const TagLib::StringList &list) { + tag->removeFrames(type); + auto frame = new TagLib::ID3v2::TextIdentificationFrame(type, TagLib::String::UTF8); + frame->setText(list); + tag->addFrame(frame); + }; + writeID3v2("TIT2", tagList(s, &MPD::Song::getTitle)); + writeID3v2("TPE1", tagList(s, &MPD::Song::getArtist)); + writeID3v2("TPE2", tagList(s, &MPD::Song::getAlbumArtist)); + writeID3v2("TALB", tagList(s, &MPD::Song::getAlbum)); + writeID3v2("TDRC", tagList(s, &MPD::Song::getDate)); + writeID3v2("TRCK", tagList(s, &MPD::Song::getTrack)); + writeID3v2("TCON", tagList(s, &MPD::Song::getGenre)); + writeID3v2("TCOM", tagList(s, &MPD::Song::getComposer)); + writeID3v2("TPE3", tagList(s, &MPD::Song::getPerformer)); + writeID3v2("TPOS", tagList(s, &MPD::Song::getDisc)); + writeID3v2("COMM", tagList(s, &MPD::Song::getComment)); +} + +void writeXiphComments(const MPD::MutableSong &s, TagLib::Ogg::XiphComment *tag) +{ + auto writeXiph = [&](const TagLib::String &type, const TagLib::StringList &list) { + tag->removeField(type); + for (auto it = list.begin(); it != list.end(); ++it) + tag->addField(type, *it, false); + }; + // remove field previously used as album artist + tag->removeField("ALBUM ARTIST"); + writeXiph("TITLE", tagList(s, &MPD::Song::getTitle)); + writeXiph("ARTIST", tagList(s, &MPD::Song::getArtist)); + writeXiph("ALBUMARTIST", tagList(s, &MPD::Song::getAlbumArtist)); + writeXiph("ALBUM", tagList(s, &MPD::Song::getAlbum)); + writeXiph("DATE", tagList(s, &MPD::Song::getDate)); + writeXiph("TRACKNUMBER", tagList(s, &MPD::Song::getTrack)); + writeXiph("GENRE", tagList(s, &MPD::Song::getGenre)); + writeXiph("COMPOSER", tagList(s, &MPD::Song::getComposer)); + writeXiph("PERFORMER", tagList(s, &MPD::Song::getPerformer)); + writeXiph("DISCNUMBER", tagList(s, &MPD::Song::getDisc)); + writeXiph("COMMENT", tagList(s, &MPD::Song::getComment)); +} + +} + +namespace Tags {// + +bool extendedSetSupported(const TagLib::File *f) +{ + return dynamic_cast(f) + || dynamic_cast(f) + || dynamic_cast(f); +} + +void read(MPD::MutableSong &s) +{ + TagLib::FileRef f(s.getURI().c_str()); + if (f.isNull()) + return; + + s.setDuration(f.audioProperties()->length()); + + if (auto mpeg_file = dynamic_cast(f.file())) + { + if (auto id3v1 = mpeg_file->ID3v1Tag()) + readID3v1Tags(s, id3v1); + if (auto id3v2 = mpeg_file->ID3v2Tag()) + readID3v2Tags(s, id3v2); + } + else if (auto ogg_file = dynamic_cast(f.file())) + { + if (auto xiph = ogg_file->tag()) + readXiphComments(s, xiph); + } + else if (auto flac_file = dynamic_cast(f.file())) + { + if (auto xiph = flac_file->xiphComment()) + readXiphComments(s, xiph); + } + else + readCommonTags(s, f.tag()); +} + +bool write(MPD::MutableSong &s) +{ + std::string old_name; + if (s.isFromDatabase()) + old_name += Config.mpd_music_dir; + old_name += s.getURI(); + + TagLib::FileRef f(old_name.c_str()); + if (f.isNull()) + return false; + + if (auto mp3_file = dynamic_cast(f.file())) + { + clearID3v1Tags(mp3_file->ID3v1Tag()); + writeID3v2Tags(s, mp3_file->ID3v2Tag(true)); + } + else if (auto ogg_file = dynamic_cast(f.file())) + { + writeXiphComments(s, ogg_file->tag()); + } + else if (auto flac_file = dynamic_cast(f.file())) + { + writeXiphComments(s, flac_file->xiphComment(true)); + } + else + writeCommonTags(s, f.tag()); + + if (!f.save()) + return false; + + if (!s.getNewURI().empty()) + { + std::string new_name; + if (s.isFromDatabase()) + new_name += Config.mpd_music_dir; + new_name += s.getDirectory() + "/" + s.getNewURI(); + if (std::rename(old_name.c_str(), new_name.c_str()) == 0 && !s.isFromDatabase()) + { + if (Global::myOldScreen == myPlaylist) + { + // if we rename local file, it won't get updated + // so just remove it from playlist and add again + size_t pos = myPlaylist->Items->choice(); + Mpd.StartCommandsList(); + Mpd.Delete(pos); + int id = Mpd.AddSong("file://" + new_name); + if (id >= 0) + { + s = myPlaylist->Items->back().value(); + Mpd.Move(s.getPosition(), pos); + } + Mpd.CommitCommandsList(); + } + else // only myBrowser->Main() + myBrowser->GetDirectory(myBrowser->CurrentDir()); + } + } + return true; +} + +} + +#endif // HAVE_TAGLIB_H diff --git a/src/tags.h b/src/tags.h new file mode 100644 index 00000000..5db8855f --- /dev/null +++ b/src/tags.h @@ -0,0 +1,42 @@ +/*************************************************************************** + * Copyright (C) 2008-2012 by Andrzej Rybczak * + * electricityispower@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef _TAGS_H +#define _TAGS_H + +#include "config.h" + +#ifdef HAVE_TAGLIB_H + +#include +#include "mutable_song.h" + +namespace Tags {// + +bool extendedSetSupported(const TagLib::File *f); + +void read(MPD::MutableSong &); +bool write(MPD::MutableSong &); + +} + +#endif // HAVE_TAGLIB_H + +#endif // _TAGS_H diff --git a/src/tiny_tag_editor.cpp b/src/tiny_tag_editor.cpp index c7b5db6c..cc348efd 100644 --- a/src/tiny_tag_editor.cpp +++ b/src/tiny_tag_editor.cpp @@ -23,10 +23,8 @@ #ifdef HAVE_TAGLIB_H // taglib includes -#include "mpegfile.h" -#include "vorbisfile.h" -#include "flacfile.h" -#include "fileref.h" +#include +#include #include "browser.h" #include "charset.h" @@ -39,6 +37,7 @@ #include "statusbar.h" #include "tag_editor.h" #include "title.h" +#include "tags.h" using Global::MainHeight; using Global::MainStartY; @@ -134,7 +133,7 @@ void TinyTagEditor::EnterPressed() if (option == 22) { Statusbar::msg("Updating tags..."); - if (TagEditor::WriteTags(itsEdited)) + if (Tags::write(itsEdited)) { Statusbar::msg("Tags updated"); if (itsEdited.isFromDatabase()) @@ -207,7 +206,7 @@ bool TinyTagEditor::getTags() w->at(19).setSeparator(true); w->at(21).setSeparator(true); - if (!extendedTagsSupported(f.file())) + if (!Tags::extendedSetSupported(f.file())) { w->at(10).setInactive(true); for (size_t i = 15; i <= 17; ++i) @@ -239,12 +238,5 @@ bool TinyTagEditor::getTags() return true; } -bool TinyTagEditor::extendedTagsSupported(TagLib::File *f) -{ - return dynamic_cast(f) - || dynamic_cast(f) - || dynamic_cast(f); -} - #endif // HAVE_TAGLIB_H diff --git a/src/tiny_tag_editor.h b/src/tiny_tag_editor.h index b1fc66c2..9437daef 100644 --- a/src/tiny_tag_editor.h +++ b/src/tiny_tag_editor.h @@ -25,9 +25,6 @@ #ifdef HAVE_TAGLIB_H -// taglib includes -#include "tfile.h" - #include "mutable_song.h" #include "screen.h" @@ -59,8 +56,6 @@ class TinyTagEditor : public Screen< NC::Menu > private: bool getTags(); MPD::MutableSong itsEdited; - - static bool extendedTagsSupported(TagLib::File *); }; extern TinyTagEditor *myTinyTagEditor;