add support for multiple tags
This commit is contained in:
@@ -186,7 +186,7 @@ void Display::SongsInColumns(const MPD::Song &s, void *, Menu<MPD::Song> *menu)
|
||||
if (it->color != clDefault)
|
||||
*menu << it->color;
|
||||
whline(menu->Raw(), 32, menu->GetWidth()-where);
|
||||
std::string tag = get ? (s.*get)() : "";
|
||||
std::string tag = get ? s.GetTags(get) : "";
|
||||
if (it->right_alignment)
|
||||
{
|
||||
if (!tag.empty() || it->display_empty_tag)
|
||||
@@ -267,34 +267,34 @@ void Display::Tags(const MPD::Song &s, void *data, Menu<MPD::Song> *menu)
|
||||
switch (static_cast<Menu<std::string> *>(data)->Choice())
|
||||
{
|
||||
case 0:
|
||||
ShowTag(*menu, s.GetTitle());
|
||||
ShowTag(*menu, s.GetTags(&MPD::Song::GetTitle));
|
||||
return;
|
||||
case 1:
|
||||
ShowTag(*menu, s.GetArtist());
|
||||
ShowTag(*menu, s.GetTags(&MPD::Song::GetArtist));
|
||||
return;
|
||||
case 2:
|
||||
ShowTag(*menu, s.GetAlbum());
|
||||
ShowTag(*menu, s.GetTags(&MPD::Song::GetAlbum));
|
||||
return;
|
||||
case 3:
|
||||
ShowTag(*menu, s.GetDate());
|
||||
ShowTag(*menu, s.GetTags(&MPD::Song::GetDate));
|
||||
return;
|
||||
case 4:
|
||||
ShowTag(*menu, s.GetTrack());
|
||||
ShowTag(*menu, s.GetTags(&MPD::Song::GetTrack));
|
||||
return;
|
||||
case 5:
|
||||
ShowTag(*menu, s.GetGenre());
|
||||
ShowTag(*menu, s.GetTags(&MPD::Song::GetGenre));
|
||||
return;
|
||||
case 6:
|
||||
ShowTag(*menu, s.GetComposer());
|
||||
ShowTag(*menu, s.GetTags(&MPD::Song::GetComposer));
|
||||
return;
|
||||
case 7:
|
||||
ShowTag(*menu, s.GetPerformer());
|
||||
ShowTag(*menu, s.GetTags(&MPD::Song::GetPerformer));
|
||||
return;
|
||||
case 8:
|
||||
ShowTag(*menu, s.GetDisc());
|
||||
ShowTag(*menu, s.GetTags(&MPD::Song::GetDisc));
|
||||
return;
|
||||
case 9:
|
||||
ShowTag(*menu, s.GetComment());
|
||||
ShowTag(*menu, s.GetTags(&MPD::Song::GetComment));
|
||||
return;
|
||||
case 11:
|
||||
if (s.GetNewName().empty())
|
||||
|
||||
40
src/info.cpp
40
src/info.cpp
@@ -55,6 +55,21 @@ pthread_t *Info::Downloader = 0;
|
||||
|
||||
Info *myInfo = new Info;
|
||||
|
||||
const Info::Metadata Info::Tags[] =
|
||||
{
|
||||
{ "Title", &MPD::Song::GetTitle, &MPD::Song::SetTitle },
|
||||
{ "Artist", &MPD::Song::GetArtist, &MPD::Song::SetArtist },
|
||||
{ "Album", &MPD::Song::GetAlbum, &MPD::Song::SetAlbum },
|
||||
{ "Year", &MPD::Song::GetDate, &MPD::Song::SetDate },
|
||||
{ "Track", &MPD::Song::GetTrack, &MPD::Song::SetTrack },
|
||||
{ "Genre", &MPD::Song::GetGenre, &MPD::Song::SetGenre },
|
||||
{ "Composer", &MPD::Song::GetComposer, &MPD::Song::SetComposer },
|
||||
{ "Performer", &MPD::Song::GetPerformer, &MPD::Song::SetPerformer },
|
||||
{ "Disc", &MPD::Song::GetDisc, &MPD::Song::SetDisc },
|
||||
{ "Comment", &MPD::Song::GetComment, &MPD::Song::SetComment },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
void Info::Init()
|
||||
{
|
||||
w = new Scrollpad(0, MainStartY, COLS, MainHeight, "", Config.main_color, brNone);
|
||||
@@ -372,25 +387,10 @@ void Info::PrepareSong(MPD::Song &s)
|
||||
# endif // HAVE_TAGLIB_H
|
||||
*w << clDefault;
|
||||
|
||||
*w << fmtBold << "\nTitle: " << fmtBoldEnd;
|
||||
ShowTag(*w, s.GetTitle());
|
||||
*w << fmtBold << "\nArtist: " << fmtBoldEnd;
|
||||
ShowTag(*w, s.GetArtist());
|
||||
*w << fmtBold << "\nAlbum: " << fmtBoldEnd;
|
||||
ShowTag(*w, s.GetAlbum());
|
||||
*w << fmtBold << "\nYear: " << fmtBoldEnd;
|
||||
ShowTag(*w, s.GetDate());
|
||||
*w << fmtBold << "\nTrack: " << fmtBoldEnd;
|
||||
ShowTag(*w, s.GetTrack());
|
||||
*w << fmtBold << "\nGenre: " << fmtBoldEnd;
|
||||
ShowTag(*w, s.GetGenre());
|
||||
*w << fmtBold << "\nComposer: " << fmtBoldEnd;
|
||||
ShowTag(*w, s.GetComposer());
|
||||
*w << fmtBold << "\nPerformer: " << fmtBoldEnd;
|
||||
ShowTag(*w, s.GetPerformer());
|
||||
*w << fmtBold << "\nDisc: " << fmtBoldEnd;
|
||||
ShowTag(*w, s.GetDisc());
|
||||
*w << fmtBold << "\nComment: " << fmtBoldEnd;
|
||||
ShowTag(*w, s.GetComment());
|
||||
for (const Metadata *m = Tags; m->Name; ++m)
|
||||
{
|
||||
*w << fmtBold << "\n" << m->Name << ": " << fmtBoldEnd;
|
||||
ShowTag(*w, s.GetTags(m->Get));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,13 @@
|
||||
class Info : public Screen<Scrollpad>
|
||||
{
|
||||
public:
|
||||
struct Metadata
|
||||
{
|
||||
const char *Name;
|
||||
MPD::Song::GetFunction Get;
|
||||
MPD::Song::SetFunction Set;
|
||||
};
|
||||
|
||||
virtual void SwitchTo() { }
|
||||
virtual void Resize();
|
||||
|
||||
@@ -49,6 +56,8 @@ class Info : public Screen<Scrollpad>
|
||||
void GetArtist();
|
||||
# endif // HAVE_CURL_CURL_H
|
||||
|
||||
static const Metadata Tags[];
|
||||
|
||||
protected:
|
||||
virtual void Init();
|
||||
|
||||
|
||||
@@ -1369,7 +1369,7 @@ int main(int argc, char *argv[])
|
||||
for (SongList::iterator it = list.begin(); it != list.end(); ++it)
|
||||
{
|
||||
(*it)->Localize();
|
||||
((*it)->*set)(new_tag);
|
||||
(*it)->SetTags(set, new_tag);
|
||||
ShowMessage("Updating tags in \"%s\"...", (*it)->GetName().c_str());
|
||||
std::string path = Config.mpd_music_dir + (*it)->GetFile();
|
||||
if (!TagEditor::WriteTags(**it))
|
||||
|
||||
@@ -323,7 +323,7 @@ bool Playlist::Sorting(MPD::Song *a, MPD::Song *b)
|
||||
{
|
||||
CaseInsensitiveStringComparison cmp;
|
||||
for (size_t i = 0; i < SortOptions; ++i)
|
||||
if (int ret = cmp((a->*(*SortDialog)[i].second)(), (b->*(*SortDialog)[i].second)()))
|
||||
if (int ret = cmp(a->GetTags((*SortDialog)[i].second), b->GetTags((*SortDialog)[i].second)))
|
||||
return ret < 0;
|
||||
return a->GetPosition() < b->GetPosition();
|
||||
}
|
||||
|
||||
149
src/song.cpp
149
src/song.cpp
@@ -74,8 +74,10 @@ MPD::Song::~Song()
|
||||
delete itsTags;
|
||||
}
|
||||
|
||||
std::string MPD::Song::GetLength() const
|
||||
std::string MPD::Song::GetLength(unsigned pos) const
|
||||
{
|
||||
if (pos > 0)
|
||||
return "";
|
||||
unsigned len = mpd_song_get_duration(itsSong);
|
||||
return !len ? "-:--" : ShowTime(len);
|
||||
}
|
||||
@@ -145,13 +147,15 @@ bool MPD::Song::isStream() const
|
||||
return !strncmp(MyFilename(), "http://", 7);
|
||||
}
|
||||
|
||||
std::string MPD::Song::GetFile() const
|
||||
std::string MPD::Song::GetFile(unsigned pos) const
|
||||
{
|
||||
return MyFilename();
|
||||
return pos > 0 ? "" : MyFilename();
|
||||
}
|
||||
|
||||
std::string MPD::Song::GetName() const
|
||||
std::string MPD::Song::GetName(unsigned pos) const
|
||||
{
|
||||
if (pos > 0)
|
||||
return "";
|
||||
std::string name = GetTag(MPD_TAG_NAME, 0);
|
||||
if (!name.empty())
|
||||
return name;
|
||||
@@ -161,9 +165,9 @@ std::string MPD::Song::GetName() const
|
||||
return MyFilename();
|
||||
}
|
||||
|
||||
std::string MPD::Song::GetDirectory() const
|
||||
std::string MPD::Song::GetDirectory(unsigned pos) const
|
||||
{
|
||||
if (isStream())
|
||||
if (pos > 0 || isStream())
|
||||
return "";
|
||||
else if (itsSlash == std::string::npos)
|
||||
return "/";
|
||||
@@ -171,30 +175,30 @@ std::string MPD::Song::GetDirectory() const
|
||||
return std::string(MyFilename(), itsSlash);
|
||||
}
|
||||
|
||||
std::string MPD::Song::GetArtist() const
|
||||
std::string MPD::Song::GetArtist(unsigned pos) const
|
||||
{
|
||||
return GetTag(MPD_TAG_ARTIST, 0);
|
||||
return GetTag(MPD_TAG_ARTIST, pos);
|
||||
}
|
||||
|
||||
std::string MPD::Song::GetTitle() const
|
||||
std::string MPD::Song::GetTitle(unsigned pos) const
|
||||
{
|
||||
return GetTag(MPD_TAG_TITLE, 0);
|
||||
return GetTag(MPD_TAG_TITLE, pos);
|
||||
}
|
||||
|
||||
std::string MPD::Song::GetAlbum() const
|
||||
std::string MPD::Song::GetAlbum(unsigned pos) const
|
||||
{
|
||||
return GetTag(MPD_TAG_ALBUM, 0);
|
||||
return GetTag(MPD_TAG_ALBUM, pos);
|
||||
}
|
||||
|
||||
std::string MPD::Song::GetTrack() const
|
||||
std::string MPD::Song::GetTrack(unsigned pos) const
|
||||
{
|
||||
std::string track = GetTag(MPD_TAG_TRACK, 0);
|
||||
std::string track = GetTag(MPD_TAG_TRACK, pos);
|
||||
return track.length() == 1 && track[0] != '0' ? "0"+track : track;
|
||||
}
|
||||
|
||||
std::string MPD::Song::GetTrackNumber() const
|
||||
std::string MPD::Song::GetTrackNumber(unsigned pos) const
|
||||
{
|
||||
std::string track = GetTag(MPD_TAG_TRACK, 0);
|
||||
std::string track = GetTag(MPD_TAG_TRACK, pos);
|
||||
size_t slash = track.find('/');
|
||||
if (slash != std::string::npos)
|
||||
{
|
||||
@@ -205,94 +209,107 @@ std::string MPD::Song::GetTrackNumber() const
|
||||
return track;
|
||||
}
|
||||
|
||||
std::string MPD::Song::GetDate() const
|
||||
std::string MPD::Song::GetDate(unsigned pos) const
|
||||
{
|
||||
return GetTag(MPD_TAG_DATE, 0);
|
||||
return GetTag(MPD_TAG_DATE, pos);
|
||||
}
|
||||
|
||||
std::string MPD::Song::GetGenre() const
|
||||
std::string MPD::Song::GetGenre(unsigned pos) const
|
||||
{
|
||||
return GetTag(MPD_TAG_GENRE, 0);
|
||||
return GetTag(MPD_TAG_GENRE, pos);
|
||||
}
|
||||
|
||||
std::string MPD::Song::GetComposer() const
|
||||
std::string MPD::Song::GetComposer(unsigned pos) const
|
||||
{
|
||||
return GetTag(MPD_TAG_COMPOSER, 0);
|
||||
return GetTag(MPD_TAG_COMPOSER, pos);
|
||||
}
|
||||
|
||||
std::string MPD::Song::GetPerformer() const
|
||||
std::string MPD::Song::GetPerformer(unsigned pos) const
|
||||
{
|
||||
return GetTag(MPD_TAG_PERFORMER, 0);
|
||||
return GetTag(MPD_TAG_PERFORMER, pos);
|
||||
}
|
||||
|
||||
std::string MPD::Song::GetDisc() const
|
||||
std::string MPD::Song::GetDisc(unsigned pos) const
|
||||
{
|
||||
return GetTag(MPD_TAG_DISC, 0);
|
||||
return GetTag(MPD_TAG_DISC, pos);
|
||||
}
|
||||
|
||||
std::string MPD::Song::GetComment() const
|
||||
std::string MPD::Song::GetComment(unsigned pos) const
|
||||
{
|
||||
return GetTag(MPD_TAG_COMMENT, 0);
|
||||
return GetTag(MPD_TAG_COMMENT, pos);
|
||||
}
|
||||
|
||||
void MPD::Song::SetArtist(const std::string &str)
|
||||
std::string MPD::Song::GetTags(GetFunction f) const
|
||||
{
|
||||
SetTag(MPD_TAG_ARTIST, 0, str);
|
||||
unsigned pos = 0;
|
||||
std::string result;
|
||||
for (std::string tag; !(tag = (this->*f)(pos)).empty(); ++pos)
|
||||
{
|
||||
if (!result.empty())
|
||||
result += ", ";
|
||||
result += tag;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void MPD::Song::SetTitle(const std::string &str)
|
||||
void MPD::Song::SetArtist(const std::string &str, unsigned pos)
|
||||
{
|
||||
SetTag(MPD_TAG_TITLE, 0, str);
|
||||
SetTag(MPD_TAG_ARTIST, pos, str);
|
||||
}
|
||||
|
||||
void MPD::Song::SetAlbum(const std::string &str)
|
||||
void MPD::Song::SetTitle(const std::string &str, unsigned pos)
|
||||
{
|
||||
SetTag(MPD_TAG_ALBUM, 0, str);
|
||||
SetTag(MPD_TAG_TITLE, pos, str);
|
||||
}
|
||||
|
||||
void MPD::Song::SetTrack(const std::string &str)
|
||||
void MPD::Song::SetAlbum(const std::string &str, unsigned pos)
|
||||
{
|
||||
SetTag(MPD_TAG_TRACK, 0, str);
|
||||
SetTag(MPD_TAG_ALBUM, pos, str);
|
||||
}
|
||||
|
||||
void MPD::Song::SetTrack(unsigned track)
|
||||
void MPD::Song::SetTrack(const std::string &str, unsigned pos)
|
||||
{
|
||||
SetTag(MPD_TAG_ARTIST, 0, IntoStr(track));
|
||||
SetTag(MPD_TAG_TRACK, pos, str);
|
||||
}
|
||||
|
||||
void MPD::Song::SetDate(const std::string &str)
|
||||
void MPD::Song::SetTrack(unsigned track, unsigned pos)
|
||||
{
|
||||
SetTag(MPD_TAG_DATE, 0, str);
|
||||
SetTag(MPD_TAG_ARTIST, pos, IntoStr(track));
|
||||
}
|
||||
|
||||
void MPD::Song::SetDate(unsigned year)
|
||||
void MPD::Song::SetDate(const std::string &str, unsigned pos)
|
||||
{
|
||||
SetTag(MPD_TAG_TRACK, 0, IntoStr(year));
|
||||
SetTag(MPD_TAG_DATE, pos, str);
|
||||
}
|
||||
|
||||
void MPD::Song::SetGenre(const std::string &str)
|
||||
void MPD::Song::SetDate(unsigned year, unsigned pos)
|
||||
{
|
||||
SetTag(MPD_TAG_GENRE, 0, str);
|
||||
SetTag(MPD_TAG_TRACK, pos, IntoStr(year));
|
||||
}
|
||||
|
||||
void MPD::Song::SetComposer(const std::string &str)
|
||||
void MPD::Song::SetGenre(const std::string &str, unsigned pos)
|
||||
{
|
||||
SetTag(MPD_TAG_COMPOSER, 0, str);
|
||||
SetTag(MPD_TAG_GENRE, pos, str);
|
||||
}
|
||||
|
||||
void MPD::Song::SetPerformer(const std::string &str)
|
||||
void MPD::Song::SetComposer(const std::string &str, unsigned pos)
|
||||
{
|
||||
SetTag(MPD_TAG_PERFORMER, 0, str);
|
||||
SetTag(MPD_TAG_COMPOSER, pos, str);
|
||||
}
|
||||
|
||||
void MPD::Song::SetDisc(const std::string &str)
|
||||
void MPD::Song::SetPerformer(const std::string &str, unsigned pos)
|
||||
{
|
||||
SetTag(MPD_TAG_DISC, 0, str);
|
||||
SetTag(MPD_TAG_PERFORMER, pos, str);
|
||||
}
|
||||
|
||||
void MPD::Song::SetComment(const std::string &str)
|
||||
void MPD::Song::SetDisc(const std::string &str, unsigned pos)
|
||||
{
|
||||
SetTag(MPD_TAG_COMMENT, 0, str);
|
||||
SetTag(MPD_TAG_DISC, pos, str);
|
||||
}
|
||||
|
||||
void MPD::Song::SetComment(const std::string &str, unsigned pos)
|
||||
{
|
||||
SetTag(MPD_TAG_COMMENT, pos, str);
|
||||
}
|
||||
|
||||
void MPD::Song::SetPosition(unsigned pos)
|
||||
@@ -300,6 +317,32 @@ void MPD::Song::SetPosition(unsigned pos)
|
||||
mpd_song_set_pos(itsSong, pos);
|
||||
}
|
||||
|
||||
void MPD::Song::SetTags(SetFunction f, const std::string &value)
|
||||
{
|
||||
unsigned pos = 0;
|
||||
// tag editor can save multiple instances of performer and composer
|
||||
// tag, so we need to split them and allow it to read them separately.
|
||||
if (f == &Song::SetComposer || f == &Song::SetPerformer)
|
||||
{
|
||||
for (size_t i = 0; i != std::string::npos; i = value.find(",", i))
|
||||
{
|
||||
if (i)
|
||||
++i;
|
||||
while (value[i] == ' ')
|
||||
++i;
|
||||
size_t j = value.find(",", i);
|
||||
(this->*f)(value.substr(i, j-i), pos++);
|
||||
}
|
||||
}
|
||||
else
|
||||
(this->*f)(value, pos++);
|
||||
// there should be empty tag at the end since if we are
|
||||
// reading them, original tag from mpd_song at the position
|
||||
// after the last one locally set can be non-empty and in this
|
||||
// case GetTags() would read it, which is undesirable.
|
||||
(this->*f)("", pos);
|
||||
}
|
||||
|
||||
std::string MPD::Song::ParseFormat(std::string::const_iterator &it, const char *escape_chars) const
|
||||
{
|
||||
std::string result;
|
||||
@@ -373,7 +416,7 @@ std::string MPD::Song::ParseFormat(std::string::const_iterator &it, const char *
|
||||
}
|
||||
if (get)
|
||||
{
|
||||
std::string tag = (this->*get)();
|
||||
std::string tag = GetTags(get);
|
||||
if (escape_chars) // prepend format escape character to all given chars to escape
|
||||
for (const char *ch = escape_chars; *ch; ++ch)
|
||||
for (size_t i = tag.find(*ch); i != std::string::npos; i = tag.find(*ch, i += 2))
|
||||
|
||||
62
src/song.h
62
src/song.h
@@ -34,48 +34,52 @@ namespace MPD
|
||||
|
||||
public:
|
||||
|
||||
typedef void (Song::*SetFunction)(const std::string &);
|
||||
typedef std::string (Song::*GetFunction)() const;
|
||||
typedef void (Song::*SetFunction)(const std::string &, unsigned);
|
||||
typedef std::string (Song::*GetFunction)(unsigned) const;
|
||||
|
||||
Song(mpd_song * = 0, bool = 0);
|
||||
Song(const Song &);
|
||||
~Song();
|
||||
|
||||
std::string GetFile() const;
|
||||
std::string GetName() const;
|
||||
std::string GetDirectory() const;
|
||||
std::string GetArtist() const;
|
||||
std::string GetTitle() const;
|
||||
std::string GetAlbum() const;
|
||||
std::string GetTrack() const;
|
||||
std::string GetTrackNumber() const;
|
||||
std::string GetDate() const;
|
||||
std::string GetGenre() const;
|
||||
std::string GetComposer() const;
|
||||
std::string GetPerformer() const;
|
||||
std::string GetDisc() const;
|
||||
std::string GetComment() const;
|
||||
std::string GetLength() const;
|
||||
std::string GetFile(unsigned = 0) const;
|
||||
std::string GetName(unsigned = 0) const;
|
||||
std::string GetDirectory(unsigned = 0) const;
|
||||
std::string GetArtist(unsigned = 0) const;
|
||||
std::string GetTitle(unsigned = 0) const;
|
||||
std::string GetAlbum(unsigned = 0) const;
|
||||
std::string GetTrack(unsigned = 0) const;
|
||||
std::string GetTrackNumber(unsigned = 0) const;
|
||||
std::string GetDate(unsigned = 0) const;
|
||||
std::string GetGenre(unsigned = 0) const;
|
||||
std::string GetComposer(unsigned = 0) const;
|
||||
std::string GetPerformer(unsigned = 0) const;
|
||||
std::string GetDisc(unsigned = 0) const;
|
||||
std::string GetComment(unsigned = 0) const;
|
||||
std::string GetLength(unsigned = 0) const;
|
||||
|
||||
std::string GetTags(GetFunction) const;
|
||||
|
||||
unsigned GetHash() const { return itsHash; }
|
||||
unsigned GetTotalLength() const { return mpd_song_get_duration(itsSong); }
|
||||
unsigned GetPosition() const { return mpd_song_get_pos(itsSong); }
|
||||
unsigned GetID() const { return mpd_song_get_id(itsSong); }
|
||||
|
||||
void SetArtist(const std::string &);
|
||||
void SetTitle(const std::string &);
|
||||
void SetAlbum(const std::string &);
|
||||
void SetTrack(const std::string &);
|
||||
void SetTrack(unsigned);
|
||||
void SetDate(const std::string &);
|
||||
void SetDate(unsigned);
|
||||
void SetGenre(const std::string &);
|
||||
void SetComposer(const std::string &);
|
||||
void SetPerformer(const std::string &);
|
||||
void SetDisc(const std::string &);
|
||||
void SetComment(const std::string &);
|
||||
void SetArtist(const std::string &, unsigned = 0);
|
||||
void SetTitle(const std::string &, unsigned = 0);
|
||||
void SetAlbum(const std::string &, unsigned = 0);
|
||||
void SetTrack(const std::string &, unsigned = 0);
|
||||
void SetTrack(unsigned, unsigned = 0);
|
||||
void SetDate(const std::string &, unsigned = 0);
|
||||
void SetDate(unsigned, unsigned = 0);
|
||||
void SetGenre(const std::string &, unsigned = 0);
|
||||
void SetComposer(const std::string &, unsigned = 0);
|
||||
void SetPerformer(const std::string &, unsigned = 0);
|
||||
void SetDisc(const std::string &, unsigned = 0);
|
||||
void SetComment(const std::string &, unsigned = 0);
|
||||
void SetPosition(unsigned);
|
||||
|
||||
void SetTags(SetFunction, const std::string &);
|
||||
|
||||
void SetNewName(const std::string &name) { itsNewName = name == GetName() ? "" : name; }
|
||||
std::string GetNewName() const { return itsNewName; }
|
||||
|
||||
|
||||
@@ -664,19 +664,19 @@ void TagEditor::EnterPressed()
|
||||
{
|
||||
LockStatusbar();
|
||||
Statusbar() << fmtBold << TagTypes->Current() << fmtBoldEnd << ": ";
|
||||
std::string new_tag = wFooter->GetString((Tags->Current().*get)());
|
||||
std::string new_tag = wFooter->GetString(Tags->Current().GetTags(get));
|
||||
UnlockStatusbar();
|
||||
for (MPD::SongList::iterator it = EditedSongs.begin(); it != EditedSongs.end(); ++it)
|
||||
(**it.*set)(new_tag);
|
||||
(*it)->SetTags(set, new_tag);
|
||||
}
|
||||
else if (w == Tags && set)
|
||||
{
|
||||
LockStatusbar();
|
||||
Statusbar() << fmtBold << TagTypes->Current() << fmtBoldEnd << ": ";
|
||||
std::string new_tag = wFooter->GetString((Tags->Current().*get)());
|
||||
std::string new_tag = wFooter->GetString(Tags->Current().GetTags(get));
|
||||
UnlockStatusbar();
|
||||
if (new_tag != (Tags->Current().*get)())
|
||||
(Tags->Current().*set)(new_tag);
|
||||
if (new_tag != Tags->Current().GetTags(get))
|
||||
Tags->Current().SetTags(set, new_tag);
|
||||
Tags->Scroll(wDown);
|
||||
}
|
||||
}
|
||||
@@ -918,12 +918,12 @@ void TagEditor::WriteXiphComments(const MPD::Song &s, TagLib::Ogg::XiphComment *
|
||||
tag->addField("DISCNUMBER", ToWString(s.GetDisc())); // disc
|
||||
|
||||
tag->removeField("COMPOSER"); // composer
|
||||
GetTagList(list, s.GetComposer());
|
||||
GetTagList(list, s, &MPD::Song::GetComposer);
|
||||
for (TagLib::StringList::ConstIterator it = list.begin(); it != list.end(); ++it)
|
||||
tag->addField("COMPOSER", *it, 0);
|
||||
|
||||
tag->removeField("PERFORMER"); // performer
|
||||
GetTagList(list, s.GetPerformer());
|
||||
GetTagList(list, s, &MPD::Song::GetPerformer);
|
||||
for (TagLib::StringList::ConstIterator it = list.begin(); it != list.end(); ++it)
|
||||
tag->addField("PERFORMER", *it, 0);
|
||||
}
|
||||
@@ -959,10 +959,10 @@ bool TagEditor::WriteTags(MPD::Song &s)
|
||||
WriteID3v2("TCON", tag, ToWString(s.GetGenre())); // genre
|
||||
WriteID3v2("TPOS", tag, ToWString(s.GetDisc())); // disc
|
||||
|
||||
GetTagList(list, s.GetComposer());
|
||||
GetTagList(list, s, &MPD::Song::GetComposer);
|
||||
WriteID3v2("TCOM", tag, list); // composer
|
||||
|
||||
GetTagList(list, s.GetPerformer());
|
||||
GetTagList(list, s, &MPD::Song::GetPerformer);
|
||||
// in >=mpd-0.16 treating TOPE frame as performer tag
|
||||
// was dropped in favor of TPE3/TPE4 frames, so we have
|
||||
// to write frame accurate to used mpd version
|
||||
@@ -1075,18 +1075,12 @@ void TagEditor::LowerAllLetters(MPD::Song &s)
|
||||
s.SetComment(conv);
|
||||
}
|
||||
|
||||
void TagEditor::GetTagList(TagLib::StringList &list, const std::string &s)
|
||||
void TagEditor::GetTagList(TagLib::StringList &list, const MPD::Song &s, MPD::Song::GetFunction f)
|
||||
{
|
||||
list.clear();
|
||||
for (size_t i = 0; i != std::string::npos; i = s.find(",", i))
|
||||
{
|
||||
if (i)
|
||||
++i;
|
||||
while (s[i] == ' ')
|
||||
++i;
|
||||
size_t j = s.find(",", i);
|
||||
list.append(ToWString(s.substr(i, j-i)));
|
||||
}
|
||||
unsigned pos = 0;
|
||||
for (std::string value; !(value = (s.*f)(pos)).empty(); ++pos)
|
||||
list.append(ToWString(value));
|
||||
}
|
||||
|
||||
std::string TagEditor::TagToString(const MPD::Song &s, void *data)
|
||||
@@ -1244,7 +1238,7 @@ std::string TagEditor::ParseFilename(MPD::Song &s, std::string mask, bool previe
|
||||
{
|
||||
MPD::Song::SetFunction set = IntoSetFunction(it->first);
|
||||
if (set)
|
||||
(s.*set)(it->second);
|
||||
s.SetTags(set, it->second);
|
||||
}
|
||||
else
|
||||
result << "%" << it->first << ": " << it->second << "\n";
|
||||
|
||||
@@ -96,7 +96,7 @@ class TagEditor : public Screen<Window>
|
||||
static std::string CapitalizeFirstLetters(const std::string &);
|
||||
static void CapitalizeFirstLetters(MPD::Song &);
|
||||
static void LowerAllLetters(MPD::Song &);
|
||||
static void GetTagList(TagLib::StringList &, const std::string &);
|
||||
static void GetTagList(TagLib::StringList &, const MPD::Song &, MPD::Song::GetFunction);
|
||||
static void WriteXiphComments(const MPD::Song &, TagLib::Ogg::XiphComment *);
|
||||
|
||||
static void GetPatternList();
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "charset.h"
|
||||
#include "display.h"
|
||||
#include "global.h"
|
||||
#include "info.h"
|
||||
#include "playlist.h"
|
||||
#include "search_engine.h"
|
||||
#include "tag_editor.h"
|
||||
@@ -93,137 +94,58 @@ std::basic_string<my_char_t> TinyTagEditor::Title()
|
||||
void TinyTagEditor::EnterPressed()
|
||||
{
|
||||
size_t option = w->Choice();
|
||||
LockStatusbar();
|
||||
|
||||
if (option >= 8 && option <= 20)
|
||||
w->at(option).Clear();
|
||||
|
||||
MPD::Song &s = itsEdited;
|
||||
|
||||
switch (option-7)
|
||||
if (option < 20) // separator after filename
|
||||
w->at(option).Clear();
|
||||
|
||||
LockStatusbar();
|
||||
if (option < 17) // separator after comment
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
Statusbar() << fmtBold << "Title: " << fmtBoldEnd;
|
||||
s.SetTitle(wFooter->GetString(s.GetTitle()));
|
||||
w->at(option) << fmtBold << "Title:" << fmtBoldEnd << ' ';
|
||||
ShowTag(w->at(option), s.GetTitle());
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
Statusbar() << fmtBold << "Artist: " << fmtBoldEnd;
|
||||
s.SetArtist(wFooter->GetString(s.GetArtist()));
|
||||
w->at(option) << fmtBold << "Artist:" << fmtBoldEnd << ' ';
|
||||
ShowTag(w->at(option), s.GetArtist());
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
Statusbar() << fmtBold << "Album: " << fmtBoldEnd;
|
||||
s.SetAlbum(wFooter->GetString(s.GetAlbum()));
|
||||
w->at(option) << fmtBold << "Album:" << fmtBoldEnd << ' ';
|
||||
ShowTag(w->at(option), s.GetAlbum());
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
Statusbar() << fmtBold << "Year: " << fmtBoldEnd;
|
||||
s.SetDate(wFooter->GetString(s.GetDate()));
|
||||
w->at(option) << fmtBold << "Year:" << fmtBoldEnd << ' ';
|
||||
ShowTag(w->at(option), s.GetDate());
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
Statusbar() << fmtBold << "Track: " << fmtBoldEnd;
|
||||
s.SetTrack(wFooter->GetString(s.GetTrack()));
|
||||
w->at(option) << fmtBold << "Track:" << fmtBoldEnd << ' ';
|
||||
ShowTag(w->at(option), s.GetTrack());
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
Statusbar() << fmtBold << "Genre: " << fmtBoldEnd;
|
||||
s.SetGenre(wFooter->GetString(s.GetGenre()));
|
||||
w->at(option) << fmtBold << "Genre:" << fmtBoldEnd << ' ';
|
||||
ShowTag(w->at(option), s.GetGenre());
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
Statusbar() << fmtBold << "Composer: " << fmtBoldEnd;
|
||||
s.SetComposer(wFooter->GetString(s.GetComposer()));
|
||||
w->at(option) << fmtBold << "Composer:" << fmtBoldEnd << ' ';
|
||||
ShowTag(w->at(option), s.GetComposer());
|
||||
break;
|
||||
}
|
||||
case 8:
|
||||
{
|
||||
Statusbar() << fmtBold << "Performer: " << fmtBoldEnd;
|
||||
s.SetPerformer(wFooter->GetString(s.GetPerformer()));
|
||||
w->at(option) << fmtBold << "Performer:" << fmtBoldEnd << ' ';
|
||||
ShowTag(w->at(option), s.GetPerformer());
|
||||
break;
|
||||
}
|
||||
case 9:
|
||||
{
|
||||
Statusbar() << fmtBold << "Disc: " << fmtBoldEnd;
|
||||
s.SetDisc(wFooter->GetString(s.GetDisc()));
|
||||
w->at(option) << fmtBold << "Disc:" << fmtBoldEnd << ' ';
|
||||
ShowTag(w->at(option), s.GetDisc());
|
||||
break;
|
||||
}
|
||||
case 10:
|
||||
{
|
||||
Statusbar() << fmtBold << "Comment: " << fmtBoldEnd;
|
||||
s.SetComment(wFooter->GetString(s.GetComment()));
|
||||
w->at(option) << fmtBold << "Comment:" << fmtBoldEnd << ' ';
|
||||
ShowTag(w->at(option), s.GetComment());
|
||||
break;
|
||||
}
|
||||
case 12:
|
||||
{
|
||||
Statusbar() << fmtBold << "Filename: " << fmtBoldEnd;
|
||||
std::string filename = s.GetNewName().empty() ? s.GetName() : s.GetNewName();
|
||||
size_t dot = filename.rfind(".");
|
||||
std::string extension = filename.substr(dot);
|
||||
filename = filename.substr(0, dot);
|
||||
std::string new_name = wFooter->GetString(filename);
|
||||
s.SetNewName(new_name + extension);
|
||||
w->at(option) << fmtBold << "Filename:" << fmtBoldEnd << ' ' << (s.GetNewName().empty() ? s.GetName() : s.GetNewName());
|
||||
break;
|
||||
}
|
||||
case 14:
|
||||
{
|
||||
ShowMessage("Updating tags...");
|
||||
if (TagEditor::WriteTags(s))
|
||||
{
|
||||
ShowMessage("Tags updated!");
|
||||
if (s.isFromDB())
|
||||
{
|
||||
Mpd.UpdateDirectory(locale_to_utf_cpy(s.GetDirectory()));
|
||||
if (myOldScreen == mySearcher) // songs from search engine are not updated automatically
|
||||
*mySearcher->Main()->Current().second = s;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (myOldScreen == myPlaylist)
|
||||
myPlaylist->Items->Current() = s;
|
||||
else if (myOldScreen == myBrowser)
|
||||
*myBrowser->Main()->Current().song = s;
|
||||
}
|
||||
}
|
||||
else
|
||||
ShowMessage("Error writing tags!");
|
||||
}
|
||||
case 15:
|
||||
{
|
||||
myOldScreen->SwitchTo();
|
||||
break;
|
||||
}
|
||||
size_t pos = option-8;
|
||||
Statusbar() << fmtBold << Info::Tags[pos].Name << ": " << fmtBoldEnd;
|
||||
s.SetTags(Info::Tags[pos].Set, wFooter->GetString(s.GetTags(Info::Tags[pos].Get)));
|
||||
w->at(option) << fmtBold << Info::Tags[pos].Name << ':' << fmtBoldEnd << ' ';
|
||||
ShowTag(w->at(option), s.GetTags(Info::Tags[pos].Get));
|
||||
}
|
||||
else if (option == 19)
|
||||
{
|
||||
Statusbar() << fmtBold << "Filename: " << fmtBoldEnd;
|
||||
std::string filename = s.GetNewName().empty() ? s.GetName() : s.GetNewName();
|
||||
size_t dot = filename.rfind(".");
|
||||
std::string extension = filename.substr(dot);
|
||||
filename = filename.substr(0, dot);
|
||||
std::string new_name = wFooter->GetString(filename);
|
||||
s.SetNewName(new_name + extension);
|
||||
w->at(option) << fmtBold << "Filename:" << fmtBoldEnd << ' ' << (s.GetNewName().empty() ? s.GetName() : s.GetNewName());
|
||||
}
|
||||
UnlockStatusbar();
|
||||
|
||||
if (option == 21)
|
||||
{
|
||||
ShowMessage("Updating tags...");
|
||||
if (TagEditor::WriteTags(s))
|
||||
{
|
||||
ShowMessage("Tags updated!");
|
||||
if (s.isFromDB())
|
||||
{
|
||||
Mpd.UpdateDirectory(locale_to_utf_cpy(s.GetDirectory()));
|
||||
if (myOldScreen == mySearcher) // songs from search engine are not updated automatically
|
||||
*mySearcher->Main()->Current().second = s;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (myOldScreen == myPlaylist)
|
||||
myPlaylist->Items->Current() = s;
|
||||
else if (myOldScreen == myBrowser)
|
||||
*myBrowser->Main()->Current().song = s;
|
||||
}
|
||||
}
|
||||
else
|
||||
ShowMessage("Error writing tags!");
|
||||
}
|
||||
if (option > 20)
|
||||
myOldScreen->SwitchTo();
|
||||
}
|
||||
|
||||
void TinyTagEditor::MouseButtonPressed(MEVENT me)
|
||||
@@ -301,29 +223,15 @@ bool TinyTagEditor::GetTags()
|
||||
w->at(5) << fmtBold << Config.color1 << "Sample rate: " << fmtBoldEnd << Config.color2 << f.audioProperties()->sampleRate() << " Hz" << clEnd;
|
||||
w->at(6) << fmtBold << Config.color1 << "Channels: " << fmtBoldEnd << Config.color2 << (f.audioProperties()->channels() == 1 ? "Mono" : "Stereo") << clDefault;
|
||||
|
||||
w->at(8) << fmtBold << "Title:" << fmtBoldEnd << ' ';
|
||||
ShowTag(w->at(8), s.GetTitle());
|
||||
w->at(9) << fmtBold << "Artist:" << fmtBoldEnd << ' ';
|
||||
ShowTag(w->at(9), s.GetArtist());
|
||||
w->at(10) << fmtBold << "Album:" << fmtBoldEnd << ' ';
|
||||
ShowTag(w->at(10), s.GetAlbum());
|
||||
w->at(11) << fmtBold << "Year:" << fmtBoldEnd << ' ';
|
||||
ShowTag(w->at(11), s.GetDate());
|
||||
w->at(12) << fmtBold << "Track:" << fmtBoldEnd << ' ';
|
||||
ShowTag(w->at(12), s.GetTrack());
|
||||
w->at(13) << fmtBold << "Genre:" << fmtBoldEnd << ' ';
|
||||
ShowTag(w->at(13), s.GetGenre());
|
||||
w->at(14) << fmtBold << "Composer:" << fmtBoldEnd << ' ';
|
||||
ShowTag(w->at(14), s.GetComposer());
|
||||
w->at(15) << fmtBold << "Performer:" << fmtBoldEnd << ' ';
|
||||
ShowTag(w->at(15), s.GetPerformer());
|
||||
w->at(16) << fmtBold << "Disc:" << fmtBoldEnd << ' ';
|
||||
ShowTag(w->at(16), s.GetDisc());
|
||||
w->at(17) << fmtBold << "Comment:" << fmtBoldEnd << ' ';
|
||||
ShowTag(w->at(17), s.GetComment());
|
||||
|
||||
unsigned pos = 8;
|
||||
for (const Info::Metadata *m = Info::Tags; m->Name; ++m, ++pos)
|
||||
{
|
||||
w->at(pos) << fmtBold << m->Name << ":" << fmtBoldEnd << ' ';
|
||||
ShowTag(w->at(pos), s.GetTags(m->Get));
|
||||
}
|
||||
|
||||
w->at(19) << fmtBold << "Filename:" << fmtBoldEnd << ' ' << s.GetName();
|
||||
|
||||
|
||||
w->at(21) << "Save";
|
||||
w->at(22) << "Cancel";
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user