summaryrefslogtreecommitdiff
path: root/src/display.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/display.cpp')
-rw-r--r--src/display.cpp548
1 files changed, 548 insertions, 0 deletions
diff --git a/src/display.cpp b/src/display.cpp
new file mode 100644
index 00000000..46f5fbc3
--- /dev/null
+++ b/src/display.cpp
@@ -0,0 +1,548 @@
+/***************************************************************************
+ * Copyright (C) 2008-2009 by Andrzej Rybczak *
+ * electricityispower@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include "display.h"
+#include "helpers.h"
+
+using MPD::Song;
+using std::string;
+
+string Display::Columns(string st)
+{
+ string result;
+ size_t where = 0;
+
+ for (int width = StrToInt(GetLineValue(st, '(', ')', 1)); width; width = StrToInt(GetLineValue(st, '(', ')', 1)))
+ {
+ width *= COLS/100.0;
+ char type = GetLineValue(st, '{', '}', 1)[0];
+
+ switch (type)
+ {
+ case 'l':
+ result += "Time";
+ break;
+ case 'f':
+ result += "Filename";
+ break;
+ case 'F':
+ result += "Full filename";
+ break;
+ case 'a':
+ result += "Artist";
+ break;
+ case 't':
+ result += "Title";
+ break;
+ case 'b':
+ result += "Album";
+ break;
+ case 'y':
+ result += "Year";
+ break;
+ case 'n':
+ result += "Track";
+ break;
+ case 'g':
+ result += "Genre";
+ break;
+ case 'c':
+ result += "Composer";
+ break;
+ case 'p':
+ result += "Performer";
+ break;
+ case 'd':
+ result += "Disc";
+ break;
+ case 'C':
+ result += "Comment";
+ break;
+ default:
+ break;
+ }
+ where += width;
+
+ if (result.length() > where)
+ result = result.substr(0, where);
+ else
+ for (size_t i = result.length(); i <= where && i < size_t(COLS); i++, result += ' ') { }
+ }
+ return result;
+}
+
+void Display::TotalPlaylistLength(Window &w)
+{
+ extern Menu<MPD::Song> *mPlaylist;
+
+ const int MINUTE = 60;
+ const int HOUR = 60*MINUTE;
+ const int DAY = 24*HOUR;
+ const int YEAR = 365*DAY;
+ int length = 0;
+
+ for (size_t i = 0; i < mPlaylist->Size(); i++)
+ length += mPlaylist->at(i).GetTotalLength();
+
+ w << '(' << mPlaylist->Size() << (mPlaylist->Size() == 1 ? " item" : " items");
+
+ if (length)
+ {
+ w << ", length: ";
+ int years = length/YEAR;
+ if (years)
+ {
+ w << years << (years == 1 ? " year" : " years");
+ length -= years*YEAR;
+ if (length)
+ w << ", ";
+ }
+ int days = length/DAY;
+ if (days)
+ {
+ w << days << (days == 1 ? " day" : " days");
+ length -= days*DAY;
+ if (length)
+ w << ", ";
+ }
+ int hours = length/HOUR;
+ if (hours)
+ {
+ w << hours << (hours == 1 ? " hour" : " hours");
+ length -= hours*HOUR;
+ if (length)
+ w << ", ";
+ }
+ int minutes = length/MINUTE;
+ if (minutes)
+ {
+ w << minutes << (minutes == 1 ? " minute" : " minutes");
+ length -= minutes*MINUTE;
+ if (length)
+ w << ", ";
+ }
+ if (length)
+ w << length << (length == 1 ? " second" : " seconds");
+ }
+ w << ')';
+ w.Refresh();
+}
+
+void Display::StringPairs(const string_pair &pair, void *, Menu<string_pair> *menu)
+{
+ *menu << pair.first;
+}
+
+void Display::SongsInColumns(const MPD::Song &s, void *s_template, Menu<MPD::Song> *menu)
+{
+ string st = s_template ? *static_cast<string *>(s_template) : "";
+ size_t where = 0;
+ Color color;
+
+ for (int width = StrToInt(GetLineValue(st, '(', ')', 1)); width; width = StrToInt(GetLineValue(st, '(', ')', 1)))
+ {
+ if (where)
+ {
+ menu->GotoXY(where, menu->Y());
+ *menu << ' ';
+ if (color != clDefault)
+ *menu << clEnd;
+ }
+
+ width *= COLS/100.0;
+ color = IntoColor(GetLineValue(st, '[', ']', 1));
+ char type = GetLineValue(st, '{', '}', 1)[0];
+
+ string (Song::*get)() const = 0;
+
+ switch (type)
+ {
+ 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::GetYear;
+ 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':
+ if (!s.GetTitle().empty())
+ get = &Song::GetTitle;
+ else
+ get = &Song::GetName;
+ break;
+ default:
+ break;
+ }
+ if (color != clDefault)
+ *menu << color;
+ whline(menu->Raw(), 32, menu->GetWidth()-where);
+ string tag = (s.*get)();
+ if (!tag.empty())
+ *menu << tag;
+ else
+ *menu << Config.empty_tag;
+ where += width;
+ }
+ if (color != clDefault)
+ *menu << clEnd;
+}
+
+void Display::Songs(const MPD::Song &s, void *data, Menu<MPD::Song> *menu)
+{
+ if (!s.Localized())
+ const_cast<MPD::Song *>(&s)->Localize();
+
+ const string &song_template = data ? *static_cast<string *>(data) : "";
+ basic_buffer<my_char_t> buf;
+ bool right = 0;
+
+ string::const_iterator goto_pos, prev_pos;
+
+ for (string::const_iterator it = song_template.begin(); it != song_template.end(); it++)
+ {
+ CHECK_LINKED_TAGS:;
+ if (*it == '{')
+ {
+ prev_pos = it;
+ string (Song::*get)() const = 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::GetYear;
+ 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 (!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;
+ }
+ 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;
+ }
+
+ if (*it != '%' && *it != '$')
+ {
+ if (!right)
+ *menu << *it;
+ else
+ buf << *it;
+ }
+ else if (*it == '%')
+ {
+ switch (*++it)
+ {
+ case 'l':
+ if (!right)
+ *menu << s.GetLength();
+ else
+ buf << TO_WSTRING(s.GetLength());
+ break;
+ case 'F':
+ if (!right)
+ *menu << s.GetFile();
+ else
+ buf << TO_WSTRING(s.GetFile());
+ break;
+ case 'f':
+ if (!right)
+ *menu << s.GetName();
+ else
+ buf << TO_WSTRING(s.GetName());
+ break;
+ case 'a':
+ if (!right)
+ *menu << s.GetArtist();
+ else
+ buf << TO_WSTRING(s.GetArtist());
+ break;
+ case 'b':
+ if (!right)
+ *menu << s.GetAlbum();
+ else
+ buf << TO_WSTRING(s.GetAlbum());
+ break;
+ case 'y':
+ if (!right)
+ *menu << s.GetYear();
+ else
+ buf << TO_WSTRING(s.GetYear());
+ break;
+ case 'n':
+ if (!right)
+ *menu << s.GetTrack();
+ else
+ buf << TO_WSTRING(s.GetTrack());
+ break;
+ case 'g':
+ if (!right)
+ *menu << s.GetGenre();
+ else
+ buf << TO_WSTRING(s.GetGenre());
+ break;
+ case 'c':
+ if (!right)
+ *menu << s.GetComposer();
+ else
+ buf << TO_WSTRING(s.GetComposer());
+ break;
+ case 'p':
+ if (!right)
+ *menu << s.GetPerformer();
+ else
+ buf << TO_WSTRING(s.GetPerformer());
+ break;
+ case 'd':
+ if (!right)
+ *menu << s.GetDisc();
+ else
+ buf << TO_WSTRING(s.GetDisc());
+ break;
+ case 'C':
+ if (!right)
+ *menu << s.GetComment();
+ else
+ buf << TO_WSTRING(s.GetComment());
+ break;
+ case 't':
+ if (!right)
+ *menu << s.GetTitle();
+ else
+ buf << TO_WSTRING(s.GetTitle());
+ break;
+ case 'r':
+ right = 1;
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ it++;
+ if (!right)
+ *menu << Color(*it-'0');
+ else
+ buf << Color(*it-'0');
+ }
+ }
+ if (right)
+ {
+ menu->GotoXY(menu->GetWidth()-buf.Str().length(), menu->Y());
+ *menu << buf;
+ }
+}
+
+void Display::Tags(const MPD::Song &s, void *data, Menu<MPD::Song> *menu)
+{
+ switch (static_cast<Menu<string> *>(data)->Choice())
+ {
+ case 0:
+ *menu << ShowTag(s.GetTitle());
+ return;
+ case 1:
+ *menu << ShowTag(s.GetArtist());
+ return;
+ case 2:
+ *menu << ShowTag(s.GetAlbum());
+ return;
+ case 3:
+ *menu << ShowTag(s.GetYear());
+ return;
+ case 4:
+ *menu << ShowTag(s.GetTrack());
+ return;
+ case 5:
+ *menu << ShowTag(s.GetGenre());
+ return;
+ case 6:
+ *menu << ShowTag(s.GetComposer());
+ return;
+ case 7:
+ *menu << ShowTag(s.GetPerformer());
+ return;
+ case 8:
+ *menu << ShowTag(s.GetDisc());
+ return;
+ case 9:
+ *menu << ShowTag(s.GetComment());
+ return;
+ case 11:
+ if (s.GetNewName().empty())
+ *menu << s.GetName();
+ else
+ *menu << s.GetName() << Config.color2 << " -> " << clEnd << s.GetNewName();
+ return;
+ default:
+ return;
+ }
+}
+
+void Display::Items(const MPD::Item &item, void *, Menu<MPD::Item> *menu)
+{
+ switch (item.type)
+ {
+ case MPD::itDirectory:
+ {
+ if (item.song)
+ {
+ *menu << "[..]";
+ return;
+ }
+ size_t slash = item.name.rfind("/");
+ *menu << "[" << (slash != string::npos ? item.name.substr(slash+1) : item.name) << "]";
+ return;
+ }
+ case MPD::itSong:
+ if (!Config.columns_in_browser)
+ Display::Songs(*item.song, &Config.song_list_format, reinterpret_cast<Menu<MPD::Song> *>(menu));
+ else
+ Display::SongsInColumns(*item.song, &Config.song_columns_list_format, reinterpret_cast<Menu<MPD::Song> *>(menu));
+ return;
+ case MPD::itPlaylist:
+ *menu << Config.browser_playlist_prefix << item.name;
+ return;
+ default:
+ return;
+ }
+}
+
+void Display::SearchEngine(const std::pair<Buffer *, Song *> &pair, void *, Menu< std::pair<Buffer *, Song *> > *menu)
+{
+ if (pair.second)
+ {
+ if (!Config.columns_in_search_engine)
+ Display::Songs(*pair.second, &Config.song_list_format, reinterpret_cast<Menu<Song> *>(menu));
+ else
+ Display::SongsInColumns(*pair.second, &Config.song_columns_list_format, reinterpret_cast<Menu<Song> *>(menu));
+ }
+
+ else
+ *menu << *pair.first;
+}
+