song format: support for nested braces
This commit is contained in:
120
src/display.cpp
120
src/display.cpp
@@ -23,6 +23,20 @@
|
||||
#include "helpers.h"
|
||||
#include "playlist.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
template <typename C, typename T> void ParseColors(const std::basic_string<C> &s, T &buf)
|
||||
{
|
||||
for (typename std::basic_string<C>::const_iterator it = s.begin(); it != s.end(); ++it)
|
||||
{
|
||||
if (*it == '$')
|
||||
buf << Color(*++it-'0');
|
||||
else
|
||||
buf << *it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string Display::Columns()
|
||||
{
|
||||
if (Config.columns.empty())
|
||||
@@ -208,109 +222,18 @@ void Display::Songs(const MPD::Song &s, void *data, Menu<MPD::Song> *menu)
|
||||
basic_buffer<my_char_t> buf;
|
||||
bool right = 0;
|
||||
|
||||
std::string::const_iterator goto_pos, prev_pos;
|
||||
|
||||
for (std::string::const_iterator it = song_template.begin(); it != song_template.end(); ++it)
|
||||
{
|
||||
CHECK_LINKED_TAGS:;
|
||||
if (*it == '{')
|
||||
while (*it == '{')
|
||||
{
|
||||
prev_pos = it;
|
||||
MPD::Song::GetFunction get = 0;
|
||||
for (; *it != '}'; ++it)
|
||||
{
|
||||
if (*it == '%')
|
||||
{
|
||||
switch (*++it)
|
||||
{
|
||||
case 'l':
|
||||
get = &MPD::Song::GetLength;
|
||||
break;
|
||||
case 'F':
|
||||
get = &MPD::Song::GetFile;
|
||||
break;
|
||||
case 'f':
|
||||
get = &MPD::Song::GetName;
|
||||
break;
|
||||
case 'a':
|
||||
get = &MPD::Song::GetArtist;
|
||||
break;
|
||||
case 'b':
|
||||
get = &MPD::Song::GetAlbum;
|
||||
break;
|
||||
case 'y':
|
||||
get = &MPD::Song::GetDate;
|
||||
break;
|
||||
case 'n':
|
||||
get = &MPD::Song::GetTrack;
|
||||
break;
|
||||
case 'g':
|
||||
get = &MPD::Song::GetGenre;
|
||||
break;
|
||||
case 'c':
|
||||
get = &MPD::Song::GetComposer;
|
||||
break;
|
||||
case 'p':
|
||||
get = &MPD::Song::GetPerformer;
|
||||
break;
|
||||
case 'd':
|
||||
get = &MPD::Song::GetDisc;
|
||||
break;
|
||||
case 'C':
|
||||
get = &MPD::Song::GetComment;
|
||||
break;
|
||||
case 't':
|
||||
get = &MPD::Song::GetTitle;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (get == &MPD::Song::GetLength)
|
||||
{
|
||||
if (!s.GetTotalLength())
|
||||
break;
|
||||
}
|
||||
else if (get)
|
||||
{
|
||||
if ((s.*get)().empty())
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (*it == '}')
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
if (*it == '}' && *(it+1) != '|')
|
||||
break;
|
||||
++it;
|
||||
}
|
||||
goto_pos = ++it;
|
||||
it = ++prev_pos;
|
||||
}
|
||||
std::string tags = s.Format_ParseBraces(it, song_template.end());
|
||||
if (!right)
|
||||
ParseColors(tags, *menu);
|
||||
else
|
||||
{
|
||||
for (; *it != '}'; ++it) { }
|
||||
++it;
|
||||
if (it == song_template.end())
|
||||
break;
|
||||
if (*it == '{' || *it == '|')
|
||||
{
|
||||
if (*it == '|')
|
||||
++it;
|
||||
goto CHECK_LINKED_TAGS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (*it == '}')
|
||||
{
|
||||
if (goto_pos == song_template.end())
|
||||
break;
|
||||
it = goto_pos;
|
||||
if (*it == '{')
|
||||
goto CHECK_LINKED_TAGS;
|
||||
ParseColors(TO_WSTRING(tags), buf);
|
||||
}
|
||||
if (it == song_template.end())
|
||||
break;
|
||||
|
||||
if (*it != '%' && *it != '$')
|
||||
{
|
||||
@@ -416,6 +339,7 @@ void Display::Songs(const MPD::Song &s, void *data, Menu<MPD::Song> *menu)
|
||||
else
|
||||
buf << Color(*it-'0');
|
||||
}
|
||||
|
||||
}
|
||||
if (right)
|
||||
{
|
||||
|
||||
211
src/song.cpp
211
src/song.cpp
@@ -289,118 +289,115 @@ void MPD::Song::SetPosition(int pos)
|
||||
itsSong->pos = pos;
|
||||
}
|
||||
|
||||
std::string MPD::Song::Format_ParseBraces(std::string::const_iterator &it, std::string::const_iterator end_it) const
|
||||
{
|
||||
std::string result;
|
||||
bool has_some_tags = 0;
|
||||
MPD::Song::GetFunction get = 0;
|
||||
while (*++it != '}')
|
||||
{
|
||||
while (*it == '{')
|
||||
{
|
||||
std::string tags = Format_ParseBraces(it, end_it);
|
||||
if (!tags.empty())
|
||||
{
|
||||
has_some_tags = 1;
|
||||
result += tags;
|
||||
}
|
||||
}
|
||||
if (*it == '}')
|
||||
break;
|
||||
else if (it == end_it)
|
||||
return "";
|
||||
|
||||
if (*it == '%')
|
||||
{
|
||||
switch (*++it)
|
||||
{
|
||||
case 'l':
|
||||
get = &MPD::Song::GetLength;
|
||||
break;
|
||||
case 'F':
|
||||
get = &MPD::Song::GetFile;
|
||||
break;
|
||||
case 'f':
|
||||
get = &MPD::Song::GetName;
|
||||
break;
|
||||
case 'a':
|
||||
get = &MPD::Song::GetArtist;
|
||||
break;
|
||||
case 'b':
|
||||
get = &MPD::Song::GetAlbum;
|
||||
break;
|
||||
case 'y':
|
||||
get = &MPD::Song::GetDate;
|
||||
break;
|
||||
case 'n':
|
||||
get = &MPD::Song::GetTrack;
|
||||
break;
|
||||
case 'g':
|
||||
get = &MPD::Song::GetGenre;
|
||||
break;
|
||||
case 'c':
|
||||
get = &MPD::Song::GetComposer;
|
||||
break;
|
||||
case 'p':
|
||||
get = &MPD::Song::GetPerformer;
|
||||
break;
|
||||
case 'd':
|
||||
get = &MPD::Song::GetDisc;
|
||||
break;
|
||||
case 'C':
|
||||
get = &MPD::Song::GetComment;
|
||||
break;
|
||||
case 't':
|
||||
get = &MPD::Song::GetTitle;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (get)
|
||||
{
|
||||
std::string tag = (this->*get)();
|
||||
if (!tag.empty() && (get != &MPD::Song::GetLength || GetTotalLength()))
|
||||
{
|
||||
has_some_tags = 1;
|
||||
result += tag;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
result += *it;
|
||||
}
|
||||
if (*it != '}' || !has_some_tags)
|
||||
{
|
||||
for (; *it != '}'; ++it) { }
|
||||
if (*++it == '|')
|
||||
return Format_ParseBraces(++it, end_it);
|
||||
else
|
||||
return "";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*++it == '|')
|
||||
for (; *it != '}' || *++it == '|'; ++it) { }
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
std::string MPD::Song::toString(const std::string &format) const
|
||||
{
|
||||
std::string result;
|
||||
std::string::const_iterator goto_pos, prev_pos;
|
||||
|
||||
for (std::string::const_iterator it = format.begin(); it != format.end(); ++it)
|
||||
{
|
||||
CHECK_LINKED_TAGS:;
|
||||
if (*it == '{')
|
||||
{
|
||||
prev_pos = it;
|
||||
GetFunction get = 0;
|
||||
for (; *it != '}'; ++it)
|
||||
{
|
||||
if (*it == '%')
|
||||
{
|
||||
switch (*++it)
|
||||
{
|
||||
case 'l':
|
||||
get = &Song::GetLength;
|
||||
break;
|
||||
case 'F':
|
||||
get = &Song::GetFile;
|
||||
break;
|
||||
case 'f':
|
||||
get = &Song::GetName;
|
||||
break;
|
||||
case 'a':
|
||||
get = &Song::GetArtist;
|
||||
break;
|
||||
case 'b':
|
||||
get = &Song::GetAlbum;
|
||||
break;
|
||||
case 'y':
|
||||
get = &Song::GetDate;
|
||||
break;
|
||||
case 'n':
|
||||
get = &Song::GetTrack;
|
||||
break;
|
||||
case 'g':
|
||||
get = &Song::GetGenre;
|
||||
break;
|
||||
case 'c':
|
||||
get = &Song::GetComposer;
|
||||
break;
|
||||
case 'p':
|
||||
get = &Song::GetPerformer;
|
||||
break;
|
||||
case 'd':
|
||||
get = &Song::GetDisc;
|
||||
break;
|
||||
case 'C':
|
||||
get = &Song::GetComment;
|
||||
break;
|
||||
case 't':
|
||||
get = &Song::GetTitle;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (get == &Song::GetLength)
|
||||
{
|
||||
if (!GetTotalLength())
|
||||
break;
|
||||
}
|
||||
else if (get)
|
||||
{
|
||||
if ((this->*get)().empty())
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (*it == '}')
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
if (*it == '}' && *(it+1) != '|')
|
||||
break;
|
||||
++it;
|
||||
}
|
||||
goto_pos = ++it;
|
||||
it = ++prev_pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (; *it != '}'; ++it) { }
|
||||
++it;
|
||||
if (it == format.end())
|
||||
break;
|
||||
if (*it == '{' || *it == '|')
|
||||
{
|
||||
if (*it == '|')
|
||||
++it;
|
||||
goto CHECK_LINKED_TAGS;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (*it == '{')
|
||||
result += Format_ParseBraces(it, format.end());
|
||||
if (it == format.end())
|
||||
break;
|
||||
|
||||
if (*it == '}')
|
||||
{
|
||||
if (goto_pos == format.end())
|
||||
break;
|
||||
it = goto_pos;
|
||||
if (*it == '{')
|
||||
goto CHECK_LINKED_TAGS;
|
||||
}
|
||||
|
||||
if (*it != '%')
|
||||
{
|
||||
result += *it;
|
||||
}
|
||||
else if (*it == '%')
|
||||
if (*it == '%')
|
||||
{
|
||||
switch (*++it)
|
||||
{
|
||||
@@ -447,6 +444,8 @@ std::string MPD::Song::toString(const std::string &format) const
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
result += *it;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -92,6 +92,7 @@ namespace MPD
|
||||
Song &operator=(const Song &);
|
||||
|
||||
static std::string ShowTime(int);
|
||||
std::string Format_ParseBraces(std::string::const_iterator &it, std::string::const_iterator end_it) const;
|
||||
private:
|
||||
void SetHashAndSlash();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user