'repeat one song' mode added + memleak fix and some code clean-ups

This commit is contained in:
unK
2008-08-27 15:55:01 +02:00
parent 070b0dee32
commit e4b80d5ac8
12 changed files with 67 additions and 29 deletions

View File

@@ -61,6 +61,8 @@
# #
#key_toggle_repeat = 'r' #key_toggle_repeat = 'r'
# #
#key_toggle_repeat_one = 'R'
#
#key_toggle_random = 'z' #key_toggle_random = 'z'
# #
#key_shuffle = 'Z' #key_shuffle = 'Z'

View File

@@ -74,6 +74,8 @@
# #
#autocenter_mode = "no" #autocenter_mode = "no"
# #
#repeat_one_mode = "no"
#
#header_visibility = "yes" #header_visibility = "yes"
# #
#statusbar_visibility = "yes" #statusbar_visibility = "yes"

View File

@@ -563,7 +563,7 @@ bool Menu::IsStatic(int option)
} }
} }
Menu Menu::EmptyClone() Window * Menu::EmptyClone()
{ {
return Menu(GetStartX(),GetStartY(),GetWidth(),GetHeight(),itsTitle,itsBaseColor,itsBorder); return new Menu(GetStartX(),GetStartY(),GetWidth(),GetHeight(),itsTitle,itsBaseColor,itsBorder);
} }

View File

@@ -77,8 +77,7 @@ class Menu : public Window
bool Empty() { return itsOptions.empty(); } bool Empty() { return itsOptions.empty(); }
bool IsStatic(int); bool IsStatic(int);
Menu EmptyClone(); virtual Window * EmptyClone();
protected: protected:
vector<Option *> itsOptions; vector<Option *> itsOptions;
vector<int> NeedsRedraw; vector<int> NeedsRedraw;

View File

