From d7b635e276bc143df220534a184a728f18aba27a Mon Sep 17 00:00:00 2001 From: unK Date: Wed, 3 Sep 2008 11:04:21 +0200 Subject: [PATCH] support for columns view in playlist --- doc/ncmpcpprc | 19 +++++ src/helpers.cpp | 164 +++++++++++++++++++++++++++++++++++++++++ src/helpers.h | 2 + src/menu.h | 4 +- src/ncmpcpp.cpp | 26 ++++--- src/ncmpcpp.h | 4 - src/settings.cpp | 15 +++- src/settings.h | 4 +- src/song.cpp | 2 +- src/status_checker.cpp | 2 +- src/window.h | 4 + 11 files changed, 223 insertions(+), 23 deletions(-) diff --git a/doc/ncmpcpprc b/doc/ncmpcpprc index 0f5d6d2f..266619a7 100644 --- a/doc/ncmpcpprc +++ b/doc/ncmpcpprc @@ -74,12 +74,31 @@ # #selected_item_suffix = "[/magenta]" # +##### columns settings ##### +## +## syntax of song columns list format is "column column etc." +## +## - syntax for each column is: +## +## (width of column in %)[column's color]{displayed tag} +## +## - color is optional (if it's not present, default window color will be used) +## +# +#song_columns_list_format = "(8)[green]{l} (28)[cyan]{a} (28)[yellow]{b} (50)[red]{t}" +# ##### various settings ##### # +## can be "normal" or "columns" +# +#playlist_display_mode = "normal" +# #autocenter_mode = "no" # #repeat_one_mode = "no" # +## can be "wrapped" or "normal" +# #default_find_mode = "wrapped" # #default_space_mode = "add" diff --git a/src/helpers.cpp b/src/helpers.cpp index 4926c10a..8a792fda 100644 --- a/src/helpers.cpp +++ b/src/helpers.cpp @@ -332,6 +332,170 @@ string DisplayItem(const Item &item, void *) } } +string DisplayColumns(string song_template) +{ + vector cols; + for (int i = song_template.find(" "); i != string::npos; i = song_template.find(" ")) + { + cols.push_back(song_template.substr(0, i)); + song_template = song_template.substr(i+1); + } + cols.push_back(song_template); + + string result, v; + + for (vector::const_iterator it = cols.begin(); it != cols.end(); it++) + { + int width = StrToInt(GetLineValue(*it, '(', ')')); + char type = GetLineValue(*it, '{', '}')[0]; + + width *= COLS/100.0; + + switch (type) + { + case 'l': + v = "Time"; + break; + case 'f': + v = "Filename"; + break; + case 'F': + v = "Full filename"; + break; + case 'a': + v = "Artist"; + break; + case 't': + v = "Title"; + break; + case 'b': + v = "Album"; + break; + case 'y': + v = "Year"; + break; + case 'n': + v = "Track"; + break; + case 'g': + v = "Genre"; + break; + case 'c': + v = "Composer"; + break; + case 'p': + v = "Performer"; + break; + case 'd': + v = "Disc"; + break; + case 'C': + v = "Comment"; + break; + default: + break; + } + + v = v.substr(0, width-1); + for (int i = v.length(); i < width; i++, v += " "); + result += v; + } + + return result.substr(0, COLS); +} + +string DisplaySongInColumns(const Song &s, void *s_template) +{ + string song_template = s_template ? *static_cast(s_template) : ""; + + vector cols; + for (int i = song_template.find(" "); i != string::npos; i = song_template.find(" ")) + { + cols.push_back(song_template.substr(0, i)); + song_template = song_template.substr(i+1); + } + cols.push_back(song_template); + + ncmpcpp_string_t result, v; + +# ifdef UTF8_ENABLED + const wstring space = L" "; + const wstring open_col = L"[."; + const wstring close_col = L"]"; + const wstring close_col2 = L"[/red]"; +# else + const string space = " "; + const string open_col = "[."; + const string close_col = "]"; + const string close_col2 = "[/red]"; +# endif + + for (vector::const_iterator it = cols.begin(); it != cols.end(); it++) + { + int width = StrToInt(GetLineValue(*it, '(', ')')); + ncmpcpp_string_t color = TO_WSTRING(GetLineValue(*it, '[', ']')); + char type = GetLineValue(*it, '{', '}')[0]; + + width *= COLS/100.0; + + string ss; + switch (type) + { + case 'l': + ss = s.GetLength(); + break; + case 'f': + ss = s.GetShortFilename(); + break; + case 'F': + ss = s.GetFile(); + break; + case 'a': + ss = s.GetArtist(); + break; + case 't': + ss = s.GetTitle(); + break; + case 'b': + ss = s.GetAlbum(); + break; + case 'y': + ss = s.GetYear(); + break; + case 'n': + ss = s.GetTrack(); + break; + case 'g': + ss = s.GetGenre(); + break; + case 'c': + ss = s.GetComposer(); + break; + case 'p': + ss = s.GetPerformer(); + break; + case 'd': + ss = s.GetDisc(); + break; + case 'C': + ss = s.GetComment(); + break; + default: + break; + } + + v = TO_WSTRING(OmitBBCodes(ss)).substr(0, width-1); + for (int i = v.length(); i < width; i++, v += space); + if (!color.empty()) + result += open_col + color + close_col; + result += v; + if (!color.empty()) + result += close_col2; + } + + return TO_STRING(result); +} + string DisplaySong(const Song &s, void *s_template) { const string &song_template = s_template ? *static_cast(s_template) : ""; diff --git a/src/helpers.h b/src/helpers.h index 5559bb0e..10c0aafa 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -48,6 +48,8 @@ bool CaseInsensitiveComparison(string, string); void WindowTitle(const string &); string TotalPlaylistLength(); string DisplayItem(const Item &, void * = NULL); +string DisplayColumns(string); +string DisplaySongInColumns(const Song &, void *); string DisplaySong(const Song &, void * = &Config.song_list_format); void ShowMessage(const string &, int = Config.message_delay_time); bool SortDirectory(const Item &a, const Item &b); diff --git a/src/menu.h b/src/menu.h index 50e6f79c..e6392d9e 100644 --- a/src/menu.h +++ b/src/menu.h @@ -126,7 +126,6 @@ class Menu : public Window bool itsHighlightEnabled; }; - template Menu::Menu(const Menu &m) : Window(m) { @@ -798,5 +797,8 @@ string Menu::DisplayOption(const T &t) const return itsItemDisplayer ? itsItemDisplayer(t, itsUserdata) : ""; } +template <> +string Menu::DisplayOption(const string &str) const; + #endif diff --git a/src/ncmpcpp.cpp b/src/ncmpcpp.cpp index 64fcb3c9..c4497cb0 100644 --- a/src/ncmpcpp.cpp +++ b/src/ncmpcpp.cpp @@ -189,11 +189,11 @@ int main(int argc, char *argv[]) if (!Config.statusbar_visibility) main_height++; - mPlaylist = new Menu(0, main_start_y, COLS, main_height, "", Config.main_color, brNone); + mPlaylist = new Menu(0, main_start_y, COLS, main_height, Config.columns_in_playlist ? DisplayColumns(Config.song_columns_list_format) : "", Config.main_color, brNone); mPlaylist->SetSelectPrefix(Config.selected_item_prefix); mPlaylist->SetSelectSuffix(Config.selected_item_suffix); - mPlaylist->SetItemDisplayer(DisplaySong); - mPlaylist->SetItemDisplayerUserData(&Config.song_list_format); + mPlaylist->SetItemDisplayer(Config.columns_in_playlist ? DisplaySongInColumns : DisplaySong); + mPlaylist->SetItemDisplayerUserData(Config.columns_in_playlist ? &Config.song_columns_list_format : &Config.song_list_format); mBrowser = new Menu(0, main_start_y, COLS, main_height, "", Config.main_color, brNone); mBrowser->SetSelectPrefix(Config.selected_item_prefix); @@ -339,8 +339,6 @@ int main(int argc, char *argv[]) wCurrent = mPlaylist; current_screen = csPlaylist; - wCurrent->Display(); - int input; timer = time(NULL); @@ -431,7 +429,7 @@ int main(int argc, char *argv[]) if (current_screen == csBrowser) { int max_length_without_scroll = wHeader->GetWidth()-volume_state.length()-title.length(); - ncmpcpp_string_t wbrowseddir = NCMPCPP_TO_WSTRING(browsed_dir); + ncmpcpp_string_t wbrowseddir = TO_WSTRING(browsed_dir); wHeader->Bold(1); if (browsed_dir.length() > max_length_without_scroll) { @@ -626,7 +624,10 @@ int main(int argc, char *argv[]) // playlist editor end - wCurrent->Refresh(redraw_me); + if (Config.columns_in_playlist && wCurrent == mPlaylist) + wCurrent->Display(redraw_me); + else + wCurrent->Refresh(redraw_me); redraw_me = 0; wCurrent->ReadKey(input); @@ -722,6 +723,7 @@ int main(int argc, char *argv[]) sHelp->Resize(COLS, main_height); sHelp->Timeout(ncmpcpp_window_timeout); mPlaylist->Resize(COLS, main_height); + mPlaylist->SetTitle(Config.columns_in_playlist ? DisplayColumns(Config.song_columns_list_format) : ""); mBrowser->Resize(COLS, main_height); mTagEditor->Resize(COLS, main_height); mSearcher->Resize(COLS, main_height); @@ -926,13 +928,13 @@ int main(int argc, char *argv[]) { ShowMessage("Updating tags..."); s.GetEmptyFields(1); - f.tag()->setTitle(NCMPCPP_TO_WSTRING(s.GetTitle())); - f.tag()->setArtist(NCMPCPP_TO_WSTRING(s.GetArtist())); - f.tag()->setAlbum(NCMPCPP_TO_WSTRING(s.GetAlbum())); + 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(NCMPCPP_TO_WSTRING(s.GetGenre())); - f.tag()->setComment(NCMPCPP_TO_WSTRING(s.GetComment())); + f.tag()->setGenre(TO_WSTRING(s.GetGenre())); + f.tag()->setComment(TO_WSTRING(s.GetComment())); s.GetEmptyFields(0); f.save(); ShowMessage("Tags updated!"); diff --git a/src/ncmpcpp.h b/src/ncmpcpp.h index 33f7147e..b94466f3 100644 --- a/src/ncmpcpp.h +++ b/src/ncmpcpp.h @@ -27,12 +27,8 @@ #ifdef UTF8_ENABLED const bool UNICODE = 1; -# define ncmpcpp_string_t wstring -# define NCMPCPP_TO_WSTRING(x) ToWString(x) #else const bool UNICODE = 0; -# define ncmpcpp_string_t string -# define NCMPCPP_TO_WSTRING(x) (x) #endif #ifdef HAVE_TAGLIB_H diff --git a/src/settings.cpp b/src/settings.cpp index 9c6103e2..9583a96d 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -144,6 +144,7 @@ void DefaultConfiguration(ncmpcpp_config &conf) { conf.mpd_music_dir = "/var/lib/mpd/music"; conf.song_list_format = "{[.green](%l)[/green] }{%a - }{%t}|{[.white]%f[/white]}"; + conf.song_columns_list_format = "(8)[green]{l} (28)[cyan]{a} (28){b} (50)[red]{t}"; conf.song_status_format = "{(%l) }{%a - }{%t}|{%f}"; conf.song_window_title_format = "{%a - }{%t}|{%f}"; conf.song_library_format = "{%n - }{%t}|{%f}"; @@ -161,6 +162,7 @@ void DefaultConfiguration(ncmpcpp_config &conf) conf.statusbar_color = clDefault; conf.active_column_color = clRed; conf.colors_enabled = true; + conf.columns_in_playlist = false; conf.header_visibility = true; conf.statusbar_visibility = true; conf.autocenter_mode = false; @@ -197,13 +199,13 @@ void GetKeys(string line, int *key) key[1] = !two.empty() && two[0] == '\'' ? two[1] : (atoi(two.c_str()) == 0 ? null_key : atoi(two.c_str())); } -string GetConfigLineValue(const string &line) +string GetLineValue(const string &line, char a, char b) { int i = 0; int begin = -1, end = -1; for (string::const_iterator it = line.begin(); it != line.end(); i++, it++) { - if (*it == '"') + if (*it == a || *it == b) { if (begin < 0) begin = i+1; @@ -414,7 +416,7 @@ void ReadConfiguration(ncmpcpp_config &conf) } for (vector::const_iterator it = config_sets.begin(); it != config_sets.end(); it++) { - v = GetConfigLineValue(*it); + v = GetLineValue(*it); if (it->find("mpd_music_dir") != string::npos) { @@ -446,6 +448,11 @@ void ReadConfiguration(ncmpcpp_config &conf) if (!v.empty()) conf.song_list_format = v; } + else if (it->find("song_columns_list_format") != string::npos) + { + if (!v.empty()) + conf.song_columns_list_format = v; + } else if (it->find("song_status_format") != string::npos) { if (!v.empty()) @@ -473,6 +480,8 @@ void ReadConfiguration(ncmpcpp_config &conf) } else if (it->find("colors_enabled") != string::npos) conf.colors_enabled = v == "yes"; + else if (it->find("playlist_display_mode") != string::npos) + conf.columns_in_playlist = v == "columns"; else if (it->find("header_visibility") != string::npos) conf.header_visibility = v == "yes"; else if (it->find("statusbar_visibility") != string::npos) diff --git a/src/settings.h b/src/settings.h index 4e774668..282fb0e2 100644 --- a/src/settings.h +++ b/src/settings.h @@ -90,6 +90,7 @@ struct ncmpcpp_config { string mpd_music_dir; string song_list_format; + string song_columns_list_format; string song_status_format; string song_window_title_format; string song_library_format; @@ -110,6 +111,7 @@ struct ncmpcpp_config Color active_column_color; bool colors_enabled; + bool columns_in_playlist; bool set_window_title; bool header_visibility; bool statusbar_visibility; @@ -127,7 +129,7 @@ struct ncmpcpp_config void DefaultKeys(ncmpcpp_keys &); void DefaultConfiguration(ncmpcpp_config &); void GetKeys(string, int *); -string GetLineValue(const string &); +string GetLineValue(const string &, char = '"', char = '"'); string IntoStr(Color); Color IntoColor(const string &); void ReadKeys(ncmpcpp_keys &); diff --git a/src/song.cpp b/src/song.cpp index e3f0c4ac..951f4360 100644 --- a/src/song.cpp +++ b/src/song.cpp @@ -87,7 +87,7 @@ string Song::GetLength() const std::stringstream ss; if (!GetTotalLength()) - return "unknown"; + return "-:--"; ss << itsMinutesLength << ":"; if (!itsSecondsLength) diff --git a/src/status_checker.cpp b/src/status_checker.cpp index e000121e..ab6fb6bc 100644 --- a/src/status_checker.cpp +++ b/src/status_checker.cpp @@ -312,7 +312,7 @@ void NcmpcppStatusChanged(MPDConnection *Mpd, MPDStatusChanges changed, void *da tracklength = " [" + ShowTime(elapsed) + "/" + s.GetLength() + "]"; else tracklength = " [" + ShowTime(elapsed) + "]"; - ncmpcpp_string_t playing_song = NCMPCPP_TO_WSTRING(OmitBBCodes(DisplaySong(s, &Config.song_status_format))); + ncmpcpp_string_t playing_song = TO_WSTRING(OmitBBCodes(DisplaySong(s, &Config.song_status_format))); int max_length_without_scroll = wFooter->GetWidth()-player_state.length()-tracklength.length(); diff --git a/src/window.h b/src/window.h index dffba8d4..c0a4b2a2 100644 --- a/src/window.h +++ b/src/window.h @@ -30,9 +30,13 @@ #include #ifdef UTF8_ENABLED +# define ncmpcpp_string_t wstring # define TO_STRING(x) ToString(x) +# define TO_WSTRING(x) ToWString(x) #else +# define ncmpcpp_string_t string # define TO_STRING(x) x +# define TO_WSTRING(x) x #endif using std::string;