update Menu class and related stuff
This commit is contained in:
@@ -107,11 +107,11 @@ namespace
|
|||||||
void UpdateItemList(Menu<Item> *menu)
|
void UpdateItemList(Menu<Item> *menu)
|
||||||
{
|
{
|
||||||
bool bold = 0;
|
bool bold = 0;
|
||||||
for (int i = 0; i < menu->Size(); i++)
|
for (size_t i = 0; i < menu->Size(); i++)
|
||||||
{
|
{
|
||||||
if (menu->at(i).type == itSong)
|
if (menu->at(i).type == itSong)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < mPlaylist->Size(); j++)
|
for (size_t j = 0; j < mPlaylist->Size(); j++)
|
||||||
{
|
{
|
||||||
if (mPlaylist->at(j).GetHash() == menu->at(i).song->GetHash())
|
if (mPlaylist->at(j).GetHash() == menu->at(i).song->GetHash())
|
||||||
{
|
{
|
||||||
@@ -126,24 +126,30 @@ void UpdateItemList(Menu<Item> *menu)
|
|||||||
menu->Refresh();
|
menu->Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
string DisplayItem(const Item &item, void *, const Menu<Item> *menu)
|
void DisplayItem(const Item &item, void *, Menu<Item> *menu)
|
||||||
{
|
{
|
||||||
switch (item.type)
|
switch (item.type)
|
||||||
{
|
{
|
||||||
case itDirectory:
|
case itDirectory:
|
||||||
{
|
{
|
||||||
if (item.song)
|
if (item.song)
|
||||||
return "[..]";
|
{
|
||||||
|
*menu << "[..]";
|
||||||
|
return;
|
||||||
|
}
|
||||||
size_t slash = item.name.find_last_of("/");
|
size_t slash = item.name.find_last_of("/");
|
||||||
return "[" + (slash != string::npos ? item.name.substr(slash+1) : item.name) + "]";
|
*menu << "[" << (slash != string::npos ? item.name.substr(slash+1) : item.name) << "]";
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
case itSong:
|
case itSong:
|
||||||
// I know casting that way is ugly etc., but it works.
|
// I know casting that way is ugly etc., but it works.
|
||||||
return DisplaySong(*item.song, &Config.song_list_format, (const Menu<Song> *)menu);
|
DisplaySong(*item.song, &Config.song_list_format, (Menu<Song> *)menu);
|
||||||
|
return;
|
||||||
case itPlaylist:
|
case itPlaylist:
|
||||||
return Config.browser_playlist_prefix + item.name;
|
*menu << Config.browser_playlist_prefix << item.name;
|
||||||
|
return;
|
||||||
default:
|
default:
|
||||||
return "";
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,6 +163,11 @@ void GetDirectory(string dir, string subdir)
|
|||||||
if (browsed_dir != dir)
|
if (browsed_dir != dir)
|
||||||
mBrowser->Reset();
|
mBrowser->Reset();
|
||||||
browsed_dir = dir;
|
browsed_dir = dir;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < mBrowser->Size(); i++)
|
||||||
|
if (mBrowser->at(i).song != (void *)1)
|
||||||
|
delete mBrowser->at(i).song;
|
||||||
|
|
||||||
mBrowser->Clear(0);
|
mBrowser->Clear(0);
|
||||||
|
|
||||||
if (dir != "/")
|
if (dir != "/")
|
||||||
@@ -192,7 +203,7 @@ void GetDirectory(string dir, string subdir)
|
|||||||
case itSong:
|
case itSong:
|
||||||
{
|
{
|
||||||
bool bold = 0;
|
bool bold = 0;
|
||||||
for (int i = 0; i < mPlaylist->Size(); i++)
|
for (size_t i = 0; i < mPlaylist->Size(); i++)
|
||||||
{
|
{
|
||||||
if (mPlaylist->at(i).GetHash() == it->song->GetHash())
|
if (mPlaylist->at(i).GetHash() == it->song->GetHash())
|
||||||
{
|
{
|
||||||
@@ -205,8 +216,8 @@ void GetDirectory(string dir, string subdir)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mBrowser->Highlight(highlightme);
|
if (highlightme >= 0)
|
||||||
|
mBrowser->Highlight(highlightme);
|
||||||
if (current_screen == csBrowser)
|
if (current_screen == csBrowser)
|
||||||
mBrowser->Hide();
|
mBrowser->Hide();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
void UpdateItemList(Menu<MPD::Item> *);
|
void UpdateItemList(Menu<MPD::Item> *);
|
||||||
|
|
||||||
string DisplayItem(const MPD::Item &, void *, const Menu<MPD::Item> *);
|
void DisplayItem(const MPD::Item &, void *, Menu<MPD::Item> *);
|
||||||
|
|
||||||
void GetDirectory(string, string = "/");
|
void GetDirectory(string, string = "/");
|
||||||
|
|
||||||
|
|||||||
426
src/helpers.cpp
426
src/helpers.cpp
@@ -223,9 +223,9 @@ bool CaseInsensitiveSorting::operator()(const Item &a, const Item &b)
|
|||||||
void UpdateSongList(Menu<Song> *menu)
|
void UpdateSongList(Menu<Song> *menu)
|
||||||
{
|
{
|
||||||
bool bold = 0;
|
bool bold = 0;
|
||||||
for (int i = 0; i < menu->Size(); i++)
|
for (size_t i = 0; i < menu->Size(); i++)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < mPlaylist->Size(); j++)
|
for (size_t j = 0; j < mPlaylist->Size(); j++)
|
||||||
{
|
{
|
||||||
if (mPlaylist->at(j).GetHash() == menu->at(i).GetHash())
|
if (mPlaylist->at(j).GetHash() == menu->at(i).GetHash())
|
||||||
{
|
{
|
||||||
@@ -326,7 +326,7 @@ string TotalPlaylistLength()
|
|||||||
const int YEAR = 365*DAY;
|
const int YEAR = 365*DAY;
|
||||||
string result;
|
string result;
|
||||||
int length = 0;
|
int length = 0;
|
||||||
for (int i = 0; i < mPlaylist->Size(); i++)
|
for (size_t i = 0; i < mPlaylist->Size(); i++)
|
||||||
length += mPlaylist->at(i).GetTotalLength();
|
length += mPlaylist->at(i).GetTotalLength();
|
||||||
|
|
||||||
if (!length)
|
if (!length)
|
||||||
@@ -371,9 +371,9 @@ string TotalPlaylistLength()
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
string DisplayStringPair(const StringPair &pair, void *, const Menu<StringPair> *)
|
void DisplayStringPair(const StringPair &pair, void *, Menu<StringPair> *menu)
|
||||||
{
|
{
|
||||||
return pair.first;
|
*menu << pair.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
string DisplayColumns(string song_template)
|
string DisplayColumns(string song_template)
|
||||||
@@ -448,9 +448,9 @@ string DisplayColumns(string song_template)
|
|||||||
return result.substr(0, COLS);
|
return result.substr(0, COLS);
|
||||||
}
|
}
|
||||||
|
|
||||||
string DisplaySongInColumns(const Song &s, void *s_template, const Menu<Song> *)
|
void DisplaySongInColumns(const Song &s, void *s_template, Menu<Song> *menu)
|
||||||
{
|
{
|
||||||
string song_template = s_template ? *static_cast<string *>(s_template) : "";
|
/*string song_template = s_template ? *static_cast<string *>(s_template) : "";
|
||||||
|
|
||||||
vector<string> cols;
|
vector<string> cols;
|
||||||
for (size_t i = song_template.find(" "); i != string::npos; i = song_template.find(" "))
|
for (size_t i = song_template.find(" "); i != string::npos; i = song_template.find(" "))
|
||||||
@@ -547,284 +547,184 @@ string DisplaySongInColumns(const Song &s, void *s_template, const Menu<Song> *)
|
|||||||
result += close_col2;
|
result += close_col2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TO_STRING(result);
|
return TO_STRING(result);*/
|
||||||
|
*menu << "dupa";
|
||||||
}
|
}
|
||||||
|
|
||||||
string DisplaySong(const Song &s, void *s_template, const Menu<Song> *menu)
|
void DisplaySong(const Song &s, void *data, Menu<Song> *menu)
|
||||||
{
|
{
|
||||||
const string &song_template = s_template ? *static_cast<string *>(s_template) : "";
|
const string &song_template = data ? *static_cast<string *>(data) : "";
|
||||||
string result;
|
basic_buffer<char> lresult;
|
||||||
string lresult;
|
|
||||||
bool link_tags = 0;
|
|
||||||
bool tags_present = 0;
|
|
||||||
bool right = 0;
|
bool right = 0;
|
||||||
int i = 0;
|
|
||||||
|
string::const_iterator goto_pos, prev_pos;
|
||||||
|
|
||||||
for (string::const_iterator it = song_template.begin(); it != song_template.end(); it++)
|
for (string::const_iterator it = song_template.begin(); it != song_template.end(); it++)
|
||||||
{
|
{
|
||||||
if (*it == '}')
|
CHECK_LINKED_TAGS:;
|
||||||
{
|
|
||||||
if (!tags_present)
|
|
||||||
result = result.substr(0, result.length()-i);
|
|
||||||
|
|
||||||
it++;
|
|
||||||
link_tags = 0;
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
if (*it == '|' && *(it+1) == '{')
|
|
||||||
{
|
|
||||||
if (!tags_present)
|
|
||||||
it++;
|
|
||||||
else
|
|
||||||
while (*++it != '}') { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*it == '}')
|
|
||||||
{
|
|
||||||
if (!tags_present)
|
|
||||||
result = result.substr(0, result.length()-i);
|
|
||||||
|
|
||||||
it++;
|
|
||||||
link_tags = 0;
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
if (*it == '|' && *(it+1) == '{')
|
|
||||||
{
|
|
||||||
if (!tags_present)
|
|
||||||
it++;
|
|
||||||
else
|
|
||||||
while (*it++ != '}') { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*it == '{')
|
if (*it == '{')
|
||||||
{
|
{
|
||||||
i = 0;
|
prev_pos = it;
|
||||||
tags_present = 1;
|
string (Song::*get)() const = 0;
|
||||||
link_tags = 1;
|
for (; *it != '}'; 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 && (s.*get)() == EMPTY_TAG)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*it == '}')
|
||||||
|
{
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (*it == '}' && *(it+1) != '|')
|
||||||
|
break;
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
goto_pos = ++it;
|
||||||
|
it = ++prev_pos;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (; *it != '}'; it++) { }
|
||||||
|
it++;
|
||||||
|
if (*it == '{' || *it == '|')
|
||||||
|
{
|
||||||
|
if (*it == '|')
|
||||||
|
it++;
|
||||||
|
goto CHECK_LINKED_TAGS;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (it == song_template.end())
|
if (*it == '}')
|
||||||
break;
|
|
||||||
|
|
||||||
if (*it != '%')
|
|
||||||
{
|
{
|
||||||
i++;
|
if (goto_pos == song_template.end())
|
||||||
result += *it;
|
break;
|
||||||
|
it = goto_pos;
|
||||||
|
if (*it == '{')
|
||||||
|
goto CHECK_LINKED_TAGS;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (*it != '%' && *it != '$')
|
||||||
|
{
|
||||||
|
if (!right)
|
||||||
|
*menu << *it;
|
||||||
|
else
|
||||||
|
lresult << *it;
|
||||||
|
}
|
||||||
|
else if (*it == '%')
|
||||||
{
|
{
|
||||||
switch (*++it)
|
switch (*++it)
|
||||||
{
|
{
|
||||||
case 'l':
|
case 'l':
|
||||||
{
|
|
||||||
if (link_tags)
|
|
||||||
{
|
|
||||||
if (s.GetTotalLength() > 0)
|
|
||||||
{
|
|
||||||
result += s.GetLength();
|
|
||||||
i += s.GetLength().length();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
tags_present = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
result += s.GetLength();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'F':
|
|
||||||
{
|
|
||||||
result += s.GetFile();
|
|
||||||
i += s.GetFile().length();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'f':
|
|
||||||
{
|
|
||||||
result += s.GetName();
|
|
||||||
i += s.GetName().length();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'a':
|
|
||||||
{
|
|
||||||
if (link_tags)
|
|
||||||
{
|
|
||||||
if (!s.GetArtist().empty() && s.GetArtist() != UNKNOWN_ARTIST)
|
|
||||||
{
|
|
||||||
result += s.GetArtist();
|
|
||||||
i += s.GetArtist().length();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
tags_present = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
result += s.GetArtist();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'b':
|
|
||||||
{
|
|
||||||
if (link_tags)
|
|
||||||
{
|
|
||||||
if (!s.GetAlbum().empty() && s.GetAlbum() != UNKNOWN_ALBUM)
|
|
||||||
{
|
|
||||||
result += s.GetAlbum();
|
|
||||||
i += s.GetAlbum().length();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
tags_present = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
result += s.GetAlbum();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'y':
|
|
||||||
{
|
|
||||||
if (link_tags)
|
|
||||||
{
|
|
||||||
if (!s.GetYear().empty() && s.GetYear() != EMPTY_TAG)
|
|
||||||
{
|
|
||||||
result += s.GetYear();
|
|
||||||
i += s.GetYear().length();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
tags_present = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
result += s.GetYear();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'n':
|
|
||||||
{
|
|
||||||
if (link_tags)
|
|
||||||
{
|
|
||||||
if (!s.GetTrack().empty() && s.GetTrack() != EMPTY_TAG)
|
|
||||||
{
|
|
||||||
result += s.GetTrack();
|
|
||||||
i += s.GetTrack().length();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
tags_present = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
result += s.GetTrack();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'g':
|
|
||||||
{
|
|
||||||
if (link_tags)
|
|
||||||
{
|
|
||||||
if (!s.GetGenre().empty() && s.GetGenre() != EMPTY_TAG)
|
|
||||||
{
|
|
||||||
result += s.GetGenre();
|
|
||||||
i += s.GetGenre().length();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
tags_present = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
result += s.GetGenre();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'c':
|
|
||||||
{
|
|
||||||
if (link_tags)
|
|
||||||
{
|
|
||||||
if (!s.GetComposer().empty() && s.GetComposer() != EMPTY_TAG)
|
|
||||||
{
|
|
||||||
result += s.GetComposer();
|
|
||||||
i += s.GetComposer().length();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
tags_present = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
result += s.GetComposer();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'p':
|
|
||||||
{
|
|
||||||
if (link_tags)
|
|
||||||
{
|
|
||||||
if (!s.GetPerformer().empty() && s.GetPerformer() != EMPTY_TAG)
|
|
||||||
{
|
|
||||||
result += s.GetPerformer();
|
|
||||||
i += s.GetPerformer().length();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
tags_present = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
result += s.GetPerformer();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'd':
|
|
||||||
{
|
|
||||||
if (link_tags)
|
|
||||||
{
|
|
||||||
if (!s.GetDisc().empty() && s.GetDisc() != EMPTY_TAG)
|
|
||||||
{
|
|
||||||
result += s.GetDisc();
|
|
||||||
i += s.GetDisc().length();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
tags_present = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
result += s.GetDisc();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'C':
|
|
||||||
{
|
|
||||||
if (link_tags)
|
|
||||||
{
|
|
||||||
if (!s.GetComment().empty() && s.GetComment() != EMPTY_TAG)
|
|
||||||
{
|
|
||||||
result += s.GetComment();
|
|
||||||
i += s.GetComment().length();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
tags_present = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
result += s.GetComment();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 't':
|
|
||||||
{
|
|
||||||
if (link_tags)
|
|
||||||
{
|
|
||||||
if (!s.GetTitle().empty() && s.GetTitle() != UNKNOWN_TITLE)
|
|
||||||
{
|
|
||||||
result += s.GetTitle();
|
|
||||||
i += s.GetTitle().length();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
tags_present = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
result += s.GetTitle();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'r':
|
|
||||||
{
|
|
||||||
if (!right)
|
if (!right)
|
||||||
{
|
*menu << s.GetLength();
|
||||||
right = 1;
|
else
|
||||||
lresult = result;
|
lresult << s.GetLength();
|
||||||
result.clear();
|
break;
|
||||||
i = 0;
|
case 'F':
|
||||||
}
|
*menu << s.GetFile();
|
||||||
}
|
break;
|
||||||
|
case 'f':
|
||||||
|
*menu << s.GetName();
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
*menu << s.GetArtist();
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
*menu << s.GetAlbum();
|
||||||
|
break;
|
||||||
|
case 'y':
|
||||||
|
*menu << s.GetYear();
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
*menu << s.GetTrack();
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
*menu << s.GetGenre();
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
*menu << s.GetComposer();
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
*menu << s.GetPerformer();
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
*menu << s.GetDisc();
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
*menu << s.GetComment();
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
*menu << s.GetTitle();
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
right = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
it++;
|
||||||
|
if (!right)
|
||||||
|
*menu << Color(*it-'0');
|
||||||
|
else
|
||||||
|
lresult << Color(*it-'0');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (right && menu)
|
if (right)
|
||||||
{
|
{
|
||||||
result = lresult + "[." + IntoStr(menu->GetWidth()-result.length()) + "]" + result;
|
menu->GotoXY(menu->GetWidth()-lresult.Str().length(), menu->Y());
|
||||||
|
*menu << lresult;
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetInfo(Song &s, Scrollpad &info)
|
void GetInfo(Song &s, Scrollpad &info)
|
||||||
|
|||||||
@@ -39,6 +39,11 @@ class CaseInsensitiveSorting
|
|||||||
bool operator()(const MPD::Item &, const MPD::Item &);
|
bool operator()(const MPD::Item &, const MPD::Item &);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class T> void GenericDisplayer(const T &t, void *, Menu<T> *menu)
|
||||||
|
{
|
||||||
|
*menu << t;
|
||||||
|
}
|
||||||
|
|
||||||
bool SortSongsByTrack(Song *, Song *);
|
bool SortSongsByTrack(Song *, Song *);
|
||||||
|
|
||||||
void UpdateSongList(Menu<Song> *);
|
void UpdateSongList(Menu<Song> *);
|
||||||
@@ -51,10 +56,10 @@ void EscapeUnallowedChars(string &);
|
|||||||
string IntoStr(mpd_TagItems);
|
string IntoStr(mpd_TagItems);
|
||||||
string FindSharedDir(const string &, const string &);
|
string FindSharedDir(const string &, const string &);
|
||||||
string TotalPlaylistLength();
|
string TotalPlaylistLength();
|
||||||
string DisplayStringPair(const StringPair &, void *, const Menu<StringPair> *);
|
void DisplayStringPair(const StringPair &, void *, Menu<StringPair> *);
|
||||||
string DisplayColumns(string);
|
string DisplayColumns(string);
|
||||||
string DisplaySongInColumns(const Song &, void *, const Menu<Song> *);
|
void DisplaySongInColumns(const Song &, void *, Menu<Song> *);
|
||||||
string DisplaySong(const Song &, void * = &Config.song_list_format, const Menu<Song> * = NULL);
|
void DisplaySong(const Song &, void * = &Config.song_list_format, Menu<Song> * = NULL);
|
||||||
void GetInfo(Song &, Scrollpad &);
|
void GetInfo(Song &, Scrollpad &);
|
||||||
void ShowMessage(const char *, ...);
|
void ShowMessage(const char *, ...);
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "song.h"
|
#include "song.h"
|
||||||
|
|
||||||
|
extern Window *wCurrent;
|
||||||
extern Scrollpad *sLyrics;
|
extern Scrollpad *sLyrics;
|
||||||
extern Scrollpad *sInfo;
|
extern Scrollpad *sInfo;
|
||||||
|
|
||||||
@@ -93,6 +94,8 @@ void * GetArtistInfo(void *ptr)
|
|||||||
}
|
}
|
||||||
input.close();
|
input.close();
|
||||||
sInfo->Flush();
|
sInfo->Flush();
|
||||||
|
if (wCurrent == sInfo)
|
||||||
|
sInfo->Refresh();
|
||||||
artist_info_downloader = 0;
|
artist_info_downloader = 0;
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
@@ -119,6 +122,8 @@ void * GetArtistInfo(void *ptr)
|
|||||||
{
|
{
|
||||||
*sInfo << "Error while fetching artist's info: " << curl_easy_strerror(code);
|
*sInfo << "Error while fetching artist's info: " << curl_easy_strerror(code);
|
||||||
sInfo->Flush();
|
sInfo->Flush();
|
||||||
|
if (wCurrent == sInfo)
|
||||||
|
sInfo->Refresh();
|
||||||
artist_info_downloader = 0;
|
artist_info_downloader = 0;
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
@@ -134,6 +139,8 @@ void * GetArtistInfo(void *ptr)
|
|||||||
EscapeHtml(result);
|
EscapeHtml(result);
|
||||||
*sInfo << "Last.fm returned an error message: " << result;
|
*sInfo << "Last.fm returned an error message: " << result;
|
||||||
sInfo->Flush();
|
sInfo->Flush();
|
||||||
|
if (wCurrent == sInfo)
|
||||||
|
sInfo->Refresh();
|
||||||
artist_info_downloader = 0;
|
artist_info_downloader = 0;
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
@@ -215,6 +222,8 @@ void * GetArtistInfo(void *ptr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
sInfo->Flush();
|
sInfo->Flush();
|
||||||
|
if (wCurrent == sInfo)
|
||||||
|
sInfo->Refresh();
|
||||||
artist_info_downloader = 0;
|
artist_info_downloader = 0;
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
@@ -244,6 +253,8 @@ void *GetLyrics(void *song)
|
|||||||
}
|
}
|
||||||
# ifdef HAVE_CURL_CURL_H
|
# ifdef HAVE_CURL_CURL_H
|
||||||
sLyrics->Flush();
|
sLyrics->Flush();
|
||||||
|
if (wCurrent == sLyrics)
|
||||||
|
sLyrics->Refresh();
|
||||||
lyrics_downloader = 0;
|
lyrics_downloader = 0;
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
# endif
|
# endif
|
||||||
@@ -281,6 +292,8 @@ void *GetLyrics(void *song)
|
|||||||
{
|
{
|
||||||
*sLyrics << "Error while fetching lyrics: " << curl_easy_strerror(code);
|
*sLyrics << "Error while fetching lyrics: " << curl_easy_strerror(code);
|
||||||
sLyrics->Flush();
|
sLyrics->Flush();
|
||||||
|
if (wCurrent == sLyrics)
|
||||||
|
sLyrics->Refresh();
|
||||||
lyrics_downloader = 0;
|
lyrics_downloader = 0;
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
@@ -295,6 +308,8 @@ void *GetLyrics(void *song)
|
|||||||
{
|
{
|
||||||
*sLyrics << result;
|
*sLyrics << result;
|
||||||
sLyrics->Flush();
|
sLyrics->Flush();
|
||||||
|
if (wCurrent == sLyrics)
|
||||||
|
sLyrics->Refresh();
|
||||||
lyrics_downloader = 0;
|
lyrics_downloader = 0;
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
@@ -315,12 +330,16 @@ void *GetLyrics(void *song)
|
|||||||
output.close();
|
output.close();
|
||||||
}
|
}
|
||||||
sLyrics->Flush();
|
sLyrics->Flush();
|
||||||
|
if (wCurrent == sLyrics)
|
||||||
|
sLyrics->Refresh();
|
||||||
lyrics_downloader = 0;
|
lyrics_downloader = 0;
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
# else
|
# else
|
||||||
else
|
else
|
||||||
*sLyrics << "Local lyrics not found. As ncmpcpp has been compiled without curl support, you can put appropriate lyrics into ~/.lyrics directory (file syntax is \"ARTIST - TITLE.txt\") or recompile ncmpcpp with curl support.";
|
*sLyrics << "Local lyrics not found. As ncmpcpp has been compiled without curl support, you can put appropriate lyrics into ~/.lyrics directory (file syntax is \"ARTIST - TITLE.txt\") or recompile ncmpcpp with curl support.";
|
||||||
sLyrics->Flush();
|
sLyrics->Flush();
|
||||||
|
if (wCurrent == sLyrics)
|
||||||
|
sLyrics->Refresh();
|
||||||
return NULL;
|
return NULL;
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|||||||
12
src/menu.cpp
12
src/menu.cpp
@@ -20,9 +20,15 @@
|
|||||||
|
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
|
|
||||||
template <>
|
/*template <> void Menu<Buffer>::AddOption(const Buffer &buf, bool is_bold, bool is_static, bool have_separator)
|
||||||
string Menu<string>::DisplayOption(const string &str) const
|
|
||||||
{
|
{
|
||||||
return str;
|
Option o;
|
||||||
|
o.Item = new Buffer();
|
||||||
|
*o.Item << buf;
|
||||||
|
o.isBold = is_bold;
|
||||||
|
o.isStatic = is_static;
|
||||||
|
o.haveSeparator = have_separator;
|
||||||
|
itsOptions.push_back(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
822
src/menu.h
822
src/menu.h
File diff suppressed because it is too large
Load Diff
@@ -346,7 +346,7 @@ void Connection::GetPlaylistChanges(long long id, SongList &v) const
|
|||||||
{
|
{
|
||||||
if (item->type == MPD_INFO_ENTITY_TYPE_SONG)
|
if (item->type == MPD_INFO_ENTITY_TYPE_SONG)
|
||||||
{
|
{
|
||||||
Song *s = new Song(item->info.song);
|
Song *s = new Song(item->info.song, 1);
|
||||||
item->info.song = 0;
|
item->info.song = 0;
|
||||||
v.push_back(s);
|
v.push_back(s);
|
||||||
}
|
}
|
||||||
|
|||||||
473
src/ncmpcpp.cpp
473
src/ncmpcpp.cpp
File diff suppressed because it is too large
Load Diff
@@ -48,8 +48,5 @@ const int ncmpcpp_window_timeout = 500;
|
|||||||
|
|
||||||
const string home_folder = getenv("HOME") ? getenv("HOME") : "";
|
const string home_folder = getenv("HOME") ? getenv("HOME") : "";
|
||||||
|
|
||||||
const string search_mode_normal = "Match if tag contains searched phrase";
|
|
||||||
const string search_mode_strict = "Match only if both values are the same";
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -25,24 +25,30 @@ using namespace MPD;
|
|||||||
|
|
||||||
extern Connection *Mpd;
|
extern Connection *Mpd;
|
||||||
extern Menu<Song> *mPlaylist;
|
extern Menu<Song> *mPlaylist;
|
||||||
extern Menu< std::pair<string, Song> > *mSearcher;
|
extern Menu< std::pair<Buffer *, Song *> > *mSearcher;
|
||||||
|
|
||||||
bool search_match_to_pattern = 1;
|
bool search_match_to_pattern = 1;
|
||||||
bool search_case_sensitive = 0;
|
bool search_case_sensitive = 0;
|
||||||
|
|
||||||
string SearchEngineDisplayer(const std::pair<string, Song> &pair, void *, const Menu< std::pair<string, Song> > *menu)
|
extern const char *search_mode_normal = "Match if tag contains searched phrase";
|
||||||
|
extern const char *search_mode_strict = "Match only if both values are the same";
|
||||||
|
|
||||||
|
void SearchEngineDisplayer(const std::pair<Buffer *, Song *> &pair, void *, Menu< std::pair<Buffer *, Song *> > *menu)
|
||||||
{
|
{
|
||||||
return pair.first == "." ? DisplaySong(pair.second, &Config.song_list_format, (Menu<Song> *) menu) : pair.first;
|
if (pair.second)
|
||||||
|
DisplaySong(*pair.second, &Config.song_list_format, reinterpret_cast<Menu<Song> *>(menu));
|
||||||
|
else
|
||||||
|
*menu << *pair.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateFoundList()
|
void UpdateFoundList()
|
||||||
{
|
{
|
||||||
bool bold = 0;
|
bool bold = 0;
|
||||||
for (int i = search_engine_static_options-1; i < mSearcher->Size(); i++)
|
for (size_t i = search_engine_static_options; i < mSearcher->Size(); i++)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < mPlaylist->Size(); j++)
|
for (size_t j = 0; j < mPlaylist->Size(); j++)
|
||||||
{
|
{
|
||||||
if (mPlaylist->at(j).GetHash() == mSearcher->at(i).second.GetHash())
|
if (mPlaylist->at(j).GetHash() == mSearcher->at(i).second->GetHash())
|
||||||
{
|
{
|
||||||
bold = 1;
|
bold = 1;
|
||||||
break;
|
break;
|
||||||
@@ -55,26 +61,48 @@ void UpdateFoundList()
|
|||||||
|
|
||||||
void PrepareSearchEngine(Song &s)
|
void PrepareSearchEngine(Song &s)
|
||||||
{
|
{
|
||||||
// adding several empty songs may seem riddiculous, but they hardly steal memory
|
for (size_t i = 0; i < mSearcher->Size(); i++)
|
||||||
// and it's much cleaner solution than having two different containers imo
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
delete (*mSearcher)[i].first;
|
||||||
|
delete (*mSearcher)[i].second;
|
||||||
|
}
|
||||||
|
catch (List::InvalidItem) { }
|
||||||
|
}
|
||||||
|
|
||||||
s.Clear();
|
s.Clear();
|
||||||
mSearcher->Clear();
|
mSearcher->Clear();
|
||||||
mSearcher->Reset();
|
mSearcher->Reset();
|
||||||
mSearcher->AddOption(make_pair("[.b]Filename:[/b] " + s.GetName(), Song()));
|
mSearcher->ResizeBuffer(15);
|
||||||
mSearcher->AddOption(make_pair("[.b]Title:[/b] " + s.GetTitle(), Song()));
|
|
||||||
mSearcher->AddOption(make_pair("[.b]Artist:[/b] " + s.GetArtist(), Song()));
|
mSearcher->IntoSeparator(8);
|
||||||
mSearcher->AddOption(make_pair("[.b]Album:[/b] " + s.GetAlbum(), Song()));
|
mSearcher->IntoSeparator(12);
|
||||||
mSearcher->AddOption(make_pair("[.b]Year:[/b] " + s.GetYear(), Song()));
|
|
||||||
mSearcher->AddOption(make_pair("[.b]Track:[/b] " + s.GetTrack(), Song()));
|
for (size_t i = 0; i < 15; i++)
|
||||||
mSearcher->AddOption(make_pair("[.b]Genre:[/b] " + s.GetGenre(), Song()));
|
{
|
||||||
mSearcher->AddOption(make_pair("[.b]Comment:[/b] " + s.GetComment(), Song()));
|
try
|
||||||
mSearcher->AddSeparator();
|
{
|
||||||
mSearcher->AddOption(make_pair("[.b]Search in:[/b] " + string(Config.search_in_db ? "Database" : "Current playlist"), Song()));
|
mSearcher->at(i).first = new Buffer();
|
||||||
mSearcher->AddOption(make_pair("[.b]Search mode:[/b] " + (search_match_to_pattern ? search_mode_normal : search_mode_strict), Song()));
|
}
|
||||||
mSearcher->AddOption(make_pair("[.b]Case sensitive:[/b] " + string(search_case_sensitive ? "Yes" : "No"), Song()));
|
catch (List::InvalidItem) { }
|
||||||
mSearcher->AddSeparator();
|
}
|
||||||
mSearcher->AddOption(make_pair("Search", Song()));
|
|
||||||
mSearcher->AddOption(make_pair("Reset", Song()));
|
*mSearcher->at(0).first << fmtBold << "Filename:" << fmtBoldEnd << ' ' << s.GetName();
|
||||||
|
*mSearcher->at(1).first << fmtBold << "Title:" << fmtBoldEnd << ' ' << s.GetTitle();
|
||||||
|
*mSearcher->at(2).first << fmtBold << "Artist:" << fmtBoldEnd << ' ' << s.GetArtist();
|
||||||
|
*mSearcher->at(3).first << fmtBold << "Album:" << fmtBoldEnd << ' ' << s.GetAlbum();
|
||||||
|
*mSearcher->at(4).first << fmtBold << "Year:" << fmtBoldEnd << ' ' << s.GetYear();
|
||||||
|
*mSearcher->at(5).first << fmtBold << "Track:" << fmtBoldEnd << ' ' << s.GetTrack();
|
||||||
|
*mSearcher->at(6).first << fmtBold << "Genre:" << fmtBoldEnd << ' ' << s.GetGenre();
|
||||||
|
*mSearcher->at(7).first << fmtBold << "Comment:" << fmtBoldEnd << ' ' << s.GetComment();
|
||||||
|
|
||||||
|
*mSearcher->at(9).first << fmtBold << "Search in:" << fmtBoldEnd << ' ' << (Config.search_in_db ? "Database" : "Current playlist");
|
||||||
|
*mSearcher->at(10).first << fmtBold << "Search mode:" << fmtBoldEnd << ' ' << (search_match_to_pattern ? search_mode_normal : search_mode_strict);
|
||||||
|
*mSearcher->at(11).first << fmtBold << "Case sensitive:" << fmtBoldEnd << ' ' << (search_case_sensitive ? "Yes" : "No");
|
||||||
|
|
||||||
|
*mSearcher->at(13).first << "Search";
|
||||||
|
*mSearcher->at(14).first << "Reset";
|
||||||
}
|
}
|
||||||
|
|
||||||
void Search(Song &s)
|
void Search(Song &s)
|
||||||
@@ -88,7 +116,7 @@ void Search(Song &s)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
list.reserve(mPlaylist->Size());
|
list.reserve(mPlaylist->Size());
|
||||||
for (int i = 0; i < mPlaylist->Size(); i++)
|
for (size_t i = 0; i < mPlaylist->Size(); i++)
|
||||||
list.push_back(&(*mPlaylist)[i]);
|
list.push_back(&(*mPlaylist)[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,7 +226,10 @@ void Search(Song &s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (found)
|
if (found)
|
||||||
mSearcher->AddOption(make_pair(".", **it));
|
{
|
||||||
|
mSearcher->AddOption(make_pair((Buffer *)0, *it));
|
||||||
|
list[it-list.begin()] = 0;
|
||||||
|
}
|
||||||
found = 1;
|
found = 1;
|
||||||
}
|
}
|
||||||
if (Config.search_in_db) // free song list only if it's database
|
if (Config.search_in_db) // free song list only if it's database
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
const int search_engine_static_options = 18;
|
const int search_engine_static_options = 18;
|
||||||
|
|
||||||
string SearchEngineDisplayer(const std::pair<string, Song> &, void *, const Menu< std::pair<string, Song> > *);
|
void SearchEngineDisplayer(const std::pair<Buffer *, Song *> &, void *, Menu< std::pair<Buffer *, Song *> > *);
|
||||||
void UpdateFoundList();
|
void UpdateFoundList();
|
||||||
void PrepareSearchEngine(Song &s);
|
void PrepareSearchEngine(Song &s);
|
||||||
void Search(Song &);
|
void Search(Song &);
|
||||||
|
|||||||
@@ -218,17 +218,17 @@ void DefaultKeys(ncmpcpp_keys &keys)
|
|||||||
void DefaultConfiguration(ncmpcpp_config &conf)
|
void DefaultConfiguration(ncmpcpp_config &conf)
|
||||||
{
|
{
|
||||||
conf.mpd_host = "localhost";
|
conf.mpd_host = "localhost";
|
||||||
conf.song_list_format = "{%a - }{%t}|{[.white]%f[/white]}%r{[.green](%l)[/green]}";
|
conf.song_list_format = "{%a - }{%t}|{$8%f$9}%r{$3(%l)$9}";
|
||||||
conf.song_columns_list_format = "(8)[green]{l} (25)[cyan]{a} (40){t} (30)[red]{b}";
|
conf.song_columns_list_format = "(8)[green]{l} (25)[cyan]{a} (40){t} (30)[red]{b}";
|
||||||
conf.song_status_format = "{(%l) }{%a - }{%t}|{%f}";
|
conf.song_status_format = "{(%l) }{%a - }{%t}|{%f}";
|
||||||
conf.song_window_title_format = "{%a - }{%t}|{%f}";
|
conf.song_window_title_format = "{%a - }{%t}|{%f}";
|
||||||
conf.song_library_format = "{%n - }{%t}|{%f}";
|
conf.song_library_format = "{%n - }{%t}|{%f}";
|
||||||
conf.media_lib_album_format = "{(%y) }%b";
|
conf.media_lib_album_format = "{(%y) }%b";
|
||||||
conf.tag_editor_album_format = "{(%y) }%b";
|
conf.tag_editor_album_format = "{(%y) }%b";
|
||||||
conf.browser_playlist_prefix = "[.red](playlist)[/red] ";
|
conf.browser_playlist_prefix << clRed << "(playlist)" << clEnd << ' ';
|
||||||
conf.pattern = "%n - %t";
|
conf.pattern = "%n - %t";
|
||||||
conf.selected_item_prefix = "[.magenta]";
|
conf.selected_item_prefix << clMagenta;
|
||||||
conf.selected_item_suffix = "[/magenta]";
|
conf.selected_item_suffix << clEnd;
|
||||||
conf.color1 = "white";
|
conf.color1 = "white";
|
||||||
conf.color2 = "green";
|
conf.color2 = "green";
|
||||||
conf.empty_tags_color = clCyan;
|
conf.empty_tags_color = clCyan;
|
||||||
@@ -569,7 +569,7 @@ void ReadConfiguration(ncmpcpp_config &conf)
|
|||||||
else if (it->find("browser_playlist_prefix") != string::npos)
|
else if (it->find("browser_playlist_prefix") != string::npos)
|
||||||
{
|
{
|
||||||
if (!v.empty())
|
if (!v.empty())
|
||||||
conf.browser_playlist_prefix = v;
|
conf.browser_playlist_prefix << v;
|
||||||
}
|
}
|
||||||
else if (it->find("default_tag_editor_pattern") != string::npos)
|
else if (it->find("default_tag_editor_pattern") != string::npos)
|
||||||
{
|
{
|
||||||
@@ -579,12 +579,12 @@ void ReadConfiguration(ncmpcpp_config &conf)
|
|||||||
else if (it->find("selected_item_prefix") != string::npos)
|
else if (it->find("selected_item_prefix") != string::npos)
|
||||||
{
|
{
|
||||||
if (!v.empty())
|
if (!v.empty())
|
||||||
conf.selected_item_prefix = v;
|
conf.selected_item_prefix << v;
|
||||||
}
|
}
|
||||||
else if (it->find("selected_item_suffix") != string::npos)
|
else if (it->find("selected_item_suffix") != string::npos)
|
||||||
{
|
{
|
||||||
if (!v.empty())
|
if (!v.empty())
|
||||||
conf.selected_item_suffix = v;
|
conf.selected_item_suffix << v;
|
||||||
}
|
}
|
||||||
else if (it->find("color1") != string::npos)
|
else if (it->find("color1") != string::npos)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -103,12 +103,12 @@ struct ncmpcpp_config
|
|||||||
string song_library_format;
|
string song_library_format;
|
||||||
string media_lib_album_format;
|
string media_lib_album_format;
|
||||||
string tag_editor_album_format;
|
string tag_editor_album_format;
|
||||||
string browser_playlist_prefix;
|
|
||||||
|
|
||||||
string pattern;
|
string pattern;
|
||||||
|
|
||||||
string selected_item_prefix;
|
Buffer browser_playlist_prefix;
|
||||||
string selected_item_suffix;
|
Buffer selected_item_prefix;
|
||||||
|
Buffer selected_item_suffix;
|
||||||
|
|
||||||
string color1;
|
string color1;
|
||||||
string color2;
|
string color2;
|
||||||
|
|||||||
152
src/song.cpp
152
src/song.cpp
@@ -282,6 +282,158 @@ void Song::SetPosition(int pos)
|
|||||||
itsSong->pos = pos;
|
itsSong->pos = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string Song::toString(const std::string &format) const
|
||||||
|
{
|
||||||
|
string result;
|
||||||
|
string::const_iterator goto_pos, prev_pos;
|
||||||
|
|
||||||
|
for (string::const_iterator it = format.begin(); it != format.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 && (this->*get)() == EMPTY_TAG)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*it == '}')
|
||||||
|
{
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (*it == '}' && *(it+1) != '|')
|
||||||
|
break;
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
goto_pos = ++it;
|
||||||
|
it = ++prev_pos;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (; *it != '}'; it++) { }
|
||||||
|
it++;
|
||||||
|
if (*it == '{' || *it == '|')
|
||||||
|
{
|
||||||
|
if (*it == '|')
|
||||||
|
it++;
|
||||||
|
goto CHECK_LINKED_TAGS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*it == '}')
|
||||||
|
{
|
||||||
|
if (goto_pos == format.end())
|
||||||
|
break;
|
||||||
|
it = goto_pos;
|
||||||
|
if (*it == '{')
|
||||||
|
goto CHECK_LINKED_TAGS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*it != '%')
|
||||||
|
{
|
||||||
|
result += *it;
|
||||||
|
}
|
||||||
|
else if (*it == '%')
|
||||||
|
{
|
||||||
|
switch (*++it)
|
||||||
|
{
|
||||||
|
case 'l':
|
||||||
|
result += GetLength();
|
||||||
|
break;
|
||||||
|
case 'F':
|
||||||
|
result += GetFile();
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
result += GetName();
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
result += GetArtist();
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
result += GetAlbum();
|
||||||
|
break;
|
||||||
|
case 'y':
|
||||||
|
result += GetYear();
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
result += GetTrack();
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
result += GetGenre();
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
result += GetComposer();
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
result += GetPerformer();
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
result += GetDisc();
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
result += GetComment();
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
result += GetTitle();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
Song & Song::operator=(const Song &s)
|
Song & Song::operator=(const Song &s)
|
||||||
{
|
{
|
||||||
if (this == &s)
|
if (this == &s)
|
||||||
|
|||||||
@@ -79,6 +79,8 @@ class Song
|
|||||||
void SetNewName(const string &name) { itsNewName = name == GetName() ? "" : name; }
|
void SetNewName(const string &name) { itsNewName = name == GetName() ? "" : name; }
|
||||||
string GetNewName() const { return itsNewName; }
|
string GetNewName() const { return itsNewName; }
|
||||||
|
|
||||||
|
std::string toString(const std::string &) const;
|
||||||
|
|
||||||
void NullMe() { itsSong = 0; }
|
void NullMe() { itsSong = 0; }
|
||||||
void CopyPtr(bool copy) { copyPtr = copy; }
|
void CopyPtr(bool copy) { copyPtr = copy; }
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "status_checker.h"
|
#include "status_checker.h"
|
||||||
|
|
||||||
#define UPDATE_WINDOW_TITLE WindowTitle(DisplaySong(Mpd->GetCurrentSong(), &Config.song_window_title_format))
|
#define UPDATE_WINDOW_TITLE WindowTitle(Mpd->GetCurrentSong().toString(Config.song_window_title_format))
|
||||||
|
|
||||||
using namespace MPD;
|
using namespace MPD;
|
||||||
|
|
||||||
@@ -76,10 +76,16 @@ bool allow_statusbar_unlock = 1;
|
|||||||
bool header_update_status = 0;
|
bool header_update_status = 0;
|
||||||
bool repeat_one_allowed = 0;
|
bool repeat_one_allowed = 0;
|
||||||
|
|
||||||
|
//time_t past, now = time(NULL)-1;
|
||||||
|
|
||||||
void TraceMpdStatus()
|
void TraceMpdStatus()
|
||||||
{
|
{
|
||||||
Mpd->UpdateStatus();
|
//past = time(NULL);
|
||||||
time_t now = time(NULL);
|
//if (past == now+1)
|
||||||
|
//{
|
||||||
|
Mpd->UpdateStatus();
|
||||||
|
time_t now = time(NULL);
|
||||||
|
//}
|
||||||
|
|
||||||
if (current_screen == csPlaylist && now == timer+Config.playlist_disable_highlight_delay)
|
if (current_screen == csPlaylist && now == timer+Config.playlist_disable_highlight_delay)
|
||||||
mPlaylist->Highlighting(!Config.playlist_disable_highlight_delay);
|
mPlaylist->Highlighting(!Config.playlist_disable_highlight_delay);
|
||||||
@@ -141,8 +147,12 @@ void NcmpcppStatusChanged(Connection *Mpd, StatusChanges changed, void *)
|
|||||||
{
|
{
|
||||||
old_playing = now_playing;
|
old_playing = now_playing;
|
||||||
now_playing = Mpd->GetCurrentSongPos();
|
now_playing = Mpd->GetCurrentSongPos();
|
||||||
mPlaylist->BoldOption(old_playing, 0);
|
try
|
||||||
mPlaylist->BoldOption(now_playing, 1);
|
{
|
||||||
|
mPlaylist->BoldOption(old_playing, 0);
|
||||||
|
mPlaylist->BoldOption(now_playing, 1);
|
||||||
|
}
|
||||||
|
catch (std::out_of_range) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changed.Playlist)
|
if (changed.Playlist)
|
||||||
@@ -161,6 +171,7 @@ void NcmpcppStatusChanged(Connection *Mpd, StatusChanges changed, void *)
|
|||||||
else
|
else
|
||||||
Mpd->GetPlaylistChanges(Mpd->GetOldPlaylistID(), list);
|
Mpd->GetPlaylistChanges(Mpd->GetOldPlaylistID(), list);
|
||||||
|
|
||||||
|
mPlaylist->Reserve(playlist_length);
|
||||||
for (SongList::const_iterator it = list.begin(); it != list.end(); it++)
|
for (SongList::const_iterator it = list.begin(); it != list.end(); it++)
|
||||||
{
|
{
|
||||||
mPlaylist->AddOption(**it, now_playing == (*it)->GetPosition());
|
mPlaylist->AddOption(**it, now_playing == (*it)->GetPosition());
|
||||||
@@ -183,7 +194,7 @@ void NcmpcppStatusChanged(Connection *Mpd, StatusChanges changed, void *)
|
|||||||
{
|
{
|
||||||
if (*list[i] != mPlaylist->at(i))
|
if (*list[i] != mPlaylist->at(i))
|
||||||
{
|
{
|
||||||
mPlaylist->UpdateOption(i, *list[i]);
|
mPlaylist->at(i) = *list[i];
|
||||||
mPlaylist->at(i).CopyPtr(0);
|
mPlaylist->at(i).CopyPtr(0);
|
||||||
list[i]->NullMe();
|
list[i]->NullMe();
|
||||||
}
|
}
|
||||||
@@ -263,7 +274,11 @@ void NcmpcppStatusChanged(Connection *Mpd, StatusChanges changed, void *)
|
|||||||
wFooter->SetColor(Config.progressbar_color);
|
wFooter->SetColor(Config.progressbar_color);
|
||||||
mvwhline(wFooter->Raw(), 0, 0, 0, wFooter->GetWidth());
|
mvwhline(wFooter->Raw(), 0, 0, 0, wFooter->GetWidth());
|
||||||
wFooter->SetColor(Config.statusbar_color);
|
wFooter->SetColor(Config.statusbar_color);
|
||||||
mPlaylist->BoldOption(old_playing, 0);
|
try
|
||||||
|
{
|
||||||
|
mPlaylist->BoldOption(old_playing, 0);
|
||||||
|
}
|
||||||
|
catch (std::out_of_range) { }
|
||||||
now_playing = -1;
|
now_playing = -1;
|
||||||
player_state.clear();
|
player_state.clear();
|
||||||
break;
|
break;
|
||||||
@@ -320,7 +335,7 @@ void NcmpcppStatusChanged(Connection *Mpd, StatusChanges changed, void *)
|
|||||||
tracklength = " [" + Song::ShowTime(elapsed) + "/" + s.GetLength() + "]";
|
tracklength = " [" + Song::ShowTime(elapsed) + "/" + s.GetLength() + "]";
|
||||||
else
|
else
|
||||||
tracklength = " [" + Song::ShowTime(elapsed) + "]";
|
tracklength = " [" + Song::ShowTime(elapsed) + "]";
|
||||||
my_string_t playing_song = TO_WSTRING(DisplaySong(s, &Config.song_status_format));
|
my_string_t playing_song = TO_WSTRING(s.toString(Config.song_status_format));
|
||||||
|
|
||||||
const size_t max_length_without_scroll = wFooter->GetWidth()-player_state.length()-tracklength.length();
|
const size_t max_length_without_scroll = wFooter->GetWidth()-player_state.length()-tracklength.length();
|
||||||
|
|
||||||
@@ -342,7 +357,7 @@ void NcmpcppStatusChanged(Connection *Mpd, StatusChanges changed, void *)
|
|||||||
playing_song_scroll_begin = 0;
|
playing_song_scroll_begin = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
wFooter->WriteXY(player_state.length(), 1, DisplaySong(s, &Config.song_status_format), 1);
|
wFooter->WriteXY(player_state.length(), 1, s.toString(Config.song_status_format), 1);
|
||||||
wFooter->Bold(1);
|
wFooter->Bold(1);
|
||||||
|
|
||||||
wFooter->WriteXY(wFooter->GetWidth()-tracklength.length(), 1, tracklength);
|
wFooter->WriteXY(wFooter->GetWidth()-tracklength.length(), 1, tracklength);
|
||||||
|
|||||||
154
src/strbuffer.h
Normal file
154
src/strbuffer.h
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2008 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., *
|
||||||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _STRBUFFER_H
|
||||||
|
#define _STRBUFFER_H
|
||||||
|
|
||||||
|
#include "window.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
struct FormatPos
|
||||||
|
{
|
||||||
|
size_t Position;
|
||||||
|
short Value;
|
||||||
|
|
||||||
|
bool operator<(const FormatPos &f)
|
||||||
|
{
|
||||||
|
return Position < f.Position;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class C> class basic_buffer
|
||||||
|
{
|
||||||
|
std::basic_ostringstream<C> itsString;
|
||||||
|
std::list<FormatPos> itsFormat;
|
||||||
|
std::basic_string<C> *itsTempString;
|
||||||
|
|
||||||
|
public:
|
||||||
|
basic_buffer() : itsTempString(0) { }
|
||||||
|
|
||||||
|
std::basic_string<C> Str() const;
|
||||||
|
void SetTemp(std::basic_string<C> *);
|
||||||
|
void Clear();
|
||||||
|
|
||||||
|
template <class T> basic_buffer<C> &operator<<(const T &t)
|
||||||
|
{
|
||||||
|
itsString << t;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
basic_buffer<C> &operator<<(std::ostream &(*os)(std::ostream &));
|
||||||
|
basic_buffer<C> &operator<<(const Color &color);
|
||||||
|
basic_buffer<C> &operator<<(const Format &f);
|
||||||
|
basic_buffer<C> &operator<<(const basic_buffer<C> &buf);
|
||||||
|
|
||||||
|
friend Window &operator<< <>(Window &, const basic_buffer<C> &);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef basic_buffer<char> Buffer;
|
||||||
|
typedef basic_buffer<wchar_t> WBuffer;
|
||||||
|
|
||||||
|
template <class C> std::basic_string<C> basic_buffer<C>::Str() const
|
||||||
|
{
|
||||||
|
return itsString.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class C> void basic_buffer<C>::SetTemp(std::basic_string<C> *tmp)
|
||||||
|
{
|
||||||
|
itsTempString = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class C> void basic_buffer<C>::Clear()
|
||||||
|
{
|
||||||
|
itsString.str(std::basic_string<C>());
|
||||||
|
itsFormat.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class C> basic_buffer<C> &basic_buffer<C>::operator<<(std::ostream &(*os)(std::ostream&))
|
||||||
|
{
|
||||||
|
itsString << os;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class C> basic_buffer<C> &basic_buffer<C>::operator<<(const Color &color)
|
||||||
|
{
|
||||||
|
FormatPos f;
|
||||||
|
f.Position = itsString.str().length();
|
||||||
|
f.Value = color;
|
||||||
|
itsFormat.push_back(f);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class C> basic_buffer<C> &basic_buffer<C>::operator<<(const Format &f)
|
||||||
|
{
|
||||||
|
return operator<<(Color(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class C> basic_buffer<C> &basic_buffer<C>::operator<<(const basic_buffer<C> &buf)
|
||||||
|
{
|
||||||
|
size_t len = itsString.str().length();
|
||||||
|
itsString << buf.itsString.str();
|
||||||
|
std::list<FormatPos> tmp = buf.itsFormat;
|
||||||
|
if (len)
|
||||||
|
for (std::list<FormatPos>::iterator it = tmp.begin(); it != tmp.end(); it++)
|
||||||
|
it->Position += len;
|
||||||
|
itsFormat.merge(tmp);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class C> Window &operator<<(Window &w, const basic_buffer<C> &buf)
|
||||||
|
{
|
||||||
|
const std::basic_string<C> &s = buf.itsTempString ? *buf.itsTempString : buf.itsString.str();
|
||||||
|
if (buf.itsFormat.empty())
|
||||||
|
{
|
||||||
|
w << s;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::basic_string<C> tmp;
|
||||||
|
std::list<FormatPos>::const_iterator b = buf.itsFormat.begin(), e = buf.itsFormat.end();
|
||||||
|
for (size_t i = 0; i < s.length() || b != e; i++)
|
||||||
|
{
|
||||||
|
while (b != e && i == b->Position)
|
||||||
|
{
|
||||||
|
if (!tmp.empty())
|
||||||
|
{
|
||||||
|
w << tmp;
|
||||||
|
tmp.clear();
|
||||||
|
}
|
||||||
|
if (b->Value < 100)
|
||||||
|
w << Color(b->Value);
|
||||||
|
else
|
||||||
|
w << Format(b->Value);
|
||||||
|
b++;
|
||||||
|
}
|
||||||
|
if (i < s.length())
|
||||||
|
tmp += s[i];
|
||||||
|
}
|
||||||
|
if (!tmp.empty())
|
||||||
|
w << tmp;
|
||||||
|
}
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ extern ncmpcpp_keys Key;
|
|||||||
extern Connection *Mpd;
|
extern Connection *Mpd;
|
||||||
extern Menu<Song> *mPlaylist;
|
extern Menu<Song> *mPlaylist;
|
||||||
|
|
||||||
extern Menu<string> *mTagEditor;
|
extern Menu<Buffer> *mTagEditor;
|
||||||
extern Window *wFooter;
|
extern Window *wFooter;
|
||||||
extern Window *wPrev;
|
extern Window *wPrev;
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ namespace
|
|||||||
|
|
||||||
string GenerateFilename(const Song &s, string &pattern)
|
string GenerateFilename(const Song &s, string &pattern)
|
||||||
{
|
{
|
||||||
string result = DisplaySong(s, &pattern);
|
string result = s.toString(pattern);
|
||||||
EscapeUnallowedChars(result);
|
EscapeUnallowedChars(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -221,34 +221,48 @@ string FindSharedDir(const SongList &v)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
string DisplayTag(const Song &s, void *data, const Menu<Song> *)
|
void DisplayTag(const Song &s, void *data, Menu<Song> *menu)
|
||||||
{
|
{
|
||||||
switch (static_cast<Menu<string> *>(data)->GetChoice())
|
switch (static_cast<Menu<string> *>(data)->Choice())
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
return s.GetTitle();
|
*menu << s.GetTitle();
|
||||||
|
return;
|
||||||
case 1:
|
case 1:
|
||||||
return s.GetArtist();
|
*menu << s.GetArtist();
|
||||||
|
return;
|
||||||
case 2:
|
case 2:
|
||||||
return s.GetAlbum();
|
*menu << s.GetAlbum();
|
||||||
|
return;
|
||||||
case 3:
|
case 3:
|
||||||
return s.GetYear();
|
*menu << s.GetYear();
|
||||||
|
return;
|
||||||
case 4:
|
case 4:
|
||||||
return s.GetTrack();
|
*menu << s.GetTrack();
|
||||||
|
return;
|
||||||
case 5:
|
case 5:
|
||||||
return s.GetGenre();
|
*menu << s.GetGenre();
|
||||||
|
return;
|
||||||
case 6:
|
case 6:
|
||||||
return s.GetComposer();
|
*menu << s.GetComposer();
|
||||||
|
return;
|
||||||
case 7:
|
case 7:
|
||||||
return s.GetPerformer();
|
*menu << s.GetPerformer();
|
||||||
|
return;
|
||||||
case 8:
|
case 8:
|
||||||
return s.GetDisc();
|
*menu << s.GetDisc();
|
||||||
|
return;
|
||||||
case 9:
|
case 9:
|
||||||
return s.GetComment();
|
*menu << s.GetComment();
|
||||||
|
return;
|
||||||
case 11:
|
case 11:
|
||||||
return s.GetNewName().empty() ? s.GetName() : s.GetName() + " [." + Config.color2 + "]->[/" + Config.color2 + "] " + s.GetNewName();
|
if (s.GetNewName().empty())
|
||||||
|
*menu << s.GetName();
|
||||||
|
else
|
||||||
|
*menu << s.GetName() << clGreen << " -> " << clEnd << s.GetNewName();
|
||||||
|
return;
|
||||||
default:
|
default:
|
||||||
return "";
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,31 +321,41 @@ bool GetSongTags(Song &s)
|
|||||||
mTagEditor->Clear();
|
mTagEditor->Clear();
|
||||||
mTagEditor->Reset();
|
mTagEditor->Reset();
|
||||||
|
|
||||||
mTagEditor->AddOption("[.b][." + Config.color1 + "]Song name: [/" + Config.color1 + "][." + Config.color2 + "][/b]" + s.GetName() + "[/" + Config.color2 + "]", 0, 1);
|
mTagEditor->ResizeBuffer(23);
|
||||||
mTagEditor->AddOption("[.b][." + Config.color1 + "]Location in DB: [/" + Config.color1 + "][." + Config.color2 + "][/b]" + s.GetDirectory() + "[/" + Config.color2 + "]", 0, 1);
|
for (size_t i = 0; i < 7; i++)
|
||||||
mTagEditor->AddOption("", 0, 1);
|
mTagEditor->Static(i, 1);
|
||||||
mTagEditor->AddOption("[.b][." + Config.color1 + "]Length: [/" + Config.color1 + "][." + Config.color2 + "][/b]" + s.GetLength() + "[/" + Config.color2 + "]", 0, 1);
|
mTagEditor->IntoSeparator(7);
|
||||||
mTagEditor->AddOption("[.b][." + Config.color1 + "]Bitrate: [/" + Config.color1 + "][." + Config.color2 + "][/b]" + IntoStr(f.audioProperties()->bitrate()) + " kbps[/" + Config.color2 + "]", 0, 1);
|
mTagEditor->IntoSeparator(18);
|
||||||
mTagEditor->AddOption("[.b][." + Config.color1 + "]Sample rate: [/" + Config.color1 + "][." + Config.color2 + "][/b]" + IntoStr(f.audioProperties()->sampleRate()) + " Hz[/" + Config.color2 + "]", 0, 1);
|
mTagEditor->IntoSeparator(20);
|
||||||
mTagEditor->AddOption("[.b][." + Config.color1 + "]Channels: [/" + Config.color1 + "][." + Config.color2 + "][/b]" + (string)(f.audioProperties()->channels() == 1 ? "Mono" : "Stereo") + "[/" + Config.color2 + "]", 0, 1);
|
|
||||||
|
|
||||||
mTagEditor->AddSeparator();
|
if (ext != "mp3")
|
||||||
|
for (size_t i = 14; i <= 16; i++)
|
||||||
|
mTagEditor->Static(i, 1);
|
||||||
|
|
||||||
mTagEditor->AddOption("[.b]Title:[/b] " + s.GetTitle());
|
mTagEditor->Highlight(8);
|
||||||
mTagEditor->AddOption("[.b]Artist:[/b] " + s.GetArtist());
|
|
||||||
mTagEditor->AddOption("[.b]Album:[/b] " + s.GetAlbum());
|
mTagEditor->at(0) << fmtBold << clWhite << "Song name: " << fmtBoldEnd << clGreen << s.GetName() << clEnd;
|
||||||
mTagEditor->AddOption("[.b]Year:[/b] " + s.GetYear());
|
mTagEditor->at(1) << fmtBold << clWhite << "Location in DB: " << fmtBoldEnd << clGreen << s.GetDirectory() << clEnd;
|
||||||
mTagEditor->AddOption("[.b]Track:[/b] " + s.GetTrack());
|
mTagEditor->at(3) << fmtBold << clWhite << "Length: " << fmtBoldEnd << clGreen << s.GetLength() << clEnd;
|
||||||
mTagEditor->AddOption("[.b]Genre:[/b] " + s.GetGenre());
|
mTagEditor->at(4) << fmtBold << clWhite << "Bitrate: " << fmtBoldEnd << clGreen << f.audioProperties()->bitrate() << " kbps" << clEnd;
|
||||||
mTagEditor->AddOption("[.b]Composer:[/b] " + s.GetComposer(), 0, ext != "mp3");
|
mTagEditor->at(5) << fmtBold << clWhite << "Sample rate: " << fmtBoldEnd << clGreen << f.audioProperties()->sampleRate() << " Hz" << clEnd;
|
||||||
mTagEditor->AddOption("[.b]Performer:[/b] " + s.GetPerformer(), 0, ext != "mp3");
|
mTagEditor->at(6) << fmtBold << clWhite << "Channels: " << fmtBoldEnd << clGreen << (f.audioProperties()->channels() == 1 ? "Mono" : "Stereo") << clDefault;
|
||||||
mTagEditor->AddOption("[.b]Disc:[/b] " + s.GetDisc(), 0, ext != "mp3");
|
|
||||||
mTagEditor->AddOption("[.b]Comment:[/b] " + s.GetComment());
|
mTagEditor->at(8) << fmtBold << "Title:" << fmtBoldEnd << ' ' << s.GetTitle();
|
||||||
mTagEditor->AddSeparator();
|
mTagEditor->at(9) << fmtBold << "Artist:" << fmtBoldEnd << ' ' << s.GetArtist();
|
||||||
mTagEditor->AddOption("[.b]Filename:[/b] " + s.GetName());
|
mTagEditor->at(10) << fmtBold << "Album:" << fmtBoldEnd << ' ' << s.GetAlbum();
|
||||||
mTagEditor->AddSeparator();
|
mTagEditor->at(11) << fmtBold << "Year:" << fmtBoldEnd << ' ' << s.GetYear();
|
||||||
mTagEditor->AddOption("Save");
|
mTagEditor->at(12) << fmtBold << "Track:" << fmtBoldEnd << ' ' << s.GetTrack();
|
||||||
mTagEditor->AddOption("Cancel");
|
mTagEditor->at(13) << fmtBold << "Genre:" << fmtBoldEnd << ' ' <<s.GetGenre();
|
||||||
|
mTagEditor->at(14) << fmtBold << "Composer:" << fmtBoldEnd << ' ' << s.GetComposer();
|
||||||
|
mTagEditor->at(15) << fmtBold << "Performer:" << fmtBoldEnd << ' ' << s.GetPerformer();
|
||||||
|
mTagEditor->at(16) << fmtBold << "Disc:" << fmtBoldEnd << ' ' << s.GetDisc();
|
||||||
|
mTagEditor->at(17) << fmtBold << "Comment:" << fmtBoldEnd << ' ' << s.GetComment();
|
||||||
|
|
||||||
|
mTagEditor->at(19) << fmtBold << "Filename:" << fmtBoldEnd << ' ' << s.GetName();
|
||||||
|
|
||||||
|
mTagEditor->at(21) << "Save";
|
||||||
|
mTagEditor->at(22) << "Cancel";
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,7 +422,7 @@ bool WriteTags(Song &s)
|
|||||||
{
|
{
|
||||||
// if we rename local file, it won't get updated
|
// if we rename local file, it won't get updated
|
||||||
// so just remove it from playlist and add again
|
// so just remove it from playlist and add again
|
||||||
int pos = mPlaylist->GetChoice();
|
int pos = mPlaylist->Choice();
|
||||||
Mpd->QueueDeleteSong(pos);
|
Mpd->QueueDeleteSong(pos);
|
||||||
Mpd->CommitQueue();
|
Mpd->CommitQueue();
|
||||||
int id = Mpd->AddSong("file://" + new_name);
|
int id = Mpd->AddSong("file://" + new_name);
|
||||||
@@ -427,6 +451,7 @@ void __deal_with_filenames(SongList &v)
|
|||||||
|
|
||||||
Menu<string> *Main = new Menu<string>((COLS-width)/2, (LINES-height)/2, width, height, "", Config.main_color, Config.window_border);
|
Menu<string> *Main = new Menu<string>((COLS-width)/2, (LINES-height)/2, width, height, "", Config.main_color, Config.window_border);
|
||||||
Main->SetTimeout(ncmpcpp_window_timeout);
|
Main->SetTimeout(ncmpcpp_window_timeout);
|
||||||
|
Main->SetItemDisplayer(GenericDisplayer);
|
||||||
Main->AddOption("Get tags from filename");
|
Main->AddOption("Get tags from filename");
|
||||||
Main->AddOption("Rename files");
|
Main->AddOption("Rename files");
|
||||||
Main->AddSeparator();
|
Main->AddSeparator();
|
||||||
@@ -449,7 +474,7 @@ void __deal_with_filenames(SongList &v)
|
|||||||
height = LINES*0.8;
|
height = LINES*0.8;
|
||||||
bool exit = 0;
|
bool exit = 0;
|
||||||
bool preview = 1;
|
bool preview = 1;
|
||||||
int choice = Main->GetChoice();
|
int choice = Main->Choice();
|
||||||
int one_width = width/2;
|
int one_width = width/2;
|
||||||
int two_width = width-one_width;
|
int two_width = width-one_width;
|
||||||
|
|
||||||
@@ -465,19 +490,20 @@ void __deal_with_filenames(SongList &v)
|
|||||||
{
|
{
|
||||||
Legend = new Scrollpad((COLS-width)/2+one_width, (LINES-height)/2, two_width, height, "Legend", Config.main_color, Config.window_border);
|
Legend = new Scrollpad((COLS-width)/2+one_width, (LINES-height)/2, two_width, height, "Legend", Config.main_color, Config.window_border);
|
||||||
Legend->SetTimeout(ncmpcpp_window_timeout);
|
Legend->SetTimeout(ncmpcpp_window_timeout);
|
||||||
/* Legend->Add("%a - artist\n");
|
*Legend << "%a - artist\n";
|
||||||
Legend->Add("%t - title\n");
|
*Legend << "%t - title\n";
|
||||||
Legend->Add("%b - album\n");
|
*Legend << "%b - album\n";
|
||||||
Legend->Add("%y - year\n");
|
*Legend << "%y - year\n";
|
||||||
Legend->Add("%n - track number\n");
|
*Legend << "%n - track number\n";
|
||||||
Legend->Add("%g - genre\n");
|
*Legend << "%g - genre\n";
|
||||||
Legend->Add("%c - composer\n");
|
*Legend << "%c - composer\n";
|
||||||
Legend->Add("%p - performer\n");
|
*Legend << "%p - performer\n";
|
||||||
Legend->Add("%d - disc\n");
|
*Legend << "%d - disc\n";
|
||||||
Legend->Add("%C - comment\n\n");
|
*Legend << "%C - comment\n\n";
|
||||||
Legend->Add("[.b]Files:[/b]\n");
|
*Legend << fmtBold << "Files:\n" << fmtBoldEnd;
|
||||||
for (SongList::const_iterator it = v.begin(); it != v.end(); it++)
|
for (SongList::const_iterator it = v.begin(); it != v.end(); it++)
|
||||||
Legend->Add("[." + Config.color2 + "]*[/" + Config.color2 + "] " + (*it)->GetName() + "\n");*/
|
*Legend << clGreen << " * " << clEnd << (*it)->GetName() << "\n";
|
||||||
|
Legend->Flush();
|
||||||
|
|
||||||
Preview = static_cast<Scrollpad *>(Legend->EmptyClone());
|
Preview = static_cast<Scrollpad *>(Legend->EmptyClone());
|
||||||
Preview->SetTitle("Preview");
|
Preview->SetTitle("Preview");
|
||||||
@@ -485,10 +511,11 @@ void __deal_with_filenames(SongList &v)
|
|||||||
|
|
||||||
Main = new Menu<string>((COLS-width)/2, (LINES-height)/2, one_width, height, "", Config.main_color, Config.active_window_border);
|
Main = new Menu<string>((COLS-width)/2, (LINES-height)/2, one_width, height, "", Config.main_color, Config.active_window_border);
|
||||||
Main->SetTimeout(ncmpcpp_window_timeout);
|
Main->SetTimeout(ncmpcpp_window_timeout);
|
||||||
|
Main->SetItemDisplayer(GenericDisplayer);
|
||||||
|
|
||||||
if (!patterns_list.empty())
|
if (!patterns_list.empty())
|
||||||
Config.pattern = patterns_list.front();
|
Config.pattern = patterns_list.front();
|
||||||
Main->AddOption("[.b]Pattern:[/b] " + Config.pattern);
|
Main->AddOption("Pattern: " + Config.pattern);
|
||||||
Main->AddOption("Preview");
|
Main->AddOption("Preview");
|
||||||
Main->AddOption("Legend");
|
Main->AddOption("Legend");
|
||||||
Main->AddSeparator();
|
Main->AddSeparator();
|
||||||
@@ -497,7 +524,7 @@ void __deal_with_filenames(SongList &v)
|
|||||||
if (!patterns_list.empty())
|
if (!patterns_list.empty())
|
||||||
{
|
{
|
||||||
Main->AddSeparator();
|
Main->AddSeparator();
|
||||||
Main->AddOption("Recent patterns", 1, 1, 0, lCenter);
|
Main->AddOption("Recent patterns", 1, 1, 0);
|
||||||
Main->AddSeparator();
|
Main->AddSeparator();
|
||||||
for (vector<string>::const_iterator it = patterns_list.begin(); it != patterns_list.end(); it++)
|
for (vector<string>::const_iterator it = patterns_list.begin(); it != patterns_list.end(); it++)
|
||||||
Main->AddOption(*it);
|
Main->AddOption(*it);
|
||||||
@@ -530,18 +557,18 @@ void __deal_with_filenames(SongList &v)
|
|||||||
Active->Scroll(wEnd);
|
Active->Scroll(wEnd);
|
||||||
else if (Keypressed(input, Key.Enter) && Active == Main)
|
else if (Keypressed(input, Key.Enter) && Active == Main)
|
||||||
{
|
{
|
||||||
switch (Main->GetRealChoice())
|
switch (Main->RealChoice())
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
LockStatusbar();
|
LockStatusbar();
|
||||||
wFooter->WriteXY(0, Config.statusbar_visibility, "[.b]Pattern:[/b] ", 1);
|
wFooter->WriteXY(0, Config.statusbar_visibility, "Pattern: ", 1);
|
||||||
string new_pattern = wFooter->GetString(Config.pattern);
|
string new_pattern = wFooter->GetString(Config.pattern);
|
||||||
UnlockStatusbar();
|
UnlockStatusbar();
|
||||||
if (!new_pattern.empty())
|
if (!new_pattern.empty())
|
||||||
{
|
{
|
||||||
Config.pattern = new_pattern;
|
Config.pattern = new_pattern;
|
||||||
Main->UpdateOption(0, "[.b]Pattern:[/b] " + Config.pattern);
|
Main->at(0) = "Pattern: " + Config.pattern;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -559,8 +586,8 @@ void __deal_with_filenames(SongList &v)
|
|||||||
{
|
{
|
||||||
if (preview)
|
if (preview)
|
||||||
{
|
{
|
||||||
// Preview->Add("[.b]" + s.GetName() + ":[/b]\n");
|
*Preview << fmtBold << s.GetName() << ":\n" << fmtBoldEnd;
|
||||||
// Preview->Add(ParseFilename(s, Config.pattern, preview) + "\n");
|
*Preview << ParseFilename(s, Config.pattern, preview) << "\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ParseFilename(s, Config.pattern, preview);
|
ParseFilename(s, Config.pattern, preview);
|
||||||
@@ -571,11 +598,12 @@ void __deal_with_filenames(SongList &v)
|
|||||||
int last_dot = file.find_last_of(".");
|
int last_dot = file.find_last_of(".");
|
||||||
string extension = file.substr(last_dot);
|
string extension = file.substr(last_dot);
|
||||||
s.GetEmptyFields(1);
|
s.GetEmptyFields(1);
|
||||||
string new_file = GenerateFilename(s, Config.pattern);
|
basic_buffer<my_char_t> new_file;
|
||||||
if (new_file.empty())
|
new_file << TO_WSTRING(GenerateFilename(s, Config.pattern));
|
||||||
|
if (new_file.Str().empty())
|
||||||
{
|
{
|
||||||
if (preview)
|
if (preview)
|
||||||
new_file = "[.red]!EMPTY![/red]";
|
new_file << clRed << "!EMPTY!" << clEnd;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ShowMessage("File '%s' would have an empty name!", s.GetName().c_str());
|
ShowMessage("File '%s' would have an empty name!", s.GetName().c_str());
|
||||||
@@ -584,8 +612,8 @@ void __deal_with_filenames(SongList &v)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!preview)
|
if (!preview)
|
||||||
s.SetNewName(new_file + extension);
|
s.SetNewName(TO_STRING(new_file.Str()) + extension);
|
||||||
// Preview->Add(file + " [." + Config.color2 + "]->[/" + Config.color2 + "] " + new_file + extension + "\n\n");
|
*Preview << file << clGreen << " -> " << clEnd << new_file << extension << "\n\n";
|
||||||
s.GetEmptyFields(0);
|
s.GetEmptyFields(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -610,6 +638,7 @@ void __deal_with_filenames(SongList &v)
|
|||||||
if (preview)
|
if (preview)
|
||||||
{
|
{
|
||||||
Helper = Preview;
|
Helper = Preview;
|
||||||
|
Helper->Flush();
|
||||||
Helper->Display();
|
Helper->Display();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -627,8 +656,8 @@ void __deal_with_filenames(SongList &v)
|
|||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
Config.pattern = Main->GetOption();
|
Config.pattern = Main->Current();
|
||||||
Main->UpdateOption(0, "[.b]Pattern:[/b] " + Config.pattern);
|
Main->at(0) = "Pattern: " + Config.pattern;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,10 +33,11 @@
|
|||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
typedef void (Song::*SongSetFunction)(const string &);
|
typedef void (Song::*SongSetFunction)(const string &);
|
||||||
|
typedef string (Song::*SongGetFunction)() const;
|
||||||
|
|
||||||
string FindSharedDir(Menu<Song> *);
|
string FindSharedDir(Menu<Song> *);
|
||||||
string FindSharedDir(const MPD::SongList &);
|
string FindSharedDir(const MPD::SongList &);
|
||||||
string DisplayTag(const Song &, void *, const Menu<Song> *);
|
void DisplayTag(const Song &, void *, Menu<Song> *);
|
||||||
|
|
||||||
SongSetFunction IntoSetFunction(mpd_TagItems);
|
SongSetFunction IntoSetFunction(mpd_TagItems);
|
||||||
|
|
||||||
|
|||||||
14
src/window.h
14
src/window.h
@@ -158,20 +158,6 @@ class Window
|
|||||||
virtual Window *Clone() const { return new Window(*this); }
|
virtual Window *Clone() const { return new Window(*this); }
|
||||||
virtual Window *EmptyClone() const;
|
virtual Window *EmptyClone() const;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// stubs for inherits, ugly shit, needs improvement
|
|
||||||
virtual void Select(int, bool) { }
|
|
||||||
virtual bool Selected(int) const { return 0; }
|
|
||||||
virtual int Size() const { return 0; }
|
|
||||||
virtual bool IsAnySelected() const { return 0; }
|
|
||||||
virtual void GetSelectedList(vector<int> &) const { }
|
|
||||||
virtual bool IsStatic(int = -1) const { return 0; }
|
|
||||||
virtual void Highlight(int) { }
|
|
||||||
virtual string GetOption(int = -1) const { return ""; }
|
|
||||||
virtual int GetChoice() const { return -1; } // for Menu class
|
|
||||||
//virtual void Add(string str) { Write(str); } // for Scrollpad class
|
|
||||||
|
|
||||||
static size_t Length(const wstring &);
|
static size_t Length(const wstring &);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
Reference in New Issue
Block a user