@@ -190,9 +190,9 @@ int main(int argc, char *argv[])
main_height++; 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.main_color, brNone);
mBrowser = new Menu(mPlaylist->EmptyClone()); mBrowser = static_cast<Menu *>(mPlaylist->EmptyClone());
mTagEditor = new Menu(mPlaylist->EmptyClone()); mTagEditor = static_cast<Menu *>(mPlaylist->EmptyClone());
mSearcher = new Menu(mPlaylist->EmptyClone()); mSearcher = static_cast<Menu *>(mPlaylist->EmptyClone());
int lib_artist_width = COLS/3-1; int lib_artist_width = COLS/3-1;
int lib_albums_width = COLS/3; int lib_albums_width = COLS/3;
@@ -205,7 +205,7 @@ int main(int argc, char *argv[])
mLibSongs = new Menu(lib_songs_start_x, main_start_y, lib_songs_width, main_height, "Songs", Config.main_color, brNone); mLibSongs = new Menu(lib_songs_start_x, main_start_y, lib_songs_width, main_height, "Songs", Config.main_color, brNone);
sHelp = new Scrollpad(0, main_start_y, COLS, main_height, "", Config.main_color, brNone); sHelp = new Scrollpad(0, main_start_y, COLS, main_height, "", Config.main_color, brNone);
sLyrics = new Scrollpad(sHelp->EmptyClone()); sLyrics = static_cast<Scrollpad *>(sHelp->EmptyClone());
sHelp->Add(" [b]Keys - Movement\n -----------------------------------------[/b]\n"); sHelp->Add(" [b]Keys - Movement\n -----------------------------------------[/b]\n");
sHelp->Add(DisplayKeys(Key.Up) + "Move Cursor up\n"); sHelp->Add(DisplayKeys(Key.Up) + "Move Cursor up\n");
@@ -233,6 +233,7 @@ int main(int argc, char *argv[])
sHelp->Add(DisplayKeys(Key.VolumeUp) + "Increase volume\n\n"); sHelp->Add(DisplayKeys(Key.VolumeUp) + "Increase volume\n\n");
sHelp->Add(DisplayKeys(Key.ToggleRepeat) + "Toggle repeat mode\n"); sHelp->Add(DisplayKeys(Key.ToggleRepeat) + "Toggle repeat mode\n");
sHelp->Add(DisplayKeys(Key.ToggleRepeatOne) + "Toggle \"repeat one\" mode\n");
sHelp->Add(DisplayKeys(Key.ToggleRandom) + "Toggle random mode\n"); sHelp->Add(DisplayKeys(Key.ToggleRandom) + "Toggle random mode\n");
sHelp->Add(DisplayKeys(Key.Shuffle) + "Shuffle playlist\n"); sHelp->Add(DisplayKeys(Key.Shuffle) + "Shuffle playlist\n");
sHelp->Add(DisplayKeys(Key.ToggleCrossfade) + "Toggle crossfade mode\n"); sHelp->Add(DisplayKeys(Key.ToggleCrossfade) + "Toggle crossfade mode\n");
@@ -431,21 +432,21 @@ int main(int argc, char *argv[])
mLibAlbums->Clear(); mLibAlbums->Clear();
Mpd->GetAlbums(mLibArtists->GetCurrentOption(), list); Mpd->GetAlbums(mLibArtists->GetCurrentOption(), list);
for (TagList::const_iterator it = list.begin(); it != list.end(); it++) for (TagList::const_iterator it = list.begin(); it != list.end(); it++)
mLibAlbums->AddOption(*it); mLibAlbums->AddOption(*it);
} }
FreeSongList(vSongs);
if (mLibAlbums->Empty()) if (mLibAlbums->Empty())
{ {
mLibAlbums->WriteXY(0, 0, "No albums found."); mLibAlbums->WriteXY(0, 0, "No albums found.");
mLibSongs->Clear(0); mLibSongs->Clear(0);
FreeSongList(vSongs);
Mpd->StartSearch(1); Mpd->StartSearch(1);
Mpd->AddSearch(MPD_TAG_ITEM_ARTIST, mLibArtists->GetCurrentOption()); Mpd->AddSearch(MPD_TAG_ITEM_ARTIST, mLibArtists->GetCurrentOption());
Mpd->CommitSearch(vSongs); Mpd->CommitSearch(vSongs);
} }
else else
{ {
FreeSongList(vSongs);
mLibSongs->Clear(0); mLibSongs->Clear(0);
Mpd->StartSearch(1); Mpd->StartSearch(1);
Mpd->AddSearch(MPD_TAG_ITEM_ARTIST, mLibArtists->GetCurrentOption()); Mpd->AddSearch(MPD_TAG_ITEM_ARTIST, mLibArtists->GetCurrentOption());
@@ -974,7 +975,7 @@ int main(int argc, char *argv[])
{ {
found_pos = 0; found_pos = 0;
vFoundPositions.clear(); vFoundPositions.clear();
vSearched.clear(); FreeSongList(vSearched);
PrepareSearchEngine(searched_song); PrepareSearchEngine(searched_song);
ShowMessage("Search state reset"); ShowMessage("Search state reset");
break; break;
@@ -1323,25 +1324,25 @@ int main(int argc, char *argv[])
wFooter->WriteXY(0, Config.statusbar_visibility, "Add: ", 1); wFooter->WriteXY(0, Config.statusbar_visibility, "Add: ", 1);
string path = wFooter->GetString(""); string path = wFooter->GetString("");
UNLOCK_STATUSBAR; UNLOCK_STATUSBAR;
SongList list; if (!path.empty())
Mpd->GetDirectoryRecursive(path, list);
if (!list.empty())
{ {
for (SongList::const_iterator it = list.begin(); it != list.end(); it++) SongList list;
Mpd->QueueAddSong(**it); Mpd->GetDirectoryRecursive(path, list);
if (Mpd->CommitQueue()) if (!list.empty())
{ {
Song *s = vPlaylist[vPlaylist.size()-list.size()]; for (SongList::const_iterator it = list.begin(); it != list.end(); it++)
if (s->GetHash() != list[0]->GetHash()) Mpd->QueueAddSong(**it);
ShowMessage(message_part_of_songs_added); if (Mpd->CommitQueue())
{
Song *s = vPlaylist[vPlaylist.size()-list.size()];
if (s->GetHash() != list[0]->GetHash())
ShowMessage(message_part_of_songs_added);
}
} }
} else
else
{
if (!path.empty())
Mpd->AddSong(path); Mpd->AddSong(path);
FreeSongList(list);
} }
FreeSongList(list);
} }
else if (Keypressed(input, Key.SeekForward) || Keypressed(input, Key.SeekBackward)) else if (Keypressed(input, Key.SeekForward) || Keypressed(input, Key.SeekBackward))
{ {
@@ -1413,6 +1414,11 @@ int main(int argc, char *argv[])
} }
else if (Keypressed(input, Key.ToggleRepeat)) else if (Keypressed(input, Key.ToggleRepeat))
Mpd->SetRepeat(!Mpd->GetRepeat()); Mpd->SetRepeat(!Mpd->GetRepeat());
else if (Keypressed(input, Key.ToggleRepeatOne))
{
Config.repeat_one_mode = !Config.repeat_one_mode;
ShowMessage("'Repeat one' mode: " + string(Config.repeat_one_mode ? "On" : "Off"));
}
else if (Keypressed(input, Key.Shuffle)) else if (Keypressed(input, Key.Shuffle))
Mpd->Shuffle(); Mpd->Shuffle();
else if (Keypressed(input, Key.ToggleRandom)) else if (Keypressed(input, Key.ToggleRandom))

View File

@@ -215,9 +215,9 @@ void Scrollpad::Clear()
Window::Clear(); Window::Clear();
} }
Scrollpad Scrollpad::EmptyClone() Window * Scrollpad::EmptyClone()
{ {
return Scrollpad(GetStartX(),GetStartY(),GetWidth(),GetHeight(),itsTitle,itsBaseColor,itsBorder); return new Scrollpad(GetStartX(),GetStartY(),GetWidth(),GetHeight(),itsTitle,itsBaseColor,itsBorder);
} }
Scrollpad & Scrollpad::operator=(const Scrollpad &base) Scrollpad & Scrollpad::operator=(const Scrollpad &base)

