diff --git a/src/ncmpcpp.cpp b/src/ncmpcpp.cpp index 60026c26..4196315c 100644 --- a/src/ncmpcpp.cpp +++ b/src/ncmpcpp.cpp @@ -649,12 +649,12 @@ int main(int argc, char *argv[]) mEditorTags->Refresh(); } - if (redraw_screen && wCurrent == mEditorTagTypes && mEditorTagTypes->GetChoice() < 10) + if (redraw_screen && wCurrent == mEditorTagTypes && mEditorTagTypes->GetChoice() < 13) { mEditorTags->Refresh(1); redraw_screen = 0; } - else if (mEditorTagTypes->GetChoice() >= 10) + else if (mEditorTagTypes->GetChoice() >= 13) mEditorTags->Window::Clear(); } // album editor end @@ -949,12 +949,11 @@ int main(int argc, char *argv[]) # ifdef HAVE_TAGLIB_H case csTinyTagEditor: { - int id = mTagEditor->GetRealChoice()+1; int option = mTagEditor->GetChoice(); LockStatusbar(); Song &s = edited_song; - switch (id) + switch (option-7) { case 1: { @@ -1017,6 +1016,36 @@ int main(int argc, char *argv[]) break; } case 7: + { + wFooter->WriteXY(0, Config.statusbar_visibility, "[.b]Composer:[/b] ", 1); + if (s.GetComposer() == EMPTY_TAG) + s.SetComposer(wFooter->GetString()); + else + s.SetComposer(wFooter->GetString(s.GetComposer())); + mTagEditor->UpdateOption(option, "[.b]Composer:[/b] " + s.GetComposer()); + break; + } + case 8: + { + wFooter->WriteXY(0, Config.statusbar_visibility, "[.b]Performer:[/b] ", 1); + if (s.GetPerformer() == EMPTY_TAG) + s.SetPerformer(wFooter->GetString()); + else + s.SetPerformer(wFooter->GetString(s.GetPerformer())); + mTagEditor->UpdateOption(option, "[.b]Performer:[/b] " + s.GetPerformer()); + break; + } + case 9: + { + wFooter->WriteXY(0, Config.statusbar_visibility, "[.b]Disc:[/b] ", 1); + if (s.GetDisc() == EMPTY_TAG) + s.SetDisc(wFooter->GetString()); + else + s.SetDisc(wFooter->GetString(s.GetDisc())); + mTagEditor->UpdateOption(option, "[.b]Disc:[/b] " + s.GetDisc()); + break; + } + case 10: { wFooter->WriteXY(0, Config.statusbar_visibility, "[.b]Comment:[/b] ", 1); if (s.GetComment() == EMPTY_TAG) @@ -1026,7 +1055,7 @@ int main(int argc, char *argv[]) mTagEditor->UpdateOption(option, "[.b]Comment:[/b] " + s.GetComment()); break; } - case 8: + case 12: { wFooter->WriteXY(0, Config.statusbar_visibility, "[.b]Filename:[/b] ", 1); string filename = s.GetNewName().empty() ? s.GetName() : s.GetNewName(); @@ -1038,7 +1067,7 @@ int main(int argc, char *argv[]) mTagEditor->UpdateOption(option, "[.b]Filename:[/b] " + (s.GetNewName().empty() ? s.GetName() : s.GetNewName())); break; } - case 9: + case 14: { ShowMessage("Updating tags..."); if (WriteTags(s)) @@ -1050,7 +1079,7 @@ int main(int argc, char *argv[]) } ShowMessage("Error writing tags!"); } - case 10: + case 15: { wCurrent->Clear(); wCurrent = wPrev; @@ -1511,9 +1540,18 @@ int main(int argc, char *argv[]) set = &Song::SetGenre; break; case 6: - set = &Song::SetComment; + set = &Song::SetComposer; break; case 7: + set = &Song::SetPerformer; + break; + case 8: + set = &Song::SetDisc; + break; + case 9: + set = &Song::SetComment; + break; + case 10: { if (wCurrent == mEditorTagTypes) { @@ -1540,13 +1578,13 @@ int main(int argc, char *argv[]) } continue; } - case 8: // reset + case 11: // reset { mEditorTags->Clear(0); ShowMessage("Changes reset"); continue; } - case 9: // save + case 12: // save { bool success = 1; ShowMessage("Writing changes..."); @@ -1554,7 +1592,7 @@ int main(int argc, char *argv[]) { if (!WriteTags(**it)) { - ShowMessage("Error writing tags!"); + ShowMessage("Error writing tags in '" + (*it)->GetFile() + "'!"); success = 0; break; } @@ -1587,6 +1625,7 @@ int main(int argc, char *argv[]) UnlockStatusbar(); for (SongList::iterator it = list.begin(); it != list.end(); it++) (**it.*set)(new_tag); + redraw_screen = 1; } else if (wCurrent == mEditorTags && set != NULL) { @@ -1790,7 +1829,7 @@ int main(int argc, char *argv[]) wCurrent = mEditorTagTypes; mEditorTagTypes->HighlightColor(Config.active_column_color); } - else if (wCurrent == mEditorTagTypes && mEditorTagTypes->GetChoice() < 10 && !mEditorTags->Empty()) + else if (wCurrent == mEditorTagTypes && mEditorTagTypes->GetChoice() < 12 && !mEditorTags->Empty()) { mEditorTagTypes->HighlightColor(Config.main_highlight_color); wCurrent->Refresh(); @@ -3326,6 +3365,9 @@ int main(int argc, char *argv[]) mEditorTagTypes->AddOption("Year"); mEditorTagTypes->AddOption("Track"); mEditorTagTypes->AddOption("Genre"); + mEditorTagTypes->AddOption("Composer"); + mEditorTagTypes->AddOption("Performer"); + mEditorTagTypes->AddOption("Disc"); mEditorTagTypes->AddOption("Comment"); mEditorTagTypes->AddSeparator(); mEditorTagTypes->AddOption("Filename"); diff --git a/src/song.cpp b/src/song.cpp index 83668cb1..96d2c5b3 100644 --- a/src/song.cpp +++ b/src/song.cpp @@ -238,6 +238,27 @@ void Song::SetGenre(const string &str) itsSong->genre = str.empty() ? 0 : str_pool_get(str.c_str()); } +void Song::SetComposer(const string &str) +{ + if (itsSong->composer) + str_pool_put(itsSong->composer); + itsSong->composer = str.empty() ? 0 : str_pool_get(str.c_str()); +} + +void Song::SetPerformer(const string &str) +{ + if (itsSong->performer) + str_pool_put(itsSong->performer); + itsSong->performer = str.empty() ? 0 : str_pool_get(str.c_str()); +} + +void Song::SetDisc(const string &str) +{ + if (itsSong->disc) + str_pool_put(itsSong->disc); + itsSong->disc = str.empty() ? 0 : str_pool_get(str.c_str()); +} + void Song::SetComment(const string &str) { if (itsSong->comment) diff --git a/src/song.h b/src/song.h index 8e350a0d..b97b7b4f 100644 --- a/src/song.h +++ b/src/song.h @@ -61,17 +61,20 @@ class Song int GetPosition() const { return itsSong->pos; } int GetID() const { return itsSong->id; } - void SetFile(const string &str); - void SetArtist(const string &str); - void SetTitle(const string &str); - void SetAlbum(const string &str); - void SetTrack(const string &str); - void SetTrack(int track); - void SetYear(const string &str); - void SetYear(int year); - void SetGenre(const string &str); - void SetComment(const string &str); - void SetPosition(int pos); + void SetFile(const string &); + void SetArtist(const string &); + void SetTitle(const string &); + void SetAlbum(const string &); + void SetTrack(const string &); + void SetTrack(int); + void SetYear(const string &); + void SetYear(int); + void SetGenre(const string &); + void SetComposer(const string &); + void SetPerformer(const string &); + void SetDisc(const string &); + void SetComment(const string &); + void SetPosition(int); void SetNewName(string name) { itsNewName = name == GetName() ? "" : name; } string GetNewName() const { return itsNewName; } diff --git a/src/tag_editor.cpp b/src/tag_editor.cpp index 35ecd4f3..b643e955 100644 --- a/src/tag_editor.cpp +++ b/src/tag_editor.cpp @@ -22,6 +22,11 @@ #ifdef HAVE_TAGLIB_H +#include "id3v2tag.h" +#include "textidentificationframe.h" +#include "mpegfile.h" +#include "flacfile.h" + #include "helpers.h" #include "status_checker.h" @@ -75,8 +80,14 @@ string DisplayTag(const Song &s, void *data, const Menu *null) case 5: return s.GetGenre(); case 6: - return s.GetComment(); + return s.GetComposer(); + case 7: + return s.GetPerformer(); case 8: + return s.GetDisc(); + case 9: + return s.GetComment(); + case 11: return s.GetNewName().empty() ? s.GetName() : s.GetName() + " [." + Config.color2 + "]->[/" + Config.color2 + "] " + s.GetNewName(); default: return ""; @@ -92,6 +103,9 @@ bool GetSongTags(Song &s) return false; s.SetComment(f.tag()->comment().to8Bit(UNICODE)); + string ext = s.GetFile(); + ext = ext.substr(ext.find_last_of(".")+1); + mTagEditor->Clear(); mTagEditor->Reset(); @@ -111,6 +125,9 @@ bool GetSongTags(Song &s) mTagEditor->AddOption("[.b]Year:[/b] " + s.GetYear()); mTagEditor->AddOption("[.b]Track:[/b] " + s.GetTrack()); mTagEditor->AddOption("[.b]Genre:[/b] " + s.GetGenre()); + mTagEditor->AddOption("[.b]Composer:[/b] " + s.GetComposer(), 0, ext != "mp3" && ext != "flac"); + mTagEditor->AddOption("[.b]Performer:[/b] " + s.GetPerformer(), 0, ext != "mp3" && ext != "flac"); + mTagEditor->AddOption("[.b]Disc:[/b] " + s.GetDisc(), 0, ext != "mp3" && ext != "flac"); mTagEditor->AddOption("[.b]Comment:[/b] " + s.GetComment()); mTagEditor->AddSeparator(); mTagEditor->AddOption("[.b]Filename:[/b] " + s.GetName()); @@ -122,20 +139,57 @@ bool GetSongTags(Song &s) bool WriteTags(Song &s) { + using namespace TagLib; string path_to_file = Config.mpd_music_dir + s.GetFile(); - TagLib::FileRef f(path_to_file.c_str()); + FileRef f(path_to_file.c_str()); if (!f.isNull()) { s.GetEmptyFields(1); - f.tag()->setTitle(s.GetTitle()); + f.tag()->setTitle(TO_WSTRING(s.GetTitle())); f.tag()->setArtist(TO_WSTRING(s.GetArtist())); f.tag()->setAlbum(TO_WSTRING(s.GetAlbum())); f.tag()->setYear(StrToInt(s.GetYear())); f.tag()->setTrack(StrToInt(s.GetTrack())); f.tag()->setGenre(TO_WSTRING(s.GetGenre())); f.tag()->setComment(TO_WSTRING(s.GetComment())); - s.GetEmptyFields(0); f.save(); + + string ext = s.GetFile(); + ext = ext.substr(ext.find_last_of(".")+1); + ID3v2::Tag *tag = 0; + File *file = 0; + + if (ext == "mp3") + { + file = new MPEG::File(path_to_file.c_str()); + tag = ((MPEG::File *)file)->ID3v2Tag(); + } + else if (ext == "flac") + { + file = new FLAC::File(path_to_file.c_str()); + tag = ((FLAC::File *)file)->ID3v2Tag(); + } + if (file && tag) + { + ByteVector Composer("TCOM"); + ByteVector Performer("TOPE"); + ByteVector Disc("TPOS"); + ID3v2::Frame *ComposerFrame = new ID3v2::TextIdentificationFrame(Composer); + ID3v2::Frame *PerformerFrame = new ID3v2::TextIdentificationFrame(Performer); + ID3v2::Frame *DiscFrame = new ID3v2::TextIdentificationFrame(Disc); + ComposerFrame->setText(TO_WSTRING(s.GetComposer())); + PerformerFrame->setText(TO_WSTRING(s.GetPerformer())); + DiscFrame->setText(TO_WSTRING(s.GetDisc())); + tag->removeFrames(Composer); + tag->addFrame(ComposerFrame); + tag->removeFrames(Performer); + tag->addFrame(PerformerFrame); + tag->removeFrames(Disc); + tag->addFrame(DiscFrame); + file->save(); + delete file; + } + s.GetEmptyFields(0); if (!s.GetNewName().empty()) { string old_name = Config.mpd_music_dir + s.GetFile();