new feature: support for multiple tag types in one column
This commit is contained in:
207
src/display.cpp
207
src/display.cpp
@@ -28,7 +28,7 @@ std::string Display::Columns()
|
||||
if (Config.columns.empty())
|
||||
return "";
|
||||
|
||||
std::basic_string<my_char_t> result, tag;
|
||||
std::basic_string<my_char_t> result;
|
||||
size_t where = 0;
|
||||
int width;
|
||||
|
||||
@@ -46,57 +46,63 @@ std::string Display::Columns()
|
||||
else
|
||||
width = it->width*(it->fixed ? 1 : COLS/100.0);
|
||||
|
||||
if (it->name.empty())
|
||||
std::basic_string<my_char_t> tag;
|
||||
if (it->type.length() >= 1 && it->name.empty())
|
||||
{
|
||||
switch (it->type)
|
||||
for (size_t j = 0; j < it->type.length(); ++j)
|
||||
{
|
||||
case 'l':
|
||||
tag = U("Time");
|
||||
break;
|
||||
case 'f':
|
||||
tag = U("Filename");
|
||||
break;
|
||||
case 'D':
|
||||
tag = U("Directory");
|
||||
break;
|
||||
case 'a':
|
||||
tag = U("Artist");
|
||||
break;
|
||||
case 'A':
|
||||
tag = U("Album Artist");
|
||||
break;
|
||||
case 't':
|
||||
tag = U("Title");
|
||||
break;
|
||||
case 'b':
|
||||
tag = U("Album");
|
||||
break;
|
||||
case 'y':
|
||||
tag = U("Year");
|
||||
break;
|
||||
case 'n':
|
||||
case 'N':
|
||||
tag = U("Track");
|
||||
break;
|
||||
case 'g':
|
||||
tag = U("Genre");
|
||||
break;
|
||||
case 'c':
|
||||
tag = U("Composer");
|
||||
break;
|
||||
case 'p':
|
||||
tag = U("Performer");
|
||||
break;
|
||||
case 'd':
|
||||
tag = U("Disc");
|
||||
break;
|
||||
case 'C':
|
||||
tag = U("Comment");
|
||||
break;
|
||||
default:
|
||||
tag.clear();
|
||||
break;
|
||||
switch (it->type[j])
|
||||
{
|
||||
case 'l':
|
||||
tag += U("Time");
|
||||
break;
|
||||
case 'f':
|
||||
tag += U("Filename");
|
||||
break;
|
||||
case 'D':
|
||||
tag += U("Directory");
|
||||
break;
|
||||
case 'a':
|
||||
tag += U("Artist");
|
||||
break;
|
||||
case 'A':
|
||||
tag += U("Album Artist");
|
||||
break;
|
||||
case 't':
|
||||
tag += U("Title");
|
||||
break;
|
||||
case 'b':
|
||||
tag += U("Album");
|
||||
break;
|
||||
case 'y':
|
||||
tag += U("Year");
|
||||
break;
|
||||
case 'n':
|
||||
case 'N':
|
||||
tag += U("Track");
|
||||
break;
|
||||
case 'g':
|
||||
tag += U("Genre");
|
||||
break;
|
||||
case 'c':
|
||||
tag += U("Composer");
|
||||
break;
|
||||
case 'p':
|
||||
tag += U("Performer");
|
||||
break;
|
||||
case 'd':
|
||||
tag += U("Disc");
|
||||
break;
|
||||
case 'C':
|
||||
tag += U("Comment");
|
||||
break;
|
||||
default:
|
||||
tag += U("?");
|
||||
break;
|
||||
}
|
||||
tag += '/';
|
||||
}
|
||||
tag.resize(tag.length()-1);
|
||||
}
|
||||
else
|
||||
tag = it->name;
|
||||
@@ -169,63 +175,66 @@ void Display::SongsInColumns(const MPD::Song &s, void *, Menu<MPD::Song> *menu)
|
||||
|
||||
MPD::Song::GetFunction get = 0;
|
||||
|
||||
switch (it->type)
|
||||
std::string tag;
|
||||
for (size_t i = 0; i < it->type.length(); ++i)
|
||||
{
|
||||
case 'l':
|
||||
get = &MPD::Song::GetLength;
|
||||
break;
|
||||
case 'D':
|
||||
get = &MPD::Song::GetDirectory;
|
||||
break;
|
||||
case 'f':
|
||||
get = &MPD::Song::GetName;
|
||||
break;
|
||||
case 'a':
|
||||
get = &MPD::Song::GetArtist;
|
||||
break;
|
||||
case 'A':
|
||||
get = &MPD::Song::GetAlbumArtist;
|
||||
break;
|
||||
case 'b':
|
||||
get = &MPD::Song::GetAlbum;
|
||||
break;
|
||||
case 'y':
|
||||
get = &MPD::Song::GetDate;
|
||||
break;
|
||||
case 'n':
|
||||
get = &MPD::Song::GetTrackNumber;
|
||||
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':
|
||||
if (!s.GetTitle().empty())
|
||||
get = &MPD::Song::GetTitle;
|
||||
else
|
||||
switch (it->type[i])
|
||||
{
|
||||
case 'l':
|
||||
get = &MPD::Song::GetLength;
|
||||
break;
|
||||
case 'D':
|
||||
get = &MPD::Song::GetDirectory;
|
||||
break;
|
||||
case 'f':
|
||||
get = &MPD::Song::GetName;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case 'a':
|
||||
get = &MPD::Song::GetArtist;
|
||||
break;
|
||||
case 'A':
|
||||
get = &MPD::Song::GetAlbumArtist;
|
||||
break;
|
||||
case 'b':
|
||||
get = &MPD::Song::GetAlbum;
|
||||
break;
|
||||
case 'y':
|
||||
get = &MPD::Song::GetDate;
|
||||
break;
|
||||
case 'n':
|
||||
get = &MPD::Song::GetTrackNumber;
|
||||
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;
|
||||
}
|
||||
tag = get ? s.GetTags(get) : "";
|
||||
if (!tag.empty())
|
||||
break;
|
||||
}
|
||||
if (!discard_colors && it->color != clDefault)
|
||||
*menu << it->color;
|
||||
whline(menu->Raw(), 32, menu->GetWidth()-where);
|
||||
std::string tag = get ? s.GetTags(get) : "";
|
||||
|
||||
// last column might need to be shrinked to make space for np/sel suffixes
|
||||
if (it == last)
|
||||
|
||||
@@ -356,7 +356,7 @@ std::string GetLineValue(std::string &line, char a, char b, bool once)
|
||||
++pos[0];
|
||||
std::string result = pos[0] >= 0 && pos[1] >= 0 ? line.substr(pos[0], pos[1]-pos[0]) : "";
|
||||
|
||||
// replace \a and \b to a and b respectively
|
||||
// replace \a and \b with a and b respectively
|
||||
char r1[] = "\\ ", r2[] = " ";
|
||||
r1[1] = r2[0] = a;
|
||||
Replace(result, r1, r2);
|
||||
|
||||
@@ -415,25 +415,7 @@ std::string Playlist::SongToString(const MPD::Song &s, void *data)
|
||||
|
||||
std::string Playlist::SongInColumnsToString(const MPD::Song &s, void *)
|
||||
{
|
||||
std::string result = "{";
|
||||
for (std::vector<Column>::const_iterator it = Config.columns.begin(); it != Config.columns.end(); ++it)
|
||||
{
|
||||
if (it->type == 't')
|
||||
{
|
||||
result += "{%t}|{%f}";
|
||||
}
|
||||
else
|
||||
{
|
||||
// tags should be put in additional braces as if they are not, the
|
||||
// tag that is not present within 'main' braces discards them all.
|
||||
result += "{%";
|
||||
result += it->type;
|
||||
result += "}";
|
||||
}
|
||||
result += " ";
|
||||
}
|
||||
result += "}";
|
||||
return s.toString(result);
|
||||
return s.toString(Config.song_in_columns_to_string_format);
|
||||
}
|
||||
|
||||
bool Playlist::Add(const MPD::Song &s, bool in_playlist, bool play, int position)
|
||||
|
||||
@@ -1149,13 +1149,7 @@ void NcmpcppConfig::Read()
|
||||
Column col;
|
||||
col.color = IntoColor(GetLineValue(song_list_columns_format, '[', ']', 1));
|
||||
std::string tag_type = GetLineValue(song_list_columns_format, '{', '}', 1);
|
||||
if (tag_type.length() > 0) // at least tag type was specified
|
||||
col.type = tag_type[0];
|
||||
else
|
||||
{
|
||||
col.type = 0;
|
||||
col.display_empty_tag = 0;
|
||||
}
|
||||
|
||||
col.fixed = *width.rbegin() == 'f';
|
||||
|
||||
// alternative name
|
||||
@@ -1166,20 +1160,51 @@ void NcmpcppConfig::Read()
|
||||
tag_type.resize(tag_type_colon_pos);
|
||||
}
|
||||
|
||||
for (std::string::const_iterator it = tag_type.begin()+(tag_type.length() > 0); it != tag_type.end(); ++it)
|
||||
if (!tag_type.empty())
|
||||
{
|
||||
switch (*it)
|
||||
size_t i = -1;
|
||||
|
||||
// extract tag types in format a|b|c etc.
|
||||
do
|
||||
col.type += tag_type[(++i)++]; // nice one.
|
||||
while (tag_type[i] == '|');
|
||||
|
||||
// apply attributes
|
||||
for (; i < tag_type.length(); ++i)
|
||||
{
|
||||
case 'r':
|
||||
col.right_alignment = 1;
|
||||
break;
|
||||
case 'E':
|
||||
col.display_empty_tag = 0;
|
||||
break;
|
||||
switch (tag_type[i])
|
||||
{
|
||||
case 'r':
|
||||
col.right_alignment = 1;
|
||||
break;
|
||||
case 'E':
|
||||
col.display_empty_tag = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // empty column
|
||||
col.display_empty_tag = 0;
|
||||
|
||||
col.width = StrToInt(width);
|
||||
columns.push_back(col);
|
||||
}
|
||||
|
||||
// generate format for converting tags in columns to string for Playlist::SongInColumnsToString()
|
||||
char tag[] = "{% }|";
|
||||
song_in_columns_to_string_format = "{";
|
||||
for (std::vector<Column>::const_iterator it = columns.begin(); it != columns.end(); ++it)
|
||||
{
|
||||
for (std::string::const_iterator j = it->type.begin(); j != it->type.end(); ++j)
|
||||
{
|
||||
tag[2] = *j;
|
||||
song_in_columns_to_string_format += tag;
|
||||
}
|
||||
*song_in_columns_to_string_format.rbegin() = ' ';
|
||||
}
|
||||
if (song_in_columns_to_string_format.length() == 1) // only '{'
|
||||
song_in_columns_to_string_format += '}';
|
||||
else
|
||||
*song_in_columns_to_string_format.rbegin() = '}';
|
||||
}
|
||||
|
||||
|
||||
@@ -43,9 +43,9 @@ struct Column
|
||||
Column() : right_alignment(0), display_empty_tag(1) { }
|
||||
|
||||
std::basic_string<my_char_t> name;
|
||||
std::string type;
|
||||
unsigned width;
|
||||
Color color;
|
||||
char type;
|
||||
bool fixed;
|
||||
bool right_alignment;
|
||||
bool display_empty_tag;
|
||||
@@ -157,6 +157,7 @@ struct NcmpcppConfig
|
||||
std::string song_window_title_format;
|
||||
std::string song_library_format;
|
||||
std::string tag_editor_album_format;
|
||||
std::string song_in_columns_to_string_format;
|
||||
std::string external_editor;
|
||||
std::string system_encoding;
|
||||
std::string execute_on_song_change;
|
||||
|
||||
Reference in New Issue
Block a user