View File

@@ -37,7 +37,7 @@ class Scrollpad: public Window
virtual void SetBorder(BORDER); virtual void SetBorder(BORDER);
virtual void SetTitle(string); virtual void SetTitle(string);
virtual void Clear(); virtual void Clear();
Scrollpad EmptyClone(); virtual Window * EmptyClone();
Scrollpad & operator=(const Scrollpad &); Scrollpad & operator=(const Scrollpad &);
protected: protected:
void print_content(); void print_content();

View File

@@ -51,6 +51,7 @@ void DefaultKeys(ncmpcpp_keys &keys)
keys.SeekForward[0] = 'f'; keys.SeekForward[0] = 'f';
keys.SeekBackward[0] = 'b'; keys.SeekBackward[0] = 'b';
keys.ToggleRepeat[0] = 'r'; keys.ToggleRepeat[0] = 'r';
keys.ToggleRepeatOne[0] = 'R';
keys.ToggleRandom[0] = 'z'; keys.ToggleRandom[0] = 'z';
keys.Shuffle[0] = 'Z'; keys.Shuffle[0] = 'Z';
keys.ToggleCrossfade[0] = 'x'; keys.ToggleCrossfade[0] = 'x';
@@ -98,6 +99,7 @@ void DefaultKeys(ncmpcpp_keys &keys)
keys.SeekForward[1] = null_key; keys.SeekForward[1] = null_key;
keys.SeekBackward[1] = null_key; keys.SeekBackward[1] = null_key;
keys.ToggleRepeat[1] = null_key; keys.ToggleRepeat[1] = null_key;
keys.ToggleRepeatOne[1] = null_key;
keys.ToggleRandom[1] = null_key; keys.ToggleRandom[1] = null_key;
keys.Shuffle[1] = null_key; keys.Shuffle[1] = null_key;
keys.ToggleCrossfade[1] = null_key; keys.ToggleCrossfade[1] = null_key;
@@ -144,6 +146,7 @@ void DefaultConfiguration(ncmpcpp_config &conf)
conf.header_visibility = true; conf.header_visibility = true;
conf.statusbar_visibility = true; conf.statusbar_visibility = true;
conf.autocenter_mode = false; conf.autocenter_mode = false;
conf.repeat_one_mode = false;
conf.set_window_title = true; conf.set_window_title = true;
conf.mpd_connection_timeout = 15; conf.mpd_connection_timeout = 15;
conf.crossfade_time = 5; conf.crossfade_time = 5;
@@ -307,6 +310,8 @@ void ReadKeys(ncmpcpp_keys &keys)
GetKeys(*it, keys.SeekBackward); GetKeys(*it, keys.SeekBackward);
else if (it->find("key_toggle_repeat ") != string::npos) else if (it->find("key_toggle_repeat ") != string::npos)
GetKeys(*it, keys.ToggleRepeat); GetKeys(*it, keys.ToggleRepeat);
else if (it->find("key_toggle_repeat_one ") != string::npos)
GetKeys(*it, keys.ToggleRepeatOne);
else if (it->find("key_toggle_random ") != string::npos) else if (it->find("key_toggle_random ") != string::npos)
GetKeys(*it, keys.ToggleRandom); GetKeys(*it, keys.ToggleRandom);
else if (it->find("key_shuffle ") != string::npos) else if (it->find("key_shuffle ") != string::npos)
@@ -423,6 +428,9 @@ void ReadConfiguration(ncmpcpp_config &conf)
if (it->find("autocenter_mode") != string::npos) if (it->find("autocenter_mode") != string::npos)
conf.autocenter_mode = v == "yes"; conf.autocenter_mode = v == "yes";
if (it->find("repeat_one_mode") != string::npos)
conf.repeat_one_mode = v == "yes";
if (it->find("enable_window_title") != string::npos) if (it->find("enable_window_title") != string::npos)
conf.set_window_title = v == "yes"; conf.set_window_title = v == "yes";

View File

@@ -53,6 +53,7 @@ struct ncmpcpp_keys
int SeekForward[2]; int SeekForward[2];
int SeekBackward[2]; int SeekBackward[2];
int ToggleRepeat[2]; int ToggleRepeat[2];
int ToggleRepeatOne[2];
int ToggleRandom[2]; int ToggleRandom[2];
int Shuffle[2]; int Shuffle[2];
int ToggleCrossfade[2]; int ToggleCrossfade[2];
@@ -102,6 +103,7 @@ struct ncmpcpp_config
bool header_visibility; bool header_visibility;
bool statusbar_visibility; bool statusbar_visibility;
bool autocenter_mode; bool autocenter_mode;
bool repeat_one_mode;
int mpd_connection_timeout; int mpd_connection_timeout;
int crossfade_time; int crossfade_time;

View File

@@ -75,6 +75,8 @@ extern bool block_library_update;
extern bool redraw_me; extern bool redraw_me;
bool repeat_one_allowed = 0;
long long playlist_old_id = -1; long long playlist_old_id = -1;
int old_playing; int old_playing;
@@ -325,11 +327,17 @@ void NcmpcppStatusChanged(MPDConnection *Mpd, MPDStatusChanges changed, void *da
{ {
if (!mPlaylist->Empty()) if (!mPlaylist->Empty())
{ {
if (Config.repeat_one_mode && repeat_one_allowed && old_playing+1 == now_playing)
{
std::swap<int>(now_playing,old_playing);
Mpd->Play(now_playing);
}
if (old_playing >= 0) if (old_playing >= 0)
mPlaylist->BoldOption(old_playing+1, 0); mPlaylist->BoldOption(old_playing+1, 0);
mPlaylist->BoldOption(now_playing+1, 1); mPlaylist->BoldOption(now_playing+1, 1);
if (Config.autocenter_mode) if (Config.autocenter_mode)
mPlaylist->Highlight(now_playing+1); mPlaylist->Highlight(now_playing+1);
repeat_one_allowed = 0;
} }
if (!Mpd->GetElapsedTime()) if (!Mpd->GetElapsedTime())
mvwhline(wFooter->RawWin(), 0, 0, 0, wFooter->GetWidth()); mvwhline(wFooter->RawWin(), 0, 0, 0, wFooter->GetWidth());
@@ -348,6 +356,10 @@ void NcmpcppStatusChanged(MPDConnection *Mpd, MPDStatusChanges changed, void *da
int elapsed = Mpd->GetElapsedTime(); int elapsed = Mpd->GetElapsedTime();
// 'repeat one' mode check - be sure that we deal with item with known length
if (Mpd->GetCurrentSong().GetTotalLength() && elapsed == Mpd->GetCurrentSong().GetTotalLength())
repeat_one_allowed = 1;
if (!block_statusbar_update && Config.statusbar_visibility) if (!block_statusbar_update && Config.statusbar_visibility)
{ {
string tracklength; string tracklength;

View File

@@ -586,6 +586,11 @@ void EnableColors()
} }
} }
Window * Window::EmptyClone()
{
return new Window(GetStartX(),GetStartY(),GetWidth(),GetHeight(),itsTitle,itsBaseColor,itsBorder);
}
char * ToString(const wchar_t *ws) char * ToString(const wchar_t *ws)
{ {
string s; string s;

View File

@@ -106,6 +106,8 @@ class Window
virtual COLOR GetColor() const; virtual COLOR GetColor() const;
virtual BORDER GetBorder() const; virtual BORDER GetBorder() const;
virtual Window * EmptyClone();
virtual void Go(WHERE) { } // for Menu and Scrollpad class virtual void Go(WHERE) { } // for Menu and Scrollpad class
virtual int GetChoice() const { return -1; } // for Menu class virtual int GetChoice() const { return -1; } // for Menu class
virtual void Add(string str) { Write(str); } // for Scrollpad class virtual void Add(string str) { Write(str); } // for Scrollpad class