rewrite communication system with mpd
This commit is contained in:
170
src/actions.cpp
170
src/actions.cpp
@@ -255,11 +255,20 @@ void setWindowsDimensions()
|
|||||||
|
|
||||||
bool connectToMPD()
|
bool connectToMPD()
|
||||||
{
|
{
|
||||||
if (!Mpd.Connect())
|
try
|
||||||
|
{
|
||||||
|
Mpd.Connect();
|
||||||
|
if (Mpd.Version() < 16)
|
||||||
|
{
|
||||||
|
std::cout << "MPD < 0.16.0 is not supported, please upgrade\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (std::exception &e)
|
||||||
{
|
{
|
||||||
std::cout << "Couldn't connect to MPD ";
|
std::cout << "Couldn't connect to MPD ";
|
||||||
std::cout << "(host = " << Mpd.GetHostname() << ", port = " << Mpd.GetPort() << ")";
|
std::cout << "(host = " << Mpd.GetHostname() << ", port = " << Mpd.GetPort() << ")";
|
||||||
std::cout << ": " << Mpd.GetErrorMessage() << std::endl;
|
std::cout << ": " << e.what() << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -341,13 +350,13 @@ void MouseEvent::run()
|
|||||||
&& m_mouse_event.y == LINES-(Config.statusbar_visibility ? 2 : 1)
|
&& m_mouse_event.y == LINES-(Config.statusbar_visibility ? 2 : 1)
|
||||||
) // progressbar
|
) // progressbar
|
||||||
{
|
{
|
||||||
if (!Mpd.isPlaying())
|
if (MpdStatus.playerState() == MPD::psStop)
|
||||||
return;
|
return;
|
||||||
Mpd.Seek(Mpd.GetTotalTime()*m_mouse_event.x/double(COLS));
|
Mpd.Seek(MpdStatus.totalTime()*m_mouse_event.x/double(COLS));
|
||||||
}
|
}
|
||||||
else if (m_mouse_event.bstate & BUTTON1_PRESSED
|
else if (m_mouse_event.bstate & BUTTON1_PRESSED
|
||||||
&& (Config.statusbar_visibility || Config.new_design)
|
&& (Config.statusbar_visibility || Config.new_design)
|
||||||
&& Mpd.isPlaying()
|
&& MpdStatus.playerState() != MPD::psStop
|
||||||
&& m_mouse_event.y == (Config.new_design ? 1 : LINES-1) && m_mouse_event.x < 9
|
&& m_mouse_event.y == (Config.new_design ? 1 : LINES-1) && m_mouse_event.x < 9
|
||||||
) // playing/paused
|
) // playing/paused
|
||||||
{
|
{
|
||||||
@@ -359,9 +368,9 @@ void MouseEvent::run()
|
|||||||
) // volume
|
) // volume
|
||||||
{
|
{
|
||||||
if (m_mouse_event.bstate & BUTTON2_PRESSED)
|
if (m_mouse_event.bstate & BUTTON2_PRESSED)
|
||||||
Mpd.SetVolume(Mpd.GetVolume()-2);
|
Mpd.SetVolume(MpdStatus.volume()-2);
|
||||||
else
|
else
|
||||||
Mpd.SetVolume(Mpd.GetVolume()+2);
|
Mpd.SetVolume(MpdStatus.volume()+2);
|
||||||
}
|
}
|
||||||
else if (m_mouse_event.bstate & (BUTTON1_PRESSED | BUTTON2_PRESSED | BUTTON3_PRESSED | BUTTON4_PRESSED))
|
else if (m_mouse_event.bstate & (BUTTON1_PRESSED | BUTTON2_PRESSED | BUTTON3_PRESSED | BUTTON4_PRESSED))
|
||||||
myScreen->mouseButtonPressed(m_mouse_event);
|
myScreen->mouseButtonPressed(m_mouse_event);
|
||||||
@@ -503,8 +512,8 @@ void ToggleInterface::run()
|
|||||||
Progressbar::unlock();
|
Progressbar::unlock();
|
||||||
Statusbar::unlock();
|
Statusbar::unlock();
|
||||||
resizeScreen(false);
|
resizeScreen(false);
|
||||||
if (!Mpd.isPlaying())
|
Status::Changes::mixer();
|
||||||
Status::Changes::mixer();
|
Status::Changes::elapsedTime();
|
||||||
Statusbar::msg("User interface: %s", Config.new_design ? "Alternative" : "Classic");
|
Statusbar::msg("User interface: %s", Config.new_design ? "Alternative" : "Classic");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -615,13 +624,13 @@ void SlaveScreen::run()
|
|||||||
|
|
||||||
void VolumeUp::run()
|
void VolumeUp::run()
|
||||||
{
|
{
|
||||||
int volume = std::min(Mpd.GetVolume()+Config.volume_change_step, 100);
|
int volume = std::min(MpdStatus.volume()+Config.volume_change_step, 100);
|
||||||
Mpd.SetVolume(volume);
|
Mpd.SetVolume(volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VolumeDown::run()
|
void VolumeDown::run()
|
||||||
{
|
{
|
||||||
int volume = std::max(Mpd.GetVolume()-Config.volume_change_step, 0);
|
int volume = std::max(MpdStatus.volume()-Config.volume_change_step, 0);
|
||||||
Mpd.SetVolume(volume);
|
Mpd.SetVolume(volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -637,16 +646,16 @@ void DeletePlaylistItems::run()
|
|||||||
{
|
{
|
||||||
Statusbar::msg("Deleting items...");
|
Statusbar::msg("Deleting items...");
|
||||||
auto delete_fun = std::bind(&MPD::Connection::Delete, _1, _2);
|
auto delete_fun = std::bind(&MPD::Connection::Delete, _1, _2);
|
||||||
if (deleteSelectedSongs(myPlaylist->main(), delete_fun))
|
deleteSelectedSongs(myPlaylist->main(), delete_fun);
|
||||||
Statusbar::msg("Item(s) deleted");
|
Statusbar::msg("Item(s) deleted");
|
||||||
}
|
}
|
||||||
else if (myScreen->isActiveWindow(myPlaylistEditor->Content))
|
else if (myScreen->isActiveWindow(myPlaylistEditor->Content))
|
||||||
{
|
{
|
||||||
std::string playlist = myPlaylistEditor->Playlists.current().value();
|
std::string playlist = myPlaylistEditor->Playlists.current().value();
|
||||||
auto delete_fun = std::bind(&MPD::Connection::PlaylistDelete, _1, playlist, _2);
|
auto delete_fun = std::bind(&MPD::Connection::PlaylistDelete, _1, playlist, _2);
|
||||||
Statusbar::msg("Deleting items...");
|
Statusbar::msg("Deleting items...");
|
||||||
if (deleteSelectedSongs(myPlaylistEditor->Content, delete_fun))
|
deleteSelectedSongs(myPlaylistEditor->Content, delete_fun);
|
||||||
Statusbar::msg("Item(s) deleted");
|
Statusbar::msg("Item(s) deleted");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -730,8 +739,8 @@ void DeleteStoredPlaylist::run()
|
|||||||
Mpd.StartCommandsList();
|
Mpd.StartCommandsList();
|
||||||
for (auto it = list.begin(); it != list.end(); ++it)
|
for (auto it = list.begin(); it != list.end(); ++it)
|
||||||
Mpd.DeletePlaylist((*it)->value());
|
Mpd.DeletePlaylist((*it)->value());
|
||||||
if (Mpd.CommitCommandsList())
|
Mpd.CommitCommandsList();
|
||||||
Statusbar::msg("Playlist%s deleted", list.size() == 1 ? "" : "s");
|
Statusbar::msg("Playlist%s deleted", list.size() == 1 ? "" : "s");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Statusbar::msg("Aborted");
|
Statusbar::msg("Aborted");
|
||||||
@@ -739,7 +748,7 @@ void DeleteStoredPlaylist::run()
|
|||||||
|
|
||||||
void ReplaySong::run()
|
void ReplaySong::run()
|
||||||
{
|
{
|
||||||
if (Mpd.isPlaying())
|
if (MpdStatus.playerState() != MPD::psStop)
|
||||||
Mpd.Seek(0);
|
Mpd.Seek(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -779,29 +788,33 @@ void SavePlaylist::run()
|
|||||||
for (size_t i = 0; i < myPlaylist->main().size(); ++i)
|
for (size_t i = 0; i < myPlaylist->main().size(); ++i)
|
||||||
Mpd.AddToPlaylist(playlist_name, myPlaylist->main()[i].value());
|
Mpd.AddToPlaylist(playlist_name, myPlaylist->main()[i].value());
|
||||||
Mpd.CommitCommandsList();
|
Mpd.CommitCommandsList();
|
||||||
if (Mpd.GetErrorMessage().empty())
|
Statusbar::msg("Filtered items added to playlist \"%s\"", playlist_name.c_str());
|
||||||
Statusbar::msg("Filtered items added to playlist \"%s\"", playlist_name.c_str());
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int result = Mpd.SavePlaylist(playlist_name);
|
try
|
||||||
if (result == MPD_ERROR_SUCCESS)
|
|
||||||
{
|
{
|
||||||
|
Mpd.SavePlaylist(playlist_name);
|
||||||
Statusbar::msg("Playlist saved as \"%s\"", playlist_name.c_str());
|
Statusbar::msg("Playlist saved as \"%s\"", playlist_name.c_str());
|
||||||
}
|
}
|
||||||
else if (result == MPD_SERVER_ERROR_EXIST)
|
catch (MPD::ServerError &e)
|
||||||
{
|
{
|
||||||
bool yes = askYesNoQuestion("Playlist \"" + playlist_name + "\" already exists, overwrite?", Status::trace);
|
if (e.code() == MPD_SERVER_ERROR_EXIST)
|
||||||
if (yes)
|
|
||||||
{
|
{
|
||||||
Mpd.DeletePlaylist(playlist_name);
|
bool yes = askYesNoQuestion("Playlist \"" + playlist_name + "\" already exists, overwrite?", Status::trace);
|
||||||
if (Mpd.SavePlaylist(playlist_name) == MPD_ERROR_SUCCESS)
|
if (yes)
|
||||||
|
{
|
||||||
|
Mpd.DeletePlaylist(playlist_name);
|
||||||
|
Mpd.SavePlaylist(playlist_name);
|
||||||
Statusbar::msg("Playlist overwritten");
|
Statusbar::msg("Playlist overwritten");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Statusbar::msg("Aborted");
|
||||||
|
if (myScreen == myPlaylist)
|
||||||
|
myPlaylist->EnableHighlighting();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Statusbar::msg("Aborted");
|
throw e;
|
||||||
if (myScreen == myPlaylist)
|
|
||||||
myPlaylist->EnableHighlighting();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -964,7 +977,7 @@ void Add::run()
|
|||||||
|
|
||||||
bool SeekForward::canBeRun() const
|
bool SeekForward::canBeRun() const
|
||||||
{
|
{
|
||||||
return Mpd.isPlaying() && Mpd.GetTotalTime() > 0;
|
return MpdStatus.playerState() != MPD::psStop && MpdStatus.totalTime() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SeekForward::run()
|
void SeekForward::run()
|
||||||
@@ -974,7 +987,7 @@ void SeekForward::run()
|
|||||||
|
|
||||||
bool SeekBackward::canBeRun() const
|
bool SeekBackward::canBeRun() const
|
||||||
{
|
{
|
||||||
return Mpd.isPlaying() && Mpd.GetTotalTime() > 0;
|
return MpdStatus.playerState() != MPD::psStop && MpdStatus.totalTime() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SeekBackward::run()
|
void SeekBackward::run()
|
||||||
@@ -1079,8 +1092,10 @@ void TogglePlayingSongCentering::run()
|
|||||||
{
|
{
|
||||||
Config.autocenter_mode = !Config.autocenter_mode;
|
Config.autocenter_mode = !Config.autocenter_mode;
|
||||||
Statusbar::msg("Centering playing song: %s", Config.autocenter_mode ? "On" : "Off");
|
Statusbar::msg("Centering playing song: %s", Config.autocenter_mode ? "On" : "Off");
|
||||||
if (Config.autocenter_mode && Mpd.isPlaying() && !myPlaylist->main().isFiltered())
|
if (Config.autocenter_mode
|
||||||
myPlaylist->main().highlight(Mpd.GetCurrentSongPos());
|
&& MpdStatus.playerState() != MPD::psStop
|
||||||
|
&& !myPlaylist->main().isFiltered())
|
||||||
|
myPlaylist->main().highlight(MpdStatus.currentSongPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateDatabase::run()
|
void UpdateDatabase::run()
|
||||||
@@ -1100,13 +1115,13 @@ bool JumpToPlayingSong::canBeRun() const
|
|||||||
return ((myScreen == myPlaylist && !myPlaylist->isFiltered())
|
return ((myScreen == myPlaylist && !myPlaylist->isFiltered())
|
||||||
|| myScreen == myBrowser
|
|| myScreen == myBrowser
|
||||||
|| myScreen == myLibrary)
|
|| myScreen == myLibrary)
|
||||||
&& Mpd.isPlaying();
|
&& MpdStatus.playerState() != MPD::psStop;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JumpToPlayingSong::run()
|
void JumpToPlayingSong::run()
|
||||||
{
|
{
|
||||||
if (myScreen == myPlaylist)
|
if (myScreen == myPlaylist)
|
||||||
myPlaylist->main().highlight(Mpd.GetCurrentSongPos());
|
myPlaylist->main().highlight(MpdStatus.currentSongPosition());
|
||||||
else if (myScreen == myBrowser)
|
else if (myScreen == myBrowser)
|
||||||
{
|
{
|
||||||
myBrowser->LocateSong(myPlaylist->nowPlayingSong());
|
myBrowser->LocateSong(myPlaylist->nowPlayingSong());
|
||||||
@@ -1120,7 +1135,7 @@ void JumpToPlayingSong::run()
|
|||||||
|
|
||||||
void ToggleRepeat::run()
|
void ToggleRepeat::run()
|
||||||
{
|
{
|
||||||
Mpd.SetRepeat(!Mpd.GetRepeat());
|
Mpd.SetRepeat(!MpdStatus.repeat());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shuffle::run()
|
void Shuffle::run()
|
||||||
@@ -1130,7 +1145,7 @@ void Shuffle::run()
|
|||||||
|
|
||||||
void ToggleRandom::run()
|
void ToggleRandom::run()
|
||||||
{
|
{
|
||||||
Mpd.SetRandom(!Mpd.GetRandom());
|
Mpd.SetRandom(!MpdStatus.random());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StartSearching::canBeRun() const
|
bool StartSearching::canBeRun() const
|
||||||
@@ -1175,17 +1190,17 @@ void SaveTagChanges::run()
|
|||||||
|
|
||||||
void ToggleSingle::run()
|
void ToggleSingle::run()
|
||||||
{
|
{
|
||||||
Mpd.SetSingle(!Mpd.GetSingle());
|
Mpd.SetSingle(!MpdStatus.single());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToggleConsume::run()
|
void ToggleConsume::run()
|
||||||
{
|
{
|
||||||
Mpd.SetConsume(!Mpd.GetConsume());
|
Mpd.SetConsume(!MpdStatus.consume());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToggleCrossfade::run()
|
void ToggleCrossfade::run()
|
||||||
{
|
{
|
||||||
Mpd.SetCrossfade(Mpd.GetCrossfade() ? 0 : Config.crossfade_time);
|
Mpd.SetCrossfade(MpdStatus.crossfade() ? 0 : Config.crossfade_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetCrossfade::run()
|
void SetCrossfade::run()
|
||||||
@@ -1215,8 +1230,8 @@ void SetVolume::run()
|
|||||||
int volume = boost::lexical_cast<int>(strvolume);
|
int volume = boost::lexical_cast<int>(strvolume);
|
||||||
if (volume >= 0 && volume <= 100)
|
if (volume >= 0 && volume <= 100)
|
||||||
{
|
{
|
||||||
if (Mpd.SetVolume(volume))
|
Mpd.SetVolume(volume);
|
||||||
Statusbar::msg("Volume set to %d%%", volume);
|
Statusbar::msg("Volume set to %d%%", volume);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1451,13 +1466,11 @@ void EditPlaylistName::run()
|
|||||||
Statusbar::unlock();
|
Statusbar::unlock();
|
||||||
if (!new_name.empty() && new_name != old_name)
|
if (!new_name.empty() && new_name != old_name)
|
||||||
{
|
{
|
||||||
if (Mpd.Rename(old_name, new_name))
|
Mpd.Rename(old_name, new_name);
|
||||||
{
|
const char msg[] = "Playlist renamed to \"%ls\"";
|
||||||
const char msg[] = "Playlist renamed to \"%ls\"";
|
Statusbar::msg(msg, wideShorten(ToWString(new_name), COLS-const_strlen(msg)).c_str());
|
||||||
Statusbar::msg(msg, wideShorten(ToWString(new_name), COLS-const_strlen(msg)).c_str());
|
if (!myBrowser->isLocal())
|
||||||
if (!myBrowser->isLocal())
|
myBrowser->GetDirectory("/");
|
||||||
myBrowser->GetDirectory("/");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1562,7 +1575,7 @@ void JumpToTagEditor::run()
|
|||||||
|
|
||||||
bool JumpToPositionInSong::canBeRun() const
|
bool JumpToPositionInSong::canBeRun() const
|
||||||
{
|
{
|
||||||
return Mpd.isPlaying() && Mpd.GetTotalTime() > 0;
|
return MpdStatus.playerState() != MPD::psStop && MpdStatus.totalTime() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JumpToPositionInSong::run()
|
void JumpToPositionInSong::run()
|
||||||
@@ -1579,12 +1592,12 @@ void JumpToPositionInSong::run()
|
|||||||
if (position.empty())
|
if (position.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int newpos = 0;
|
unsigned newpos = 0;
|
||||||
if (position.find(':') != std::string::npos) // probably time in mm:ss
|
if (position.find(':') != std::string::npos) // probably time in mm:ss
|
||||||
{
|
{
|
||||||
newpos = boost::lexical_cast<int>(position)*60
|
newpos = boost::lexical_cast<int>(position)*60
|
||||||
+ boost::lexical_cast<int>(position.substr(position.find(':')+1));
|
+ boost::lexical_cast<int>(position.substr(position.find(':')+1));
|
||||||
if (newpos >= 0 && newpos <= Mpd.GetTotalTime())
|
if (newpos <= MpdStatus.totalTime())
|
||||||
Mpd.Seek(newpos);
|
Mpd.Seek(newpos);
|
||||||
else
|
else
|
||||||
Statusbar::msg("Out of bounds, 0:00-%s possible for mm:ss, %s given", s.getLength().c_str(), MPD::Song::ShowTime(newpos).c_str());
|
Statusbar::msg("Out of bounds, 0:00-%s possible for mm:ss, %s given", s.getLength().c_str(), MPD::Song::ShowTime(newpos).c_str());
|
||||||
@@ -1592,7 +1605,7 @@ void JumpToPositionInSong::run()
|
|||||||
else if (position.find('s') != std::string::npos) // probably position in seconds
|
else if (position.find('s') != std::string::npos) // probably position in seconds
|
||||||
{
|
{
|
||||||
newpos = boost::lexical_cast<int>(position);
|
newpos = boost::lexical_cast<int>(position);
|
||||||
if (newpos >= 0 && newpos <= Mpd.GetTotalTime())
|
if (newpos <= MpdStatus.totalTime())
|
||||||
Mpd.Seek(newpos);
|
Mpd.Seek(newpos);
|
||||||
else
|
else
|
||||||
Statusbar::msg("Out of bounds, 0-%d possible for seconds, %d given", s.getDuration(), newpos);
|
Statusbar::msg("Out of bounds, 0-%d possible for seconds, %d given", s.getDuration(), newpos);
|
||||||
@@ -1600,8 +1613,8 @@ void JumpToPositionInSong::run()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
newpos = boost::lexical_cast<int>(position);
|
newpos = boost::lexical_cast<int>(position);
|
||||||
if (newpos >= 0 && newpos <= 100)
|
if (newpos <= 100)
|
||||||
Mpd.Seek(Mpd.GetTotalTime()*newpos/100.0);
|
Mpd.Seek(MpdStatus.totalTime()*newpos/100.0);
|
||||||
else
|
else
|
||||||
Statusbar::msg("Out of bounds, 0-100 possible for %%, %d given", newpos);
|
Statusbar::msg("Out of bounds, 0-100 possible for %%, %d given", newpos);
|
||||||
}
|
}
|
||||||
@@ -1689,8 +1702,8 @@ void CropMainPlaylist::run()
|
|||||||
if (yes)
|
if (yes)
|
||||||
{
|
{
|
||||||
Statusbar::msg("Cropping playlist...");
|
Statusbar::msg("Cropping playlist...");
|
||||||
if (cropPlaylist(myPlaylist->main(), std::bind(&MPD::Connection::Delete, _1, _2)))
|
cropPlaylist(myPlaylist->main(), std::bind(&MPD::Connection::Delete, _1, _2));
|
||||||
Statusbar::msg("Cropping playlist...");
|
Statusbar::msg("Cropping playlist...");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1710,8 +1723,8 @@ void CropPlaylist::run()
|
|||||||
{
|
{
|
||||||
auto delete_fun = std::bind(&MPD::Connection::PlaylistDelete, _1, playlist, _2);
|
auto delete_fun = std::bind(&MPD::Connection::PlaylistDelete, _1, playlist, _2);
|
||||||
Statusbar::msg("Cropping playlist \"%s\"...", playlist.c_str());
|
Statusbar::msg("Cropping playlist \"%s\"...", playlist.c_str());
|
||||||
if (cropPlaylist(myPlaylistEditor->Content, delete_fun))
|
cropPlaylist(myPlaylistEditor->Content, delete_fun);
|
||||||
Statusbar::msg("Playlist \"%s\" cropped", playlist.c_str());
|
Statusbar::msg("Playlist \"%s\" cropped", playlist.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1725,8 +1738,8 @@ void ClearMainPlaylist::run()
|
|||||||
auto delete_fun = std::bind(&MPD::Connection::Delete, _1, _2);
|
auto delete_fun = std::bind(&MPD::Connection::Delete, _1, _2);
|
||||||
auto clear_fun = std::bind(&MPD::Connection::ClearMainPlaylist, _1);
|
auto clear_fun = std::bind(&MPD::Connection::ClearMainPlaylist, _1);
|
||||||
Statusbar::msg("Deleting items...");
|
Statusbar::msg("Deleting items...");
|
||||||
if (clearPlaylist(myPlaylist->main(), delete_fun, clear_fun))
|
clearPlaylist(myPlaylist->main(), delete_fun, clear_fun);
|
||||||
Statusbar::msg("Items deleted");
|
Statusbar::msg("Items deleted");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1747,8 +1760,8 @@ void ClearPlaylist::run()
|
|||||||
auto delete_fun = std::bind(&MPD::Connection::PlaylistDelete, _1, playlist, _2);
|
auto delete_fun = std::bind(&MPD::Connection::PlaylistDelete, _1, playlist, _2);
|
||||||
auto clear_fun = std::bind(&MPD::Connection::ClearPlaylist, _1, playlist);
|
auto clear_fun = std::bind(&MPD::Connection::ClearPlaylist, _1, playlist);
|
||||||
Statusbar::msg("Deleting items from \"%s\"...", playlist.c_str());
|
Statusbar::msg("Deleting items from \"%s\"...", playlist.c_str());
|
||||||
if (clearPlaylist(myPlaylistEditor->Content, delete_fun, clear_fun))
|
clearPlaylist(myPlaylistEditor->Content, delete_fun, clear_fun);
|
||||||
Statusbar::msg("Items deleted from \"%s\"", playlist.c_str());
|
Statusbar::msg("Items deleted from \"%s\"", playlist.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2578,7 +2591,7 @@ void seek()
|
|||||||
using Global::Timer;
|
using Global::Timer;
|
||||||
using Global::SeekingInProgress;
|
using Global::SeekingInProgress;
|
||||||
|
|
||||||
if (!Mpd.GetTotalTime())
|
if (!MpdStatus.totalTime())
|
||||||
{
|
{
|
||||||
Statusbar::msg("Unknown item length");
|
Statusbar::msg("Unknown item length");
|
||||||
return;
|
return;
|
||||||
@@ -2587,7 +2600,7 @@ void seek()
|
|||||||
Progressbar::lock();
|
Progressbar::lock();
|
||||||
Statusbar::lock();
|
Statusbar::lock();
|
||||||
|
|
||||||
int songpos = Mpd.GetElapsedTime();
|
unsigned songpos = MpdStatus.elapsedTime();
|
||||||
timeval t = Timer;
|
timeval t = Timer;
|
||||||
|
|
||||||
int old_timeout = wFooter->getTimeout();
|
int old_timeout = wFooter->getTimeout();
|
||||||
@@ -2602,7 +2615,7 @@ void seek()
|
|||||||
Status::trace();
|
Status::trace();
|
||||||
myPlaylist->UpdateTimer();
|
myPlaylist->UpdateTimer();
|
||||||
|
|
||||||
int howmuch = Config.incremental_seeking ? (Timer.tv_sec-t.tv_sec)/2+Config.seek_time : Config.seek_time;
|
unsigned howmuch = Config.incremental_seeking ? (Timer.tv_sec-t.tv_sec)/2+Config.seek_time : Config.seek_time;
|
||||||
|
|
||||||
Key input = Key::read(*wFooter);
|
Key input = Key::read(*wFooter);
|
||||||
auto k = Bindings.get(input);
|
auto k = Bindings.get(input);
|
||||||
@@ -2611,20 +2624,17 @@ void seek()
|
|||||||
auto a = k.first->action();
|
auto a = k.first->action();
|
||||||
if (a == seekForward)
|
if (a == seekForward)
|
||||||
{
|
{
|
||||||
if (songpos < Mpd.GetTotalTime())
|
if (songpos < MpdStatus.totalTime())
|
||||||
{
|
songpos = std::min(songpos + howmuch, MpdStatus.totalTime());
|
||||||
songpos += howmuch;
|
|
||||||
if (songpos > Mpd.GetTotalTime())
|
|
||||||
songpos = Mpd.GetTotalTime();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (a == seekBackward)
|
else if (a == seekBackward)
|
||||||
{
|
{
|
||||||
if (songpos > 0)
|
if (songpos > 0)
|
||||||
{
|
{
|
||||||
songpos -= howmuch;
|
if (songpos < howmuch)
|
||||||
if (songpos < 0)
|
|
||||||
songpos = 0;
|
songpos = 0;
|
||||||
|
else
|
||||||
|
songpos -= howmuch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -2637,12 +2647,12 @@ void seek()
|
|||||||
if (Config.display_remaining_time)
|
if (Config.display_remaining_time)
|
||||||
{
|
{
|
||||||
tracklength = "-";
|
tracklength = "-";
|
||||||
tracklength += MPD::Song::ShowTime(Mpd.GetTotalTime()-songpos);
|
tracklength += MPD::Song::ShowTime(MpdStatus.totalTime()-songpos);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
tracklength = MPD::Song::ShowTime(songpos);
|
tracklength = MPD::Song::ShowTime(songpos);
|
||||||
tracklength += "/";
|
tracklength += "/";
|
||||||
tracklength += MPD::Song::ShowTime(Mpd.GetTotalTime());
|
tracklength += MPD::Song::ShowTime(MpdStatus.totalTime());
|
||||||
*wHeader << NC::XY(0, 0) << tracklength << " ";
|
*wHeader << NC::XY(0, 0) << tracklength << " ";
|
||||||
wHeader->refresh();
|
wHeader->refresh();
|
||||||
}
|
}
|
||||||
@@ -2652,17 +2662,17 @@ void seek()
|
|||||||
if (Config.display_remaining_time)
|
if (Config.display_remaining_time)
|
||||||
{
|
{
|
||||||
tracklength += "-";
|
tracklength += "-";
|
||||||
tracklength += MPD::Song::ShowTime(Mpd.GetTotalTime()-songpos);
|
tracklength += MPD::Song::ShowTime(MpdStatus.totalTime()-songpos);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
tracklength += MPD::Song::ShowTime(songpos);
|
tracklength += MPD::Song::ShowTime(songpos);
|
||||||
tracklength += "/";
|
tracklength += "/";
|
||||||
tracklength += MPD::Song::ShowTime(Mpd.GetTotalTime());
|
tracklength += MPD::Song::ShowTime(MpdStatus.totalTime());
|
||||||
tracklength += "]";
|
tracklength += "]";
|
||||||
*wFooter << NC::XY(wFooter->getWidth()-tracklength.length(), 1) << tracklength;
|
*wFooter << NC::XY(wFooter->getWidth()-tracklength.length(), 1) << tracklength;
|
||||||
}
|
}
|
||||||
*wFooter << NC::Format::NoBold;
|
*wFooter << NC::Format::NoBold;
|
||||||
Progressbar::draw(songpos, Mpd.GetTotalTime());
|
Progressbar::draw(songpos, MpdStatus.totalTime());
|
||||||
wFooter->refresh();
|
wFooter->refresh();
|
||||||
}
|
}
|
||||||
SeekingInProgress = false;
|
SeekingInProgress = false;
|
||||||
|
|||||||
@@ -74,9 +74,6 @@ Browser::Browser() : itsBrowseLocally(0), itsScrollBeginning(0), itsBrowsedDir("
|
|||||||
w.setSelectedPrefix(Config.selected_item_prefix);
|
w.setSelectedPrefix(Config.selected_item_prefix);
|
||||||
w.setSelectedSuffix(Config.selected_item_suffix);
|
w.setSelectedSuffix(Config.selected_item_suffix);
|
||||||
w.setItemDisplayer(std::bind(Display::Items, _1, proxySongList()));
|
w.setItemDisplayer(std::bind(Display::Items, _1, proxySongList()));
|
||||||
|
|
||||||
if (SupportedExtensions.empty())
|
|
||||||
Mpd.GetSupportedExtensions(SupportedExtensions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Browser::resize()
|
void Browser::resize()
|
||||||
@@ -136,11 +133,9 @@ void Browser::enterPressed()
|
|||||||
}
|
}
|
||||||
case itPlaylist:
|
case itPlaylist:
|
||||||
{
|
{
|
||||||
if (Mpd.LoadPlaylist(item.name))
|
Mpd.LoadPlaylist(item.name);
|
||||||
{
|
Statusbar::msg("Playlist \"%s\" loaded", item.name.c_str());
|
||||||
Statusbar::msg("Playlist \"%s\" loaded", item.name.c_str());
|
myPlaylist->PlayNewlyAddedSongs();
|
||||||
myPlaylist->PlayNewlyAddedSongs();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -168,7 +163,6 @@ void Browser::spacePressed()
|
|||||||
{
|
{
|
||||||
case itDirectory:
|
case itDirectory:
|
||||||
{
|
{
|
||||||
bool result;
|
|
||||||
# ifndef WIN32
|
# ifndef WIN32
|
||||||
if (isLocal())
|
if (isLocal())
|
||||||
{
|
{
|
||||||
@@ -179,13 +173,12 @@ void Browser::spacePressed()
|
|||||||
list.reserve(items.size());
|
list.reserve(items.size());
|
||||||
for (MPD::ItemList::const_iterator it = items.begin(); it != items.end(); ++it)
|
for (MPD::ItemList::const_iterator it = items.begin(); it != items.end(); ++it)
|
||||||
list.push_back(*it->song);
|
list.push_back(*it->song);
|
||||||
result = addSongsToPlaylist(list, false, -1);
|
addSongsToPlaylist(list, false, -1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
# endif // !WIN32
|
# endif // !WIN32
|
||||||
result = Mpd.Add(item.name);
|
Mpd.Add(item.name);
|
||||||
if (result)
|
Statusbar::msg("Directory \"%s\" added", item.name.c_str());
|
||||||
Statusbar::msg("Directory \"%s\" added", item.name.c_str());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case itSong:
|
case itSong:
|
||||||
@@ -195,8 +188,8 @@ void Browser::spacePressed()
|
|||||||
}
|
}
|
||||||
case itPlaylist:
|
case itPlaylist:
|
||||||
{
|
{
|
||||||
if (Mpd.LoadPlaylist(item.name))
|
Mpd.LoadPlaylist(item.name);
|
||||||
Statusbar::msg("Playlist \"%s\" loaded", item.name.c_str());
|
Statusbar::msg("Playlist \"%s\" loaded", item.name.c_str());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -363,6 +356,12 @@ MPD::SongList Browser::getSelectedSongs()
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Browser::fetchSupportedExtensions()
|
||||||
|
{
|
||||||
|
SupportedExtensions.clear();
|
||||||
|
Mpd.GetSupportedExtensions(SupportedExtensions);
|
||||||
|
}
|
||||||
|
|
||||||
void Browser::LocateSong(const MPD::Song &s)
|
void Browser::LocateSong(const MPD::Song &s)
|
||||||
{
|
{
|
||||||
if (s.getDirectory().empty())
|
if (s.getDirectory().empty())
|
||||||
@@ -580,7 +579,7 @@ bool Browser::deleteItem(const MPD::Item &item)
|
|||||||
|
|
||||||
// playlist created by mpd
|
// playlist created by mpd
|
||||||
if (!isLocal() && item.type == itPlaylist && CurrentDir() == "/")
|
if (!isLocal() && item.type == itPlaylist && CurrentDir() == "/")
|
||||||
return Mpd.DeletePlaylist(item.name);
|
Mpd.DeletePlaylist(item.name);
|
||||||
|
|
||||||
std::string path;
|
std::string path;
|
||||||
if (!isLocal())
|
if (!isLocal())
|
||||||
|
|||||||
@@ -65,6 +65,8 @@ struct Browser: Screen<NC::Menu<MPD::Item>>, Filterable, HasSongs, Searchable, T
|
|||||||
// private members
|
// private members
|
||||||
const std::string &CurrentDir() { return itsBrowsedDir; }
|
const std::string &CurrentDir() { return itsBrowsedDir; }
|
||||||
|
|
||||||
|
void fetchSupportedExtensions();
|
||||||
|
|
||||||
bool isLocal() { return itsBrowseLocally; }
|
bool isLocal() { return itsBrowseLocally; }
|
||||||
void LocateSong(const MPD::Song &);
|
void LocateSong(const MPD::Song &);
|
||||||
void GetDirectory(std::string, std::string = "/");
|
void GetDirectory(std::string, std::string = "/");
|
||||||
|
|||||||
@@ -117,13 +117,11 @@ void ParseArgv(int argc, char **argv)
|
|||||||
<< " -s, --screen <name> specify the startup screen\n"
|
<< " -s, --screen <name> specify the startup screen\n"
|
||||||
<< " -?, --help show help message\n"
|
<< " -?, --help show help message\n"
|
||||||
<< " -v, --version display version information\n"
|
<< " -v, --version display version information\n"
|
||||||
<< " --now-playing display now playing song [" << now_playing_format << "]\n"
|
|
||||||
;
|
;
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Actions::connectToMPD())
|
Actions::connectToMPD();
|
||||||
exit(1);
|
|
||||||
|
|
||||||
if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "--screen"))
|
if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "--screen"))
|
||||||
{
|
{
|
||||||
@@ -164,34 +162,6 @@ void ParseArgv(int argc, char **argv)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!strcmp(argv[i], "--now-playing"))
|
|
||||||
{
|
|
||||||
Mpd.UpdateStatus();
|
|
||||||
if (!Mpd.GetErrorMessage().empty())
|
|
||||||
{
|
|
||||||
std::cerr << "MPD error: " << Mpd.GetErrorMessage() << std::endl;
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if (Mpd.isPlaying())
|
|
||||||
{
|
|
||||||
if (argc > ++i)
|
|
||||||
{
|
|
||||||
if (MPD::Song::isFormatOk("now-playing format", argv[i]))
|
|
||||||
{
|
|
||||||
// apply additional pair of braces
|
|
||||||
now_playing_format = "{";
|
|
||||||
now_playing_format += argv[i];
|
|
||||||
now_playing_format += "}";
|
|
||||||
boost::replace_all(now_playing_format, "\\n", "\n");
|
|
||||||
boost::replace_all(now_playing_format, "\\t", "\t");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::string np = Mpd.GetCurrentlyPlayingSong().toString(
|
|
||||||
now_playing_format, Config.tags_separator);
|
|
||||||
std::cout << Charset::utf8ToLocale(np) << "\n";
|
|
||||||
}
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
else if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "--config"))
|
else if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "--config"))
|
||||||
{
|
{
|
||||||
// this is used in Configuration::CheckForCommandLineConfigFilePath, ignoring here.
|
// this is used in Configuration::CheckForCommandLineConfigFilePath, ignoring here.
|
||||||
@@ -202,10 +172,5 @@ void ParseArgv(int argc, char **argv)
|
|||||||
std::cerr << "Invalid option: " << argv[i] << std::endl;
|
std::cerr << "Invalid option: " << argv[i] << std::endl;
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (!Mpd.GetErrorMessage().empty())
|
|
||||||
{
|
|
||||||
std::cerr << "Error: " << Mpd.GetErrorMessage() << std::endl;
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,8 +97,8 @@ void setProperties(NC::Menu<T> &menu, const MPD::Song &s, const ProxySongList &p
|
|||||||
discard_colors = Config.discard_colors_if_item_is_selected && is_selected;
|
discard_colors = Config.discard_colors_if_item_is_selected && is_selected;
|
||||||
|
|
||||||
int song_pos = menu.isFiltered() ? s.getPosition() : drawn_pos;
|
int song_pos = menu.isFiltered() ? s.getPosition() : drawn_pos;
|
||||||
is_now_playing = Mpd.isPlaying() && myPlaylist->isActiveWindow(menu)
|
is_now_playing = MpdStatus.playerState() != MPD::psStop && myPlaylist->isActiveWindow(menu)
|
||||||
&& song_pos == Mpd.GetCurrentSongPos();
|
&& song_pos == MpdStatus.currentSongPosition();
|
||||||
if (is_now_playing)
|
if (is_now_playing)
|
||||||
menu << Config.now_playing_prefix;
|
menu << Config.now_playing_prefix;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,8 +24,6 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include "gcc.h"
|
#include "gcc.h"
|
||||||
|
|
||||||
#define Error(msg) std::cerr << "ncmpcpp: " << msg;
|
|
||||||
|
|
||||||
void FatalError(const std::string &msg) GNUC_NORETURN;
|
void FatalError(const std::string &msg) GNUC_NORETURN;
|
||||||
|
|
||||||
#endif // NCMPCPP_ERROR_H
|
#endif // NCMPCPP_ERROR_H
|
||||||
|
|||||||
@@ -49,9 +49,6 @@ extern size_t MainStartY;
|
|||||||
// height of main window
|
// height of main window
|
||||||
extern size_t MainHeight;
|
extern size_t MainHeight;
|
||||||
|
|
||||||
// indicates whether messages from Statusbar::msg function should be shown
|
|
||||||
extern bool ShowMessages;
|
|
||||||
|
|
||||||
// indicates whether seeking action in currently in progress
|
// indicates whether seeking action in currently in progress
|
||||||
extern bool SeekingInProgress;
|
extern bool SeekingInProgress;
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ bool addSongToPlaylist(const MPD::Song &s, bool play, size_t position)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
position = std::min(position, Mpd.GetPlaylistLength());
|
position = std::min(position, myPlaylist->main().size());
|
||||||
int id = Mpd.AddSong(s, position);
|
int id = Mpd.AddSong(s, position);
|
||||||
if (id >= 0)
|
if (id >= 0)
|
||||||
{
|
{
|
||||||
@@ -64,18 +64,18 @@ bool addSongToPlaylist(const MPD::Song &s, bool play, size_t position)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool addSongsToPlaylist(const MPD::SongList &list, bool play, size_t position)
|
void addSongsToPlaylist(const MPD::SongList &list, bool play, size_t position)
|
||||||
{
|
{
|
||||||
if (list.empty())
|
if (list.empty())
|
||||||
return false;
|
return;
|
||||||
position = std::min(position, Mpd.GetPlaylistLength());
|
position = std::min(position, myPlaylist->main().size());
|
||||||
Mpd.StartCommandsList();
|
Mpd.StartCommandsList();
|
||||||
for (auto s = list.rbegin(); s != list.rend(); ++s)
|
for (auto s = list.rbegin(); s != list.rend(); ++s)
|
||||||
if (Mpd.AddSong(*s, position) < 0)
|
if (Mpd.AddSong(*s, position) < 0)
|
||||||
break;
|
break;
|
||||||
if (play)
|
if (play)
|
||||||
Mpd.Play(position);
|
Mpd.Play(position);
|
||||||
return Mpd.CommitCommandsList();
|
Mpd.CommitCommandsList();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Timestamp(time_t t)
|
std::string Timestamp(time_t t)
|
||||||
|
|||||||
101
src/helpers.h
101
src/helpers.h
@@ -152,24 +152,22 @@ void moveSelectedItemsUp(NC::Menu<MPD::Song> &m, F swap_fun)
|
|||||||
Mpd.StartCommandsList();
|
Mpd.StartCommandsList();
|
||||||
for (auto it = list.begin(); it != list.end(); ++it)
|
for (auto it = list.begin(); it != list.end(); ++it)
|
||||||
swap_fun(Mpd, *it - begin, *it - begin - 1);
|
swap_fun(Mpd, *it - begin, *it - begin - 1);
|
||||||
if (Mpd.CommitCommandsList())
|
Mpd.CommitCommandsList();
|
||||||
|
if (list.size() > 1)
|
||||||
{
|
{
|
||||||
if (list.size() > 1)
|
for (auto it = list.begin(); it != list.end(); ++it)
|
||||||
{
|
{
|
||||||
for (auto it = list.begin(); it != list.end(); ++it)
|
(*it)->setSelected(false);
|
||||||
{
|
(*it-1)->setSelected(true);
|
||||||
(*it)->setSelected(false);
|
|
||||||
(*it-1)->setSelected(true);
|
|
||||||
}
|
|
||||||
m.highlight(list[(list.size())/2] - begin - 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// if we move only one item, do not select it. however, if single item
|
|
||||||
// was selected prior to move, it'll deselect it. oh well.
|
|
||||||
list[0]->setSelected(false);
|
|
||||||
m.scroll(NC::Scroll::Up);
|
|
||||||
}
|
}
|
||||||
|
m.highlight(list[(list.size())/2] - begin - 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// if we move only one item, do not select it. however, if single item
|
||||||
|
// was selected prior to move, it'll deselect it. oh well.
|
||||||
|
list[0]->setSelected(false);
|
||||||
|
m.scroll(NC::Scroll::Up);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -186,24 +184,22 @@ void moveSelectedItemsDown(NC::Menu<MPD::Song> &m, F swap_fun)
|
|||||||
Mpd.StartCommandsList();
|
Mpd.StartCommandsList();
|
||||||
for (auto it = list.begin(); it != list.end(); ++it)
|
for (auto it = list.begin(); it != list.end(); ++it)
|
||||||
swap_fun(Mpd, it->base() - begin, it->base() - begin + 1);
|
swap_fun(Mpd, it->base() - begin, it->base() - begin + 1);
|
||||||
if (Mpd.CommitCommandsList())
|
Mpd.CommitCommandsList();
|
||||||
|
if (list.size() > 1)
|
||||||
{
|
{
|
||||||
if (list.size() > 1)
|
for (auto it = list.begin(); it != list.end(); ++it)
|
||||||
{
|
{
|
||||||
for (auto it = list.begin(); it != list.end(); ++it)
|
(*it)->setSelected(false);
|
||||||
{
|
(*it-1)->setSelected(true);
|
||||||
(*it)->setSelected(false);
|
|
||||||
(*it-1)->setSelected(true);
|
|
||||||
}
|
|
||||||
m.highlight(list[(list.size())/2].base() - begin + 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// if we move only one item, do not select it. however, if single item
|
|
||||||
// was selected prior to move, it'll deselect it. oh well.
|
|
||||||
list[0]->setSelected(false);
|
|
||||||
m.scroll(NC::Scroll::Down);
|
|
||||||
}
|
}
|
||||||
|
m.highlight(list[(list.size())/2].base() - begin + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// if we move only one item, do not select it. however, if single item
|
||||||
|
// was selected prior to move, it'll deselect it. oh well.
|
||||||
|
list[0]->setSelected(false);
|
||||||
|
m.scroll(NC::Scroll::Down);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -236,14 +232,12 @@ void moveSelectedItemsTo(NC::Menu<MPD::Song> &m, F move_fun)
|
|||||||
size_t i = list.size()-1;
|
size_t i = list.size()-1;
|
||||||
for (auto it = list.rbegin(); it != list.rend(); ++it, --i)
|
for (auto it = list.rbegin(); it != list.rend(); ++it, --i)
|
||||||
move_fun(Mpd, *it - begin, pos+i);
|
move_fun(Mpd, *it - begin, pos+i);
|
||||||
if (Mpd.CommitCommandsList())
|
Mpd.CommitCommandsList();
|
||||||
|
i = list.size()-1;
|
||||||
|
for (auto it = list.rbegin(); it != list.rend(); ++it, --i)
|
||||||
{
|
{
|
||||||
i = list.size()-1;
|
(*it)->setSelected(false);
|
||||||
for (auto it = list.rbegin(); it != list.rend(); ++it, --i)
|
m[pos+i].setSelected(true);
|
||||||
{
|
|
||||||
(*it)->setSelected(false);
|
|
||||||
m[pos+i].setSelected(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (diff < 0) // move up
|
else if (diff < 0) // move up
|
||||||
@@ -251,23 +245,20 @@ void moveSelectedItemsTo(NC::Menu<MPD::Song> &m, F move_fun)
|
|||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
for (auto it = list.begin(); it != list.end(); ++it, ++i)
|
for (auto it = list.begin(); it != list.end(); ++it, ++i)
|
||||||
move_fun(Mpd, *it - begin, pos+i);
|
move_fun(Mpd, *it - begin, pos+i);
|
||||||
if (Mpd.CommitCommandsList())
|
Mpd.CommitCommandsList();
|
||||||
|
i = 0;
|
||||||
|
for (auto it = list.begin(); it != list.end(); ++it, ++i)
|
||||||
{
|
{
|
||||||
i = 0;
|
(*it)->setSelected(false);
|
||||||
for (auto it = list.begin(); it != list.end(); ++it, ++i)
|
m[pos+i].setSelected(true);
|
||||||
{
|
|
||||||
(*it)->setSelected(false);
|
|
||||||
m[pos+i].setSelected(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
bool deleteSelectedSongs(NC::Menu<MPD::Song> &m, F delete_fun)
|
void deleteSelectedSongs(NC::Menu<MPD::Song> &m, F delete_fun)
|
||||||
{
|
{
|
||||||
bool result = false;
|
|
||||||
selectCurrentIfNoneSelected(m);
|
selectCurrentIfNoneSelected(m);
|
||||||
// ok, this is tricky. we need to operate on whole playlist
|
// ok, this is tricky. we need to operate on whole playlist
|
||||||
// to get positions right, but at the same time we need to
|
// to get positions right, but at the same time we need to
|
||||||
@@ -298,31 +289,27 @@ bool deleteSelectedSongs(NC::Menu<MPD::Song> &m, F delete_fun)
|
|||||||
++cur_filtered;
|
++cur_filtered;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Mpd.CommitCommandsList())
|
Mpd.CommitCommandsList();
|
||||||
result = true;
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
bool cropPlaylist(NC::Menu<MPD::Song> &m, F delete_fun)
|
void cropPlaylist(NC::Menu<MPD::Song> &m, F delete_fun)
|
||||||
{
|
{
|
||||||
reverseSelectionHelper(m.begin(), m.end());
|
reverseSelectionHelper(m.begin(), m.end());
|
||||||
return deleteSelectedSongs(m, delete_fun);
|
deleteSelectedSongs(m, delete_fun);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F, typename G>
|
template <typename F, typename G>
|
||||||
bool clearPlaylist(NC::Menu<MPD::Song> &m, F delete_fun, G clear_fun)
|
void clearPlaylist(NC::Menu<MPD::Song> &m, F delete_fun, G clear_fun)
|
||||||
{
|
{
|
||||||
bool result = false;
|
|
||||||
if (m.isFiltered())
|
if (m.isFiltered())
|
||||||
{
|
{
|
||||||
for (auto it = m.begin(); it != m.end(); ++it)
|
for (auto it = m.begin(); it != m.end(); ++it)
|
||||||
it->setSelected(true);
|
it->setSelected(true);
|
||||||
result = deleteSelectedSongs(m, delete_fun);
|
deleteSelectedSongs(m, delete_fun);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
result = clear_fun(Mpd);
|
clear_fun(Mpd);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Iterator> std::string getSharedDirectory(Iterator first, Iterator last)
|
template <typename Iterator> std::string getSharedDirectory(Iterator first, Iterator last)
|
||||||
@@ -471,7 +458,7 @@ template <typename BufferT> void ShowTag(BufferT &buf, const std::string &tag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool addSongToPlaylist(const MPD::Song &s, bool play, size_t position = -1);
|
bool addSongToPlaylist(const MPD::Song &s, bool play, size_t position = -1);
|
||||||
bool addSongsToPlaylist(const MPD::SongList &list, bool play, size_t position = -1);
|
void addSongsToPlaylist(const MPD::SongList &list, bool play, size_t position = -1);
|
||||||
|
|
||||||
std::string Timestamp(time_t t);
|
std::string Timestamp(time_t t);
|
||||||
|
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ void Lastfm::Save(const std::string &data)
|
|||||||
output.close();
|
output.close();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Error("couldn't save file \"" << itsFilename << "\"");
|
std::cerr << "ncmpcpp: couldn't save file \"" << itsFilename << "\"\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void Lastfm::Refetch()
|
void Lastfm::Refetch()
|
||||||
|
|||||||
@@ -249,8 +249,6 @@ std::wstring MediaLibrary::title()
|
|||||||
|
|
||||||
void MediaLibrary::update()
|
void MediaLibrary::update()
|
||||||
{
|
{
|
||||||
Mpd.BlockIdle(true);
|
|
||||||
|
|
||||||
if (hasTwoColumns)
|
if (hasTwoColumns)
|
||||||
{
|
{
|
||||||
if (Albums.reallyEmpty() || m_albums_update_request)
|
if (Albums.reallyEmpty() || m_albums_update_request)
|
||||||
@@ -407,8 +405,6 @@ void MediaLibrary::update()
|
|||||||
});
|
});
|
||||||
Songs.refresh();
|
Songs.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
Mpd.BlockIdle(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaLibrary::enterPressed()
|
void MediaLibrary::enterPressed()
|
||||||
@@ -969,20 +965,18 @@ void MediaLibrary::AddToPlaylist(bool add_n_play)
|
|||||||
addSongToPlaylist(Songs.current().value(), add_n_play);
|
addSongToPlaylist(Songs.current().value(), add_n_play);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto list = getSelectedSongs();
|
addSongsToPlaylist(getSelectedSongs(), add_n_play);
|
||||||
if (addSongsToPlaylist(list, add_n_play))
|
if ((!Tags.empty() && isActiveWindow(Tags))
|
||||||
|
|| (isActiveWindow(Albums) && Albums.current().value().isAllTracksEntry()))
|
||||||
{
|
{
|
||||||
if ((!Tags.empty() && isActiveWindow(Tags))
|
std::string tag_type = boost::locale::to_lower(
|
||||||
|| (isActiveWindow(Albums) && Albums.current().value().isAllTracksEntry()))
|
tagTypeToString(Config.media_lib_primary_tag));
|
||||||
{
|
Statusbar::msg("Songs with %s = \"%s\" added",
|
||||||
std::string tag_type = boost::locale::to_lower(
|
tag_type.c_str(), Tags.current().value().tag().c_str());
|
||||||
tagTypeToString(Config.media_lib_primary_tag));
|
|
||||||
Statusbar::msg("Songs with %s = \"%s\" added", tag_type.c_str(), Tags.current().value().tag().c_str());
|
|
||||||
}
|
|
||||||
else if (isActiveWindow(Albums))
|
|
||||||
Statusbar::msg("Songs from album \"%s\" added",
|
|
||||||
Albums.current().value().entry().album().c_str());
|
|
||||||
}
|
}
|
||||||
|
else if (isActiveWindow(Albums))
|
||||||
|
Statusbar::msg("Songs from album \"%s\" added",
|
||||||
|
Albums.current().value().entry().album().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!add_n_play)
|
if (!add_n_play)
|
||||||
|
|||||||
1350
src/mpdpp.cpp
1350
src/mpdpp.cpp
File diff suppressed because it is too large
Load Diff
216
src/mpdpp.h
216
src/mpdpp.h
@@ -22,6 +22,7 @@
|
|||||||
#define NCMPCPP_MPDPP_H
|
#define NCMPCPP_MPDPP_H
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <exception>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -34,6 +35,36 @@ enum ItemType { itDirectory, itSong, itPlaylist };
|
|||||||
enum PlayerState { psUnknown, psStop, psPlay, psPause };
|
enum PlayerState { psUnknown, psStop, psPlay, psPause };
|
||||||
enum ReplayGainMode { rgmOff, rgmTrack, rgmAlbum };
|
enum ReplayGainMode { rgmOff, rgmTrack, rgmAlbum };
|
||||||
|
|
||||||
|
struct ClientError: public std::exception
|
||||||
|
{
|
||||||
|
ClientError(mpd_error code_, std::string msg, bool clearable_)
|
||||||
|
: m_code(code_), m_msg(msg), m_clearable(clearable_) { }
|
||||||
|
|
||||||
|
virtual const char *what() const noexcept { return m_msg.c_str(); }
|
||||||
|
mpd_error code() const { return m_code; }
|
||||||
|
bool clearable() const { return m_clearable; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
mpd_error m_code;
|
||||||
|
std::string m_msg;
|
||||||
|
bool m_clearable;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ServerError: public std::exception
|
||||||
|
{
|
||||||
|
ServerError(mpd_server_error code_, std::string msg, bool clearable_)
|
||||||
|
: m_code(code_), m_msg(msg), m_clearable(clearable_) { }
|
||||||
|
|
||||||
|
virtual const char *what() const noexcept { return m_msg.c_str(); }
|
||||||
|
mpd_server_error code() const { return m_code; }
|
||||||
|
bool clearable() const { return m_clearable; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
mpd_server_error m_code;
|
||||||
|
std::string m_msg;
|
||||||
|
bool m_clearable;
|
||||||
|
};
|
||||||
|
|
||||||
struct Statistics
|
struct Statistics
|
||||||
{
|
{
|
||||||
friend class Connection;
|
friend class Connection;
|
||||||
@@ -54,6 +85,40 @@ private:
|
|||||||
std::shared_ptr<mpd_stats> m_stats;
|
std::shared_ptr<mpd_stats> m_stats;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Status
|
||||||
|
{
|
||||||
|
friend class Connection;
|
||||||
|
|
||||||
|
Status() { }
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
bool empty() const;
|
||||||
|
|
||||||
|
int volume() const;
|
||||||
|
bool repeat() const;
|
||||||
|
bool random() const;
|
||||||
|
bool single() const;
|
||||||
|
bool consume() const;
|
||||||
|
unsigned playlistLength() const;
|
||||||
|
unsigned playlistVersion() const;
|
||||||
|
PlayerState playerState() const;
|
||||||
|
unsigned crossfade() const;
|
||||||
|
int currentSongPosition() const;
|
||||||
|
int currentSongID() const;
|
||||||
|
int nextSongPosition() const;
|
||||||
|
int nextSongID() const;
|
||||||
|
unsigned elapsedTime() const;
|
||||||
|
unsigned totalTime() const;
|
||||||
|
unsigned kbps() const;
|
||||||
|
unsigned updateID() const;
|
||||||
|
const char *error() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Status(mpd_status *status) : m_status(status, mpd_status_free) { }
|
||||||
|
|
||||||
|
std::shared_ptr<mpd_status> m_status;
|
||||||
|
};
|
||||||
|
|
||||||
struct Item
|
struct Item
|
||||||
{
|
{
|
||||||
std::shared_ptr<Song> song;
|
std::shared_ptr<Song> song;
|
||||||
@@ -61,26 +126,6 @@ struct Item
|
|||||||
std::string name;
|
std::string name;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StatusChanges
|
|
||||||
{
|
|
||||||
StatusChanges() : Playlist(0), StoredPlaylists(0), SongID(0), Database(0), DBUpdating(0), Volume(0), ElapsedTime(0), Crossfade(0), Random(0), Repeat(0), Single(0), Consume(0), PlayerState(0), StatusFlags(0), Outputs(0) { }
|
|
||||||
bool Playlist:1;
|
|
||||||
bool StoredPlaylists:1;
|
|
||||||
bool SongID:1;
|
|
||||||
bool Database:1;
|
|
||||||
bool DBUpdating:1;
|
|
||||||
bool Volume:1;
|
|
||||||
bool ElapsedTime:1;
|
|
||||||
bool Crossfade:1;
|
|
||||||
bool Random:1;
|
|
||||||
bool Repeat:1;
|
|
||||||
bool Single:1;
|
|
||||||
bool Consume:1;
|
|
||||||
bool PlayerState:1;
|
|
||||||
bool StatusFlags:1;
|
|
||||||
bool Outputs:1;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Output
|
struct Output
|
||||||
{
|
{
|
||||||
Output(const std::string &name_, bool enabled) : m_name(name_), m_enabled(enabled) { }
|
Output(const std::string &name_, bool enabled) : m_name(name_), m_enabled(enabled) { }
|
||||||
@@ -99,7 +144,6 @@ typedef std::vector<Output> OutputList;
|
|||||||
|
|
||||||
class Connection
|
class Connection
|
||||||
{
|
{
|
||||||
typedef void (*StatusUpdater) (Connection *, StatusChanges, void *);
|
|
||||||
typedef void (*ErrorHandler) (Connection *, int, const char *, void *);
|
typedef void (*ErrorHandler) (Connection *, int, const char *, void *);
|
||||||
|
|
||||||
typedef std::function<void(Item &&)> ItemConsumer;
|
typedef std::function<void(Item &&)> ItemConsumer;
|
||||||
@@ -111,33 +155,27 @@ public:
|
|||||||
Connection();
|
Connection();
|
||||||
~Connection();
|
~Connection();
|
||||||
|
|
||||||
bool Connect();
|
void Connect();
|
||||||
bool Connected() const;
|
bool Connected() const;
|
||||||
void Disconnect();
|
void Disconnect();
|
||||||
|
|
||||||
const std::string & GetHostname() { return itsHost; }
|
const std::string &GetHostname() { return m_host; }
|
||||||
int GetPort() { return itsPort; }
|
int GetPort() { return m_port; }
|
||||||
|
|
||||||
unsigned Version() const;
|
unsigned Version() const;
|
||||||
|
|
||||||
void SetIdleEnabled(bool val) { isIdleEnabled = val; }
|
int GetFD() const { return m_fd; }
|
||||||
void BlockIdle(bool val) { itsIdleBlocked = val; }
|
|
||||||
bool SupportsIdle() const { return supportsIdle; }
|
|
||||||
void OrderDataFetching() { hasData = 1; }
|
|
||||||
int GetFD() const { return itsFD; }
|
|
||||||
|
|
||||||
void SetHostname(const std::string &);
|
void SetHostname(const std::string &);
|
||||||
void SetPort(int port) { itsPort = port; }
|
void SetPort(int port) { m_port = port; }
|
||||||
void SetTimeout(int timeout) { itsTimeout = timeout; }
|
void SetTimeout(int timeout) { m_timeout = timeout; }
|
||||||
void SetPassword(const std::string &password) { itsPassword = password; }
|
void SetPassword(const std::string &password) { m_password = password; }
|
||||||
bool SendPassword();
|
void SendPassword();
|
||||||
|
|
||||||
Statistics getStatistics();
|
Statistics getStatistics();
|
||||||
|
Status getStatus();
|
||||||
|
|
||||||
void SetStatusUpdater(StatusUpdater, void *);
|
void UpdateDirectory(const std::string &);
|
||||||
void SetErrorHandler(ErrorHandler, void *);
|
|
||||||
void UpdateStatus();
|
|
||||||
bool UpdateDirectory(const std::string &);
|
|
||||||
|
|
||||||
void Play();
|
void Play();
|
||||||
void Play(int);
|
void Play(int);
|
||||||
@@ -147,36 +185,15 @@ public:
|
|||||||
void Stop();
|
void Stop();
|
||||||
void Next();
|
void Next();
|
||||||
void Prev();
|
void Prev();
|
||||||
bool Move(unsigned, unsigned);
|
void Move(unsigned int from, unsigned int to);
|
||||||
void Swap(unsigned, unsigned);
|
void Swap(unsigned, unsigned);
|
||||||
void Seek(unsigned);
|
void Seek(unsigned);
|
||||||
void Shuffle();
|
void Shuffle();
|
||||||
bool ClearMainPlaylist();
|
void ClearMainPlaylist();
|
||||||
|
|
||||||
bool isPlaying() const { return GetState() > psStop; }
|
|
||||||
|
|
||||||
PlayerState GetState() const { return itsCurrentStatus ? PlayerState(mpd_status_get_state(itsCurrentStatus)) : psUnknown; }
|
|
||||||
PlayerState GetOldState() const { return itsOldStatus ? PlayerState(mpd_status_get_state(itsOldStatus)) : psUnknown; }
|
|
||||||
bool GetRepeat() const { return itsCurrentStatus ? mpd_status_get_repeat(itsCurrentStatus) : 0; }
|
|
||||||
bool GetRandom() const { return itsCurrentStatus ? mpd_status_get_random(itsCurrentStatus) : 0; }
|
|
||||||
bool GetSingle() const { return itsCurrentStatus ? mpd_status_get_single(itsCurrentStatus) : 0; }
|
|
||||||
bool GetConsume() const { return itsCurrentStatus ? mpd_status_get_consume(itsCurrentStatus) : 0; }
|
|
||||||
bool GetDBIsUpdating() const { return itsCurrentStatus ? mpd_status_get_update_id(itsCurrentStatus) : 0; }
|
|
||||||
int GetVolume() const { return itsCurrentStatus ? mpd_status_get_volume(itsCurrentStatus) : -1; }
|
|
||||||
unsigned GetCrossfade() const { return itsCurrentStatus ? mpd_status_get_crossfade(itsCurrentStatus) : 0; }
|
|
||||||
unsigned GetPlaylistID() const { return itsCurrentStatus ? mpd_status_get_queue_version(itsCurrentStatus) : 0; }
|
|
||||||
unsigned GetOldPlaylistID() const { return itsOldStatus ? mpd_status_get_queue_version(itsOldStatus) : 0; }
|
|
||||||
unsigned GetElapsedTime() const { return itsCurrentStatus ? itsElapsed : 0; }
|
|
||||||
int GetTotalTime() const { return itsCurrentStatus ? mpd_status_get_total_time(itsCurrentStatus) : 0; }
|
|
||||||
unsigned GetBitrate() const { return itsCurrentStatus ? mpd_status_get_kbit_rate(itsCurrentStatus) : 0; }
|
|
||||||
|
|
||||||
size_t GetPlaylistLength() const { return itsCurrentStatus ? mpd_status_get_queue_length(itsCurrentStatus) : 0; }
|
|
||||||
void GetPlaylistChanges(unsigned, SongConsumer f);
|
void GetPlaylistChanges(unsigned, SongConsumer f);
|
||||||
|
|
||||||
const std::string &GetErrorMessage() const { return itsErrorMessage; }
|
|
||||||
|
|
||||||
Song GetCurrentlyPlayingSong();
|
Song GetCurrentlyPlayingSong();
|
||||||
int GetCurrentSongPos() const;
|
|
||||||
Song GetSong(const std::string &);
|
Song GetSong(const std::string &);
|
||||||
void GetPlaylistContent(const std::string &name, SongConsumer f);
|
void GetPlaylistContent(const std::string &name, SongConsumer f);
|
||||||
|
|
||||||
@@ -187,36 +204,35 @@ public:
|
|||||||
void SetSingle(bool);
|
void SetSingle(bool);
|
||||||
void SetConsume(bool);
|
void SetConsume(bool);
|
||||||
void SetCrossfade(unsigned);
|
void SetCrossfade(unsigned);
|
||||||
bool SetVolume(unsigned);
|
void SetVolume(unsigned int vol);
|
||||||
|
|
||||||
std::string GetReplayGainMode();
|
std::string GetReplayGainMode();
|
||||||
void SetReplayGainMode(ReplayGainMode);
|
void SetReplayGainMode(ReplayGainMode);
|
||||||
|
|
||||||
bool SetPriority(const Song &s, int prio);
|
void SetPriority(const MPD::Song &s, int prio);
|
||||||
|
|
||||||
int AddSong(const std::string &, int = -1); // returns id of added song
|
int AddSong(const std::string &, int = -1); // returns id of added song
|
||||||
int AddSong(const Song &, int = -1); // returns id of added song
|
int AddSong(const Song &, int = -1); // returns id of added song
|
||||||
bool AddRandomTag(mpd_tag_type, size_t);
|
bool AddRandomTag(mpd_tag_type, size_t);
|
||||||
bool AddRandomSongs(size_t);
|
bool AddRandomSongs(size_t);
|
||||||
bool Add(const std::string &path);
|
void Add(const std::string &path);
|
||||||
bool Delete(unsigned);
|
void Delete(unsigned int pos);
|
||||||
bool DeleteID(unsigned);
|
void PlaylistDelete(const std::string &playlist, unsigned int pos);
|
||||||
bool PlaylistDelete(const std::string &, unsigned);
|
|
||||||
void StartCommandsList();
|
void StartCommandsList();
|
||||||
bool CommitCommandsList();
|
void CommitCommandsList();
|
||||||
|
|
||||||
bool DeletePlaylist(const std::string &);
|
void DeletePlaylist(const std::string &name);
|
||||||
bool LoadPlaylist(const std::string &name);
|
void LoadPlaylist(const std::string &name);
|
||||||
int SavePlaylist(const std::string &);
|
void SavePlaylist(const std::string &);
|
||||||
bool ClearPlaylist(const std::string &);
|
void ClearPlaylist(const std::string &playlist);
|
||||||
void AddToPlaylist(const std::string &, const Song &);
|
void AddToPlaylist(const std::string &, const Song &);
|
||||||
void AddToPlaylist(const std::string &, const std::string &);
|
void AddToPlaylist(const std::string &, const std::string &);
|
||||||
bool PlaylistMove(const std::string &, int, int);
|
void PlaylistMove(const std::string &path, int from, int to);
|
||||||
bool Rename(const std::string &, const std::string &);
|
void Rename(const std::string &from, const std::string &to);
|
||||||
|
|
||||||
void StartSearch(bool);
|
void StartSearch(bool);
|
||||||
void StartFieldSearch(mpd_tag_type);
|
void StartFieldSearch(mpd_tag_type);
|
||||||
void AddSearch(mpd_tag_type, const std::string &) const;
|
void AddSearch(mpd_tag_type item, const std::string &str) const;
|
||||||
void AddSearchAny(const std::string &str) const;
|
void AddSearchAny(const std::string &str) const;
|
||||||
void AddSearchURI(const std::string &str) const;
|
void AddSearchURI(const std::string &str) const;
|
||||||
void CommitSearchSongs(SongConsumer f);
|
void CommitSearchSongs(SongConsumer f);
|
||||||
@@ -230,53 +246,39 @@ public:
|
|||||||
void GetDirectories(const std::string &directory, StringConsumer f);
|
void GetDirectories(const std::string &directory, StringConsumer f);
|
||||||
|
|
||||||
void GetOutputs(OutputConsumer f);
|
void GetOutputs(OutputConsumer f);
|
||||||
bool EnableOutput(int);
|
void EnableOutput(int id);
|
||||||
bool DisableOutput(int);
|
void DisableOutput(int id);
|
||||||
|
|
||||||
void GetURLHandlers(StringConsumer f);
|
void GetURLHandlers(StringConsumer f);
|
||||||
void GetTagTypes(StringConsumer f);
|
void GetTagTypes(StringConsumer f);
|
||||||
|
|
||||||
|
void idle();
|
||||||
|
int noidle();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void GoIdle();
|
|
||||||
int GoBusy();
|
|
||||||
|
|
||||||
int CheckForErrors();
|
void checkConnection() const;
|
||||||
|
void prechecks();
|
||||||
|
void prechecksNoCommandsList();
|
||||||
|
void checkErrors() const;
|
||||||
|
|
||||||
mpd_connection *itsConnection;
|
mpd_connection *m_connection;
|
||||||
bool isCommandsListEnabled;
|
bool m_command_list_active;
|
||||||
|
|
||||||
std::string itsErrorMessage;
|
int m_fd;
|
||||||
|
bool m_idle;
|
||||||
|
|
||||||
int itsFD;
|
std::string m_host;
|
||||||
bool isIdle;
|
int m_port;
|
||||||
bool isIdleEnabled;
|
int m_timeout;
|
||||||
bool itsIdleBlocked;
|
std::string m_password;
|
||||||
bool supportsIdle;
|
|
||||||
bool hasData;
|
|
||||||
|
|
||||||
std::string itsHost;
|
mpd_tag_type m_searched_field;
|
||||||
int itsPort;
|
|
||||||
int itsTimeout;
|
|
||||||
std::string itsPassword;
|
|
||||||
|
|
||||||
mpd_status *itsCurrentStatus;
|
|
||||||
mpd_status *itsOldStatus;
|
|
||||||
|
|
||||||
unsigned itsElapsed;
|
|
||||||
time_t itsElapsedTimer[2];
|
|
||||||
|
|
||||||
StatusChanges itsChanges;
|
|
||||||
|
|
||||||
StatusUpdater itsUpdater;
|
|
||||||
void *itsStatusUpdaterUserdata;
|
|
||||||
ErrorHandler itsErrorHandler;
|
|
||||||
void *itsErrorHandlerUserdata;
|
|
||||||
|
|
||||||
mpd_tag_type itsSearchedField;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern MPD::Connection Mpd;
|
extern MPD::Connection Mpd;
|
||||||
|
extern MPD::Status MpdStatus;
|
||||||
|
|
||||||
#endif // NCMPCPP_MPDPP_H
|
#endif // NCMPCPP_MPDPP_H
|
||||||
|
|||||||
157
src/ncmpcpp.cpp
157
src/ncmpcpp.cpp
@@ -40,6 +40,7 @@
|
|||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
#include "lyrics.h"
|
#include "lyrics.h"
|
||||||
|
#include "outputs.h"
|
||||||
#include "playlist.h"
|
#include "playlist.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "status.h"
|
#include "status.h"
|
||||||
@@ -97,7 +98,6 @@ int main(int argc, char **argv)
|
|||||||
using Global::wHeader;
|
using Global::wHeader;
|
||||||
using Global::wFooter;
|
using Global::wFooter;
|
||||||
|
|
||||||
using Global::ShowMessages;
|
|
||||||
using Global::VolumeState;
|
using Global::VolumeState;
|
||||||
using Global::Timer;
|
using Global::Timer;
|
||||||
|
|
||||||
@@ -126,20 +126,10 @@ int main(int argc, char **argv)
|
|||||||
Mpd.SetPort(Config.mpd_port);
|
Mpd.SetPort(Config.mpd_port);
|
||||||
|
|
||||||
Mpd.SetTimeout(Config.mpd_connection_timeout);
|
Mpd.SetTimeout(Config.mpd_connection_timeout);
|
||||||
Mpd.SetIdleEnabled(Config.enable_idle_notifications);
|
|
||||||
|
|
||||||
if (argc > 1)
|
if (argc > 1)
|
||||||
ParseArgv(argc, argv);
|
ParseArgv(argc, argv);
|
||||||
|
|
||||||
if (!Actions::connectToMPD())
|
|
||||||
exit(1);
|
|
||||||
|
|
||||||
if (Mpd.Version() < 16)
|
|
||||||
{
|
|
||||||
std::cout << "MPD < 0.16.0 is not supported, please upgrade.\n";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
CreateDir(Config.ncmpcpp_directory);
|
CreateDir(Config.ncmpcpp_directory);
|
||||||
|
|
||||||
// always execute these commands, even if ncmpcpp use exit function
|
// always execute these commands, even if ncmpcpp use exit function
|
||||||
@@ -171,8 +161,6 @@ int main(int argc, char **argv)
|
|||||||
wFooter = new NC::Window(0, Actions::FooterStartY, COLS, Actions::FooterHeight, "", Config.statusbar_color, NC::Border::None);
|
wFooter = new NC::Window(0, Actions::FooterStartY, COLS, Actions::FooterHeight, "", Config.statusbar_color, NC::Border::None);
|
||||||
wFooter->setTimeout(500);
|
wFooter->setTimeout(500);
|
||||||
wFooter->setGetStringHelper(Statusbar::Helpers::getString);
|
wFooter->setGetStringHelper(Statusbar::Helpers::getString);
|
||||||
if (Mpd.SupportsIdle())
|
|
||||||
wFooter->addFDCallback(Mpd.GetFD(), Statusbar::Helpers::mpd);
|
|
||||||
wFooter->createHistory();
|
wFooter->createHistory();
|
||||||
|
|
||||||
// initialize global timer
|
// initialize global timer
|
||||||
@@ -186,9 +174,6 @@ int main(int argc, char **argv)
|
|||||||
if (Config.startup_screen != myScreen)
|
if (Config.startup_screen != myScreen)
|
||||||
Config.startup_screen->switchTo();
|
Config.startup_screen->switchTo();
|
||||||
|
|
||||||
Mpd.SetStatusUpdater(Status::update, 0);
|
|
||||||
Mpd.SetErrorHandler(Status::handleError, 0);
|
|
||||||
|
|
||||||
// local variables
|
// local variables
|
||||||
Key input(0, Key::Standard);
|
Key input(0, Key::Standard);
|
||||||
timeval past = { 0, 0 };
|
timeval past = { 0, 0 };
|
||||||
@@ -198,15 +183,6 @@ int main(int argc, char **argv)
|
|||||||
if (Config.mouse_support)
|
if (Config.mouse_support)
|
||||||
mousemask(ALL_MOUSE_EVENTS, 0);
|
mousemask(ALL_MOUSE_EVENTS, 0);
|
||||||
|
|
||||||
Mpd.OrderDataFetching();
|
|
||||||
if (Config.jump_to_now_playing_song_at_start)
|
|
||||||
{
|
|
||||||
Status::trace();
|
|
||||||
int curr_pos = Mpd.GetCurrentSongPos();
|
|
||||||
if (curr_pos >= 0)
|
|
||||||
myPlaylist->main().highlight(curr_pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
# ifndef WIN32
|
# ifndef WIN32
|
||||||
signal(SIGPIPE, sighandler);
|
signal(SIGPIPE, sighandler);
|
||||||
signal(SIGWINCH, sighandler);
|
signal(SIGWINCH, sighandler);
|
||||||
@@ -214,66 +190,95 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
while (!Actions::ExitMainLoop)
|
while (!Actions::ExitMainLoop)
|
||||||
{
|
{
|
||||||
if (!Mpd.Connected())
|
try
|
||||||
{
|
{
|
||||||
if (!wFooter->FDCallbacksListEmpty())
|
if (!Mpd.Connected())
|
||||||
wFooter->clearFDCallbacksList();
|
|
||||||
Statusbar::msg("Attempting to reconnect...");
|
|
||||||
if (Mpd.Connect())
|
|
||||||
{
|
{
|
||||||
Statusbar::msg("Connected to %s", Mpd.GetHostname().c_str());
|
wFooter->clearFDCallbacksList();
|
||||||
if (Mpd.SupportsIdle())
|
try
|
||||||
{
|
{
|
||||||
|
Mpd.Connect();
|
||||||
|
if (Mpd.Version() < 16)
|
||||||
|
{
|
||||||
|
// FIXME workaround so we won't get assertion fails
|
||||||
|
MpdStatus = Mpd.getStatus();
|
||||||
|
Mpd.Disconnect();
|
||||||
|
throw MPD::ClientError(MPD_ERROR_STATE, "MPD < 0.16.0 is not supported", false);
|
||||||
|
}
|
||||||
|
MpdStatus.clear();
|
||||||
wFooter->addFDCallback(Mpd.GetFD(), Statusbar::Helpers::mpd);
|
wFooter->addFDCallback(Mpd.GetFD(), Statusbar::Helpers::mpd);
|
||||||
Mpd.OrderDataFetching(); // we need info about new connection
|
Status::update(-1); // we need info about new connection
|
||||||
|
|
||||||
|
if (Config.jump_to_now_playing_song_at_start)
|
||||||
|
{
|
||||||
|
int curr_pos = MpdStatus.currentSongPosition();
|
||||||
|
if (curr_pos >= 0)
|
||||||
|
myPlaylist->main().highlight(curr_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
myBrowser->fetchSupportedExtensions();
|
||||||
|
# ifdef ENABLE_OUTPUTS
|
||||||
|
myOutputs->FetchList();
|
||||||
|
# endif // ENABLE_OUTPUTS
|
||||||
|
# ifdef ENABLE_VISUALIZER
|
||||||
|
myVisualizer->ResetFD();
|
||||||
|
if (myScreen == myVisualizer)
|
||||||
|
myVisualizer->SetFD();
|
||||||
|
myVisualizer->FindOutputID();
|
||||||
|
# endif // ENABLE_VISUALIZER
|
||||||
|
|
||||||
|
Statusbar::msg("Connected to %s", Mpd.GetHostname().c_str());
|
||||||
|
}
|
||||||
|
catch (MPD::ClientError &e)
|
||||||
|
{
|
||||||
|
Status::handleClientError(e);
|
||||||
}
|
}
|
||||||
ShowMessages = false;
|
|
||||||
# ifdef ENABLE_VISUALIZER
|
|
||||||
myVisualizer->ResetFD();
|
|
||||||
if (myScreen == myVisualizer)
|
|
||||||
myVisualizer->SetFD();
|
|
||||||
myVisualizer->FindOutputID();
|
|
||||||
# endif // ENABLE_VISUALIZER
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Status::trace();
|
||||||
|
|
||||||
|
// header stuff
|
||||||
|
if (((Timer.tv_sec == past.tv_sec && Timer.tv_usec >= past.tv_usec+500000) || Timer.tv_sec > past.tv_sec)
|
||||||
|
&& (myScreen == myPlaylist || myScreen == myBrowser || myScreen == myLyrics)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
drawHeader();
|
||||||
|
past = Timer;
|
||||||
|
}
|
||||||
|
// header stuff end
|
||||||
|
|
||||||
|
if (input != Key::noOp)
|
||||||
|
myScreen->refreshWindow();
|
||||||
|
input = Key::read(*wFooter);
|
||||||
|
|
||||||
|
if (input == Key::noOp)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto k = Bindings.get(input);
|
||||||
|
for (; k.first != k.second; ++k.first)
|
||||||
|
if (k.first->execute())
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (myScreen == myPlaylist)
|
||||||
|
myPlaylist->EnableHighlighting();
|
||||||
|
|
||||||
|
# ifdef ENABLE_VISUALIZER
|
||||||
|
// visualizer sets timeout to 40ms, but since only it needs such small
|
||||||
|
// value, we should restore defalt one after switching to another screen.
|
||||||
|
if (wFooter->getTimeout() < 500
|
||||||
|
&& !(myScreen == myVisualizer || myLockedScreen == myVisualizer || myInactiveScreen == myVisualizer)
|
||||||
|
)
|
||||||
|
wFooter->setTimeout(500);
|
||||||
|
# endif // ENABLE_VISUALIZER
|
||||||
}
|
}
|
||||||
|
catch (MPD::ClientError &e)
|
||||||
Status::trace();
|
|
||||||
|
|
||||||
ShowMessages = true;
|
|
||||||
|
|
||||||
// header stuff
|
|
||||||
if (((Timer.tv_sec == past.tv_sec && Timer.tv_usec >= past.tv_usec+500000) || Timer.tv_sec > past.tv_sec)
|
|
||||||
&& (myScreen == myPlaylist || myScreen == myBrowser || myScreen == myLyrics)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
drawHeader();
|
Status::handleClientError(e);
|
||||||
past = Timer;
|
}
|
||||||
|
catch (MPD::ServerError &e)
|
||||||
|
{
|
||||||
|
Status::handleServerError(e);
|
||||||
}
|
}
|
||||||
// header stuff end
|
|
||||||
|
|
||||||
if (input != Key::noOp)
|
|
||||||
myScreen->refreshWindow();
|
|
||||||
input = Key::read(*wFooter);
|
|
||||||
|
|
||||||
if (input == Key::noOp)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
auto k = Bindings.get(input);
|
|
||||||
for (; k.first != k.second; ++k.first)
|
|
||||||
if (k.first->execute())
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (myScreen == myPlaylist)
|
|
||||||
myPlaylist->EnableHighlighting();
|
|
||||||
|
|
||||||
# ifdef ENABLE_VISUALIZER
|
|
||||||
// visualizer sets timeout to 40ms, but since only it needs such small
|
|
||||||
// value, we should restore defalt one after switching to another screen.
|
|
||||||
if (wFooter->getTimeout() < 500
|
|
||||||
&& !(myScreen == myVisualizer || myLockedScreen == myVisualizer || myInactiveScreen == myVisualizer)
|
|
||||||
)
|
|
||||||
wFooter->setTimeout(500);
|
|
||||||
# endif // ENABLE_VISUALIZER
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ Outputs::Outputs()
|
|||||||
w.setItemDisplayer([](NC::Menu<MPD::Output> &menu) {
|
w.setItemDisplayer([](NC::Menu<MPD::Output> &menu) {
|
||||||
menu << Charset::utf8ToLocale(menu.drawn()->value().name());
|
menu << Charset::utf8ToLocale(menu.drawn()->value().name());
|
||||||
});
|
});
|
||||||
FetchList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Outputs::switchTo()
|
void Outputs::switchTo()
|
||||||
@@ -73,16 +72,14 @@ void Outputs::enterPressed()
|
|||||||
{
|
{
|
||||||
if (w.current().value().isEnabled())
|
if (w.current().value().isEnabled())
|
||||||
{
|
{
|
||||||
if (Mpd.DisableOutput(w.choice()))
|
Mpd.DisableOutput(w.choice());
|
||||||
Statusbar::msg("Output \"%s\" disabled", w.current().value().name().c_str());
|
Statusbar::msg("Output \"%s\" disabled", w.current().value().name().c_str());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (Mpd.EnableOutput(w.choice()))
|
Mpd.EnableOutput(w.choice());
|
||||||
Statusbar::msg("Output \"%s\" enabled", w.current().value().name().c_str());
|
Statusbar::msg("Output \"%s\" enabled", w.current().value().name().c_str());
|
||||||
}
|
}
|
||||||
if (!Mpd.SupportsIdle())
|
|
||||||
FetchList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Outputs::mouseButtonPressed(MEVENT me)
|
void Outputs::mouseButtonPressed(MEVENT me)
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ Playlist *myPlaylist;
|
|||||||
|
|
||||||
bool Playlist::ReloadTotalLength = 0;
|
bool Playlist::ReloadTotalLength = 0;
|
||||||
bool Playlist::ReloadRemaining = false;
|
bool Playlist::ReloadRemaining = false;
|
||||||
|
unsigned Playlist::Version = 0;
|
||||||
|
|
||||||
namespace {//
|
namespace {//
|
||||||
|
|
||||||
@@ -217,9 +218,9 @@ MPD::SongList Playlist::getSelectedSongs()
|
|||||||
MPD::Song Playlist::nowPlayingSong()
|
MPD::Song Playlist::nowPlayingSong()
|
||||||
{
|
{
|
||||||
MPD::Song s;
|
MPD::Song s;
|
||||||
if (Mpd.isPlaying())
|
if (MpdStatus.playerState() != MPD::psStop)
|
||||||
withUnfilteredMenu(w, [this, &s]() {
|
withUnfilteredMenu(w, [this, &s]() {
|
||||||
s = w.at(Mpd.GetCurrentSongPos()).value();
|
s = w.at(MpdStatus.currentSongPosition()).value();
|
||||||
});
|
});
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@@ -242,8 +243,8 @@ void Playlist::Reverse()
|
|||||||
Mpd.StartCommandsList();
|
Mpd.StartCommandsList();
|
||||||
for (--end; begin < end; ++begin, --end)
|
for (--end; begin < end; ++begin, --end)
|
||||||
Mpd.Swap(begin->value().getPosition(), end->value().getPosition());
|
Mpd.Swap(begin->value().getPosition(), end->value().getPosition());
|
||||||
if (Mpd.CommitCommandsList())
|
Mpd.CommitCommandsList();
|
||||||
Statusbar::msg("Playlist reversed");
|
Statusbar::msg("Playlist reversed");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Playlist::EnableHighlighting()
|
void Playlist::EnableHighlighting()
|
||||||
@@ -271,7 +272,7 @@ std::string Playlist::TotalLength()
|
|||||||
if (Config.playlist_show_remaining_time && ReloadRemaining && !w.isFiltered())
|
if (Config.playlist_show_remaining_time && ReloadRemaining && !w.isFiltered())
|
||||||
{
|
{
|
||||||
itsRemainingTime = 0;
|
itsRemainingTime = 0;
|
||||||
for (size_t i = Mpd.GetCurrentSongPos(); i < w.size(); ++i)
|
for (size_t i = MpdStatus.currentSongPosition(); i < w.size(); ++i)
|
||||||
itsRemainingTime += w[i].value().getDuration();
|
itsRemainingTime += w[i].value().getDuration();
|
||||||
ReloadRemaining = false;
|
ReloadRemaining = false;
|
||||||
}
|
}
|
||||||
@@ -284,7 +285,7 @@ std::string Playlist::TotalLength()
|
|||||||
size_t real_size = w.size();
|
size_t real_size = w.size();
|
||||||
w.showFiltered();
|
w.showFiltered();
|
||||||
if (w.size() != real_size)
|
if (w.size() != real_size)
|
||||||
result << " (out of " << Mpd.GetPlaylistLength() << ")";
|
result << " (out of " << real_size << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (itsTotalLength)
|
if (itsTotalLength)
|
||||||
@@ -307,7 +308,7 @@ void Playlist::PlayNewlyAddedSongs()
|
|||||||
bool is_filtered = w.isFiltered();
|
bool is_filtered = w.isFiltered();
|
||||||
w.showAll();
|
w.showAll();
|
||||||
size_t old_size = w.size();
|
size_t old_size = w.size();
|
||||||
Mpd.UpdateStatus();
|
//Mpd.UpdateStatus();
|
||||||
if (old_size < w.size())
|
if (old_size < w.size())
|
||||||
Mpd.Play(old_size);
|
Mpd.Play(old_size);
|
||||||
if (is_filtered)
|
if (is_filtered)
|
||||||
@@ -320,8 +321,8 @@ void Playlist::SetSelectedItemsPriority(int prio)
|
|||||||
Mpd.StartCommandsList();
|
Mpd.StartCommandsList();
|
||||||
for (auto it = list.begin(); it != list.end(); ++it)
|
for (auto it = list.begin(); it != list.end(); ++it)
|
||||||
Mpd.SetPriority((*it)->value(), prio);
|
Mpd.SetPriority((*it)->value(), prio);
|
||||||
if (Mpd.CommitCommandsList())
|
Mpd.CommitCommandsList();
|
||||||
Statusbar::msg("Priority set");
|
Statusbar::msg("Priority set");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Playlist::checkForSong(const MPD::Song &s)
|
bool Playlist::checkForSong(const MPD::Song &s)
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ struct Playlist: Screen<NC::Menu<MPD::Song>>, Filterable, HasSongs, Searchable,
|
|||||||
void registerHash(size_t hash);
|
void registerHash(size_t hash);
|
||||||
void unregisterHash(size_t hash);
|
void unregisterHash(size_t hash);
|
||||||
|
|
||||||
|
static unsigned Version;
|
||||||
static bool ReloadTotalLength;
|
static bool ReloadTotalLength;
|
||||||
static bool ReloadRemaining;
|
static bool ReloadRemaining;
|
||||||
|
|
||||||
|
|||||||
@@ -221,12 +221,10 @@ void PlaylistEditor::AddToPlaylist(bool add_n_play)
|
|||||||
|
|
||||||
if (isActiveWindow(Playlists) && !Playlists.empty())
|
if (isActiveWindow(Playlists) && !Playlists.empty())
|
||||||
{
|
{
|
||||||
if (Mpd.LoadPlaylist(Playlists.current().value()))
|
Mpd.LoadPlaylist(Playlists.current().value());
|
||||||
{
|
Statusbar::msg("Playlist \"%s\" loaded", Playlists.current().value().c_str());
|
||||||
Statusbar::msg("Playlist \"%s\" loaded", Playlists.current().value().c_str());
|
if (add_n_play)
|
||||||
if (add_n_play)
|
myPlaylist->PlayNewlyAddedSongs();
|
||||||
myPlaylist->PlayNewlyAddedSongs();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (isActiveWindow(Content) && !Content.empty())
|
else if (isActiveWindow(Content) && !Content.empty())
|
||||||
addSongToPlaylist(Content.current().value(), add_n_play);
|
addSongToPlaylist(Content.current().value(), add_n_play);
|
||||||
|
|||||||
@@ -234,61 +234,54 @@ void SelectedItemsAdder::addToExistingPlaylist(const std::string &playlist) cons
|
|||||||
Mpd.StartCommandsList();
|
Mpd.StartCommandsList();
|
||||||
for (auto s = m_selected_items.begin(); s != m_selected_items.end(); ++s)
|
for (auto s = m_selected_items.begin(); s != m_selected_items.end(); ++s)
|
||||||
Mpd.AddToPlaylist(playlist, *s);
|
Mpd.AddToPlaylist(playlist, *s);
|
||||||
if (Mpd.CommitCommandsList())
|
Mpd.CommitCommandsList();
|
||||||
{
|
Statusbar::msg("Selected item(s) added to playlist \"%s\"", playlist.c_str());
|
||||||
Statusbar::msg("Selected item(s) added to playlist \"%s\"", playlist.c_str());
|
switchToPreviousScreen();
|
||||||
switchToPreviousScreen();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectedItemsAdder::addAtTheEndOfPlaylist() const
|
void SelectedItemsAdder::addAtTheEndOfPlaylist() const
|
||||||
{
|
{
|
||||||
bool success = addSongsToPlaylist(m_selected_items, false);
|
addSongsToPlaylist(m_selected_items, false);
|
||||||
if (success)
|
exitSuccessfully();
|
||||||
exitSuccessfully();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectedItemsAdder::addAtTheBeginningOfPlaylist() const
|
void SelectedItemsAdder::addAtTheBeginningOfPlaylist() const
|
||||||
{
|
{
|
||||||
bool success = addSongsToPlaylist(m_selected_items, false, 0);
|
addSongsToPlaylist(m_selected_items, false, 0);
|
||||||
if (success)
|
exitSuccessfully();
|
||||||
exitSuccessfully();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectedItemsAdder::addAfterCurrentSong() const
|
void SelectedItemsAdder::addAfterCurrentSong() const
|
||||||
{
|
{
|
||||||
if (!Mpd.isPlaying())
|
if (MpdStatus.playerState() == MPD::psStop)
|
||||||
return;
|
return;
|
||||||
size_t pos = Mpd.GetCurrentSongPos();
|
size_t pos = MpdStatus.currentSongPosition();
|
||||||
++pos;
|
++pos;
|
||||||
bool success = addSongsToPlaylist(m_selected_items, false, pos);
|
addSongsToPlaylist(m_selected_items, false, pos);
|
||||||
if (success)
|
exitSuccessfully();
|
||||||
exitSuccessfully();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectedItemsAdder::addAfterCurrentAlbum() const
|
void SelectedItemsAdder::addAfterCurrentAlbum() const
|
||||||
{
|
{
|
||||||
if (!Mpd.isPlaying())
|
if (MpdStatus.playerState() == MPD::psStop)
|
||||||
return;
|
return;
|
||||||
auto &pl = myPlaylist->main();
|
auto &pl = myPlaylist->main();
|
||||||
size_t pos = Mpd.GetCurrentSongPos();
|
size_t pos = MpdStatus.currentSongPosition();
|
||||||
withUnfilteredMenu(pl, [&pos, &pl]() {
|
withUnfilteredMenu(pl, [&pos, &pl]() {
|
||||||
std::string album = pl[pos].value().getAlbum();
|
std::string album = pl[pos].value().getAlbum();
|
||||||
while (pos < pl.size() && pl[pos].value().getAlbum() == album)
|
while (pos < pl.size() && pl[pos].value().getAlbum() == album)
|
||||||
++pos;
|
++pos;
|
||||||
});
|
});
|
||||||
bool success = addSongsToPlaylist(m_selected_items, false, pos);
|
addSongsToPlaylist(m_selected_items, false, pos);
|
||||||
if (success)
|
exitSuccessfully();
|
||||||
exitSuccessfully();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectedItemsAdder::addAfterHighlightedSong() const
|
void SelectedItemsAdder::addAfterHighlightedSong() const
|
||||||
{
|
{
|
||||||
size_t pos = myPlaylist->main().current().value().getPosition();
|
size_t pos = myPlaylist->main().current().value().getPosition();
|
||||||
++pos;
|
++pos;
|
||||||
bool success = addSongsToPlaylist(m_selected_items, false, pos);
|
addSongsToPlaylist(m_selected_items, false, pos);
|
||||||
if (success)
|
exitSuccessfully();
|
||||||
exitSuccessfully();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectedItemsAdder::cancel()
|
void SelectedItemsAdder::cancel()
|
||||||
|
|||||||
@@ -36,19 +36,25 @@ ServerInfo::ServerInfo()
|
|||||||
{
|
{
|
||||||
SetDimensions();
|
SetDimensions();
|
||||||
w = NC::Scrollpad((COLS-itsWidth)/2, (MainHeight-itsHeight)/2+MainStartY, itsWidth, itsHeight, "MPD server info", Config.main_color, Config.window_border);
|
w = NC::Scrollpad((COLS-itsWidth)/2, (MainHeight-itsHeight)/2+MainStartY, itsWidth, itsHeight, "MPD server info", Config.main_color, Config.window_border);
|
||||||
Mpd.GetURLHandlers([this](std::string &&handler) {
|
|
||||||
itsURLHandlers.push_back(handler);
|
|
||||||
});
|
|
||||||
Mpd.GetTagTypes([this](std::string &&tag_type) {
|
|
||||||
itsTagTypes.push_back(tag_type);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerInfo::switchTo()
|
void ServerInfo::switchTo()
|
||||||
{
|
{
|
||||||
using Global::myScreen;
|
using Global::myScreen;
|
||||||
if (myScreen != this)
|
if (myScreen != this)
|
||||||
|
{
|
||||||
SwitchTo::execute(this);
|
SwitchTo::execute(this);
|
||||||
|
|
||||||
|
itsURLHandlers.clear();
|
||||||
|
itsTagTypes.clear();
|
||||||
|
|
||||||
|
Mpd.GetURLHandlers([this](std::string &&handler) {
|
||||||
|
itsURLHandlers.push_back(handler);
|
||||||
|
});
|
||||||
|
Mpd.GetTagTypes([this](std::string &&tag_type) {
|
||||||
|
itsTagTypes.push_back(tag_type);
|
||||||
|
});
|
||||||
|
}
|
||||||
else
|
else
|
||||||
switchToPreviousScreen();
|
switchToPreviousScreen();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -201,11 +201,9 @@ void SortPlaylistDialog::sort() const
|
|||||||
Statusbar::msg("Sorting...");
|
Statusbar::msg("Sorting...");
|
||||||
Mpd.StartCommandsList();
|
Mpd.StartCommandsList();
|
||||||
quick_sort(playlist.begin(), playlist.end());
|
quick_sort(playlist.begin(), playlist.end());
|
||||||
if (Mpd.CommitCommandsList())
|
Mpd.CommitCommandsList();
|
||||||
{
|
Statusbar::msg("Playlist sorted");
|
||||||
Statusbar::msg("Playlist sorted");
|
switchToPreviousScreen();
|
||||||
switchToPreviousScreen();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SortPlaylistDialog::cancel() const
|
void SortPlaylistDialog::cancel() const
|
||||||
|
|||||||
252
src/status.cpp
252
src/status.cpp
@@ -71,68 +71,68 @@ void drawTitle(const MPD::Song &np)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Status::trace()
|
void Status::handleClientError(MPD::ClientError &e)
|
||||||
{
|
{
|
||||||
gettimeofday(&Timer, 0);
|
if (!e.clearable())
|
||||||
if (Mpd.Connected() && (Mpd.SupportsIdle() || Timer.tv_sec > past.tv_sec))
|
Mpd.Disconnect();
|
||||||
{
|
Statusbar::msg("NCMPCPP: %s", e.what());
|
||||||
if (!Mpd.SupportsIdle())
|
|
||||||
{
|
|
||||||
past = Timer;
|
|
||||||
}
|
|
||||||
else if (Config.display_bitrate && Global::Timer.tv_sec > past.tv_sec && Mpd.GetState() == MPD::psPlay)
|
|
||||||
{
|
|
||||||
// ncmpcpp doesn't fetch status constantly if mpd supports
|
|
||||||
// idle mode so current song's bitrate is never updated.
|
|
||||||
// we need to force ncmpcpp to fetch it.
|
|
||||||
Mpd.OrderDataFetching();
|
|
||||||
past = Timer;
|
|
||||||
}
|
|
||||||
Mpd.UpdateStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
applyToVisibleWindows(&BaseScreen::update);
|
|
||||||
|
|
||||||
if (isVisible(myPlaylist)
|
|
||||||
&& Timer.tv_sec == myPlaylist->Timer()+Config.playlist_disable_highlight_delay
|
|
||||||
&& myPlaylist->main().isHighlighted()
|
|
||||||
&& Config.playlist_disable_highlight_delay)
|
|
||||||
{
|
|
||||||
myPlaylist->main().setHighlighting(false);
|
|
||||||
myPlaylist->main().refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
Statusbar::tryRedraw();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Status::handleError(MPD::Connection * , int errorid, const char *msg, void *)
|
void Status::handleServerError(MPD::ServerError &e)
|
||||||
{
|
{
|
||||||
// for errorid:
|
if (e.code() == MPD_SERVER_ERROR_PERMISSION)
|
||||||
// - 0-7 bits define MPD_ERROR_* codes, compare them with (0xff & errorid)
|
|
||||||
// - 8-15 bits define MPD_SERVER_ERROR_* codes, compare them with (errorid >> 8)
|
|
||||||
if ((errorid >> 8) == MPD_SERVER_ERROR_PERMISSION)
|
|
||||||
{
|
{
|
||||||
wFooter->setGetStringHelper(0);
|
wFooter->setGetStringHelper(nullptr);
|
||||||
Statusbar::put() << "Password: ";
|
Statusbar::put() << "Password: ";
|
||||||
Mpd.SetPassword(wFooter->getString(-1, 0, 1));
|
Mpd.SetPassword(wFooter->getString(-1, 0, 1));
|
||||||
if (Mpd.SendPassword())
|
Mpd.SendPassword();
|
||||||
Statusbar::msg("Password accepted");
|
Statusbar::msg("Password accepted");
|
||||||
wFooter->setGetStringHelper(Statusbar::Helpers::getString);
|
wFooter->setGetStringHelper(Statusbar::Helpers::getString);
|
||||||
}
|
}
|
||||||
else if ((errorid >> 8) == MPD_SERVER_ERROR_NO_EXIST && myScreen == myBrowser)
|
else if (e.code() == MPD_SERVER_ERROR_NO_EXIST && myScreen == myBrowser)
|
||||||
{
|
{
|
||||||
myBrowser->GetDirectory(getParentDirectory(myBrowser->CurrentDir()));
|
myBrowser->GetDirectory(getParentDirectory(myBrowser->CurrentDir()));
|
||||||
myBrowser->refresh();
|
myBrowser->refresh();
|
||||||
}
|
}
|
||||||
else
|
Statusbar::msg("MPD: %s", e.what());
|
||||||
Statusbar::msg("MPD: %s", msg);
|
}
|
||||||
|
|
||||||
|
void Status::trace()
|
||||||
|
{
|
||||||
|
gettimeofday(&Timer, 0);
|
||||||
|
if (Mpd.Connected())
|
||||||
|
{
|
||||||
|
if (MpdStatus.playerState() == MPD::psPlay && Global::Timer.tv_sec > past.tv_sec)
|
||||||
|
{
|
||||||
|
// update elapsed time/bitrate of the current song
|
||||||
|
MpdStatus = Mpd.getStatus();
|
||||||
|
Status::Changes::elapsedTime();
|
||||||
|
wFooter->refresh();
|
||||||
|
past = Timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
applyToVisibleWindows(&BaseScreen::update);
|
||||||
|
|
||||||
|
if (isVisible(myPlaylist)
|
||||||
|
&& Timer.tv_sec == myPlaylist->Timer()+Config.playlist_disable_highlight_delay
|
||||||
|
&& myPlaylist->main().isHighlighted()
|
||||||
|
&& Config.playlist_disable_highlight_delay)
|
||||||
|
{
|
||||||
|
myPlaylist->main().setHighlighting(false);
|
||||||
|
myPlaylist->main().refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
Statusbar::tryRedraw();
|
||||||
|
|
||||||
|
Mpd.idle();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Status::Changes::playlist()
|
void Status::Changes::playlist()
|
||||||
{
|
{
|
||||||
myPlaylist->main().clearSearchResults();
|
myPlaylist->main().clearSearchResults();
|
||||||
withUnfilteredMenuReapplyFilter(myPlaylist->main(), []() {
|
withUnfilteredMenuReapplyFilter(myPlaylist->main(), []() {
|
||||||
size_t playlist_length = Mpd.GetPlaylistLength();
|
size_t playlist_length = MpdStatus.playlistLength();
|
||||||
if (playlist_length < myPlaylist->main().size())
|
if (playlist_length < myPlaylist->main().size())
|
||||||
{
|
{
|
||||||
auto it = myPlaylist->main().begin()+playlist_length;
|
auto it = myPlaylist->main().begin()+playlist_length;
|
||||||
@@ -142,7 +142,7 @@ void Status::Changes::playlist()
|
|||||||
myPlaylist->main().resizeList(playlist_length);
|
myPlaylist->main().resizeList(playlist_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
Mpd.GetPlaylistChanges(Mpd.GetOldPlaylistID(), [](MPD::Song &&s) {
|
Mpd.GetPlaylistChanges(myPlaylist->Version, [](MPD::Song &&s) {
|
||||||
size_t pos = s.getPosition();
|
size_t pos = s.getPosition();
|
||||||
if (pos < myPlaylist->main().size())
|
if (pos < myPlaylist->main().size())
|
||||||
{
|
{
|
||||||
@@ -155,9 +155,11 @@ void Status::Changes::playlist()
|
|||||||
myPlaylist->main().addItem(s);
|
myPlaylist->main().addItem(s);
|
||||||
myPlaylist->registerHash(s.getHash());
|
myPlaylist->registerHash(s.getHash());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
myPlaylist->Version = MpdStatus.playlistVersion();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (Mpd.isPlaying())
|
if (MpdStatus.playerState() != MPD::psStop)
|
||||||
drawTitle(myPlaylist->nowPlayingSong());
|
drawTitle(myPlaylist->nowPlayingSong());
|
||||||
|
|
||||||
Playlist::ReloadTotalLength = true;
|
Playlist::ReloadTotalLength = true;
|
||||||
@@ -201,7 +203,7 @@ void Status::Changes::database()
|
|||||||
|
|
||||||
void Status::Changes::playerState()
|
void Status::Changes::playerState()
|
||||||
{
|
{
|
||||||
MPD::PlayerState state = Mpd.GetState();
|
MPD::PlayerState state = MpdStatus.playerState();
|
||||||
switch (state)
|
switch (state)
|
||||||
{
|
{
|
||||||
case MPD::psUnknown:
|
case MPD::psUnknown:
|
||||||
@@ -214,8 +216,6 @@ void Status::Changes::playerState()
|
|||||||
drawTitle(myPlaylist->nowPlayingSong());
|
drawTitle(myPlaylist->nowPlayingSong());
|
||||||
player_state = Config.new_design ? "[playing]" : "Playing: ";
|
player_state = Config.new_design ? "[playing]" : "Playing: ";
|
||||||
Playlist::ReloadRemaining = true;
|
Playlist::ReloadRemaining = true;
|
||||||
if (Mpd.GetOldState() == MPD::psStop) // show track info in status immediately
|
|
||||||
elapsedTime();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MPD::psPause:
|
case MPD::psPause:
|
||||||
@@ -272,7 +272,7 @@ void Status::Changes::songID()
|
|||||||
playing_song_scroll_begin = 0;
|
playing_song_scroll_begin = 0;
|
||||||
first_line_scroll_begin = 0;
|
first_line_scroll_begin = 0;
|
||||||
second_line_scroll_begin = 0;
|
second_line_scroll_begin = 0;
|
||||||
if (Mpd.isPlaying())
|
if (MpdStatus.playerState() != MPD::psStop)
|
||||||
{
|
{
|
||||||
GNUC_UNUSED int res;
|
GNUC_UNUSED int res;
|
||||||
if (!Config.execute_on_song_change.empty())
|
if (!Config.execute_on_song_change.empty())
|
||||||
@@ -286,18 +286,17 @@ void Status::Changes::songID()
|
|||||||
drawTitle(myPlaylist->nowPlayingSong());
|
drawTitle(myPlaylist->nowPlayingSong());
|
||||||
|
|
||||||
if (Config.autocenter_mode && !myPlaylist->main().isFiltered())
|
if (Config.autocenter_mode && !myPlaylist->main().isFiltered())
|
||||||
myPlaylist->main().highlight(Mpd.GetCurrentSongPos());
|
myPlaylist->main().highlight(MpdStatus.currentSongPosition());
|
||||||
|
|
||||||
if (Config.now_playing_lyrics && isVisible(myLyrics) && myLyrics->previousScreen() == myPlaylist)
|
if (Config.now_playing_lyrics && isVisible(myLyrics) && myLyrics->previousScreen() == myPlaylist)
|
||||||
myLyrics->ReloadNP = 1;
|
myLyrics->ReloadNP = 1;
|
||||||
|
|
||||||
elapsedTime();
|
|
||||||
}
|
}
|
||||||
|
elapsedTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Status::Changes::elapsedTime()
|
void Status::Changes::elapsedTime()
|
||||||
{
|
{
|
||||||
if (!Mpd.isPlaying())
|
if (MpdStatus.playerState() == MPD::psStop)
|
||||||
{
|
{
|
||||||
if (Statusbar::isUnlocked() && Config.statusbar_visibility)
|
if (Statusbar::isUnlocked() && Config.statusbar_visibility)
|
||||||
*wFooter << NC::XY(0, 1) << wclrtoeol;
|
*wFooter << NC::XY(0, 1) << wclrtoeol;
|
||||||
@@ -313,20 +312,20 @@ void Status::Changes::elapsedTime()
|
|||||||
if (Config.display_remaining_time)
|
if (Config.display_remaining_time)
|
||||||
{
|
{
|
||||||
tracklength = "-";
|
tracklength = "-";
|
||||||
tracklength += MPD::Song::ShowTime(Mpd.GetTotalTime()-Mpd.GetElapsedTime());
|
tracklength += MPD::Song::ShowTime(MpdStatus.totalTime()-MpdStatus.elapsedTime());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
tracklength = MPD::Song::ShowTime(Mpd.GetElapsedTime());
|
tracklength = MPD::Song::ShowTime(MpdStatus.elapsedTime());
|
||||||
if (Mpd.GetTotalTime())
|
if (MpdStatus.totalTime())
|
||||||
{
|
{
|
||||||
tracklength += "/";
|
tracklength += "/";
|
||||||
tracklength += MPD::Song::ShowTime(Mpd.GetTotalTime());
|
tracklength += MPD::Song::ShowTime(MpdStatus.totalTime());
|
||||||
}
|
}
|
||||||
// bitrate here doesn't look good, but it can be moved somewhere else later
|
// bitrate here doesn't look good, but it can be moved somewhere else later
|
||||||
if (Config.display_bitrate && Mpd.GetBitrate())
|
if (Config.display_bitrate && MpdStatus.kbps())
|
||||||
{
|
{
|
||||||
tracklength += " ";
|
tracklength += " ";
|
||||||
tracklength += boost::lexical_cast<std::string>(Mpd.GetBitrate());
|
tracklength += boost::lexical_cast<std::string>(MpdStatus.kbps());
|
||||||
tracklength += " kbps";
|
tracklength += " kbps";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,29 +356,29 @@ void Status::Changes::elapsedTime()
|
|||||||
}
|
}
|
||||||
else if (Statusbar::isUnlocked() && Config.statusbar_visibility)
|
else if (Statusbar::isUnlocked() && Config.statusbar_visibility)
|
||||||
{
|
{
|
||||||
if (Config.display_bitrate && Mpd.GetBitrate())
|
if (Config.display_bitrate && MpdStatus.kbps())
|
||||||
{
|
{
|
||||||
tracklength += " [";
|
tracklength += " [";
|
||||||
tracklength += boost::lexical_cast<std::string>(Mpd.GetBitrate());
|
tracklength += boost::lexical_cast<std::string>(MpdStatus.kbps());
|
||||||
tracklength += " kbps]";
|
tracklength += " kbps]";
|
||||||
}
|
}
|
||||||
tracklength += " [";
|
tracklength += " [";
|
||||||
if (Mpd.GetTotalTime())
|
if (MpdStatus.totalTime())
|
||||||
{
|
{
|
||||||
if (Config.display_remaining_time)
|
if (Config.display_remaining_time)
|
||||||
{
|
{
|
||||||
tracklength += "-";
|
tracklength += "-";
|
||||||
tracklength += MPD::Song::ShowTime(Mpd.GetTotalTime()-Mpd.GetElapsedTime());
|
tracklength += MPD::Song::ShowTime(MpdStatus.totalTime()-MpdStatus.elapsedTime());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
tracklength += MPD::Song::ShowTime(Mpd.GetElapsedTime());
|
tracklength += MPD::Song::ShowTime(MpdStatus.elapsedTime());
|
||||||
tracklength += "/";
|
tracklength += "/";
|
||||||
tracklength += MPD::Song::ShowTime(Mpd.GetTotalTime());
|
tracklength += MPD::Song::ShowTime(MpdStatus.totalTime());
|
||||||
tracklength += "]";
|
tracklength += "]";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tracklength += MPD::Song::ShowTime(Mpd.GetElapsedTime());
|
tracklength += MPD::Song::ShowTime(MpdStatus.elapsedTime());
|
||||||
tracklength += "]";
|
tracklength += "]";
|
||||||
}
|
}
|
||||||
NC::WBuffer np_song;
|
NC::WBuffer np_song;
|
||||||
@@ -389,44 +388,50 @@ void Status::Changes::elapsedTime()
|
|||||||
*wFooter << NC::Format::Bold << NC::XY(wFooter->getWidth()-tracklength.length(), 1) << tracklength << NC::Format::NoBold;
|
*wFooter << NC::Format::Bold << NC::XY(wFooter->getWidth()-tracklength.length(), 1) << tracklength << NC::Format::NoBold;
|
||||||
}
|
}
|
||||||
if (Progressbar::isUnlocked())
|
if (Progressbar::isUnlocked())
|
||||||
Progressbar::draw(Mpd.GetElapsedTime(), Mpd.GetTotalTime());
|
Progressbar::draw(MpdStatus.elapsedTime(), MpdStatus.totalTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Status::Changes::repeat()
|
void Status::Changes::repeat(bool show_msg)
|
||||||
{
|
{
|
||||||
mpd_repeat = Mpd.GetRepeat() ? 'r' : 0;
|
mpd_repeat = MpdStatus.repeat() ? 'r' : 0;
|
||||||
Statusbar::msg("Repeat mode is %s", !mpd_repeat ? "off" : "on");
|
if (show_msg)
|
||||||
|
Statusbar::msg("Repeat mode is %s", !mpd_repeat ? "off" : "on");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Status::Changes::random()
|
void Status::Changes::random(bool show_msg)
|
||||||
{
|
{
|
||||||
mpd_random = Mpd.GetRandom() ? 'z' : 0;
|
mpd_random = MpdStatus.random() ? 'z' : 0;
|
||||||
Statusbar::msg("Random mode is %s", !mpd_random ? "off" : "on");
|
if (show_msg)
|
||||||
|
Statusbar::msg("Random mode is %s", !mpd_random ? "off" : "on");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Status::Changes::single()
|
void Status::Changes::single(bool show_msg)
|
||||||
{
|
{
|
||||||
mpd_single = Mpd.GetSingle() ? 's' : 0;
|
mpd_single = MpdStatus.single() ? 's' : 0;
|
||||||
Statusbar::msg("Single mode is %s", !mpd_single ? "off" : "on");
|
if (show_msg)
|
||||||
|
Statusbar::msg("Single mode is %s", !mpd_single ? "off" : "on");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Status::Changes::consume()
|
void Status::Changes::consume(bool show_msg)
|
||||||
{
|
{
|
||||||
mpd_consume = Mpd.GetConsume() ? 'c' : 0;
|
mpd_consume = MpdStatus.consume() ? 'c' : 0;
|
||||||
Statusbar::msg("Consume mode is %s", !mpd_consume ? "off" : "on");
|
if (show_msg)
|
||||||
|
Statusbar::msg("Consume mode is %s", !mpd_consume ? "off" : "on");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Status::Changes::crossfade()
|
void Status::Changes::crossfade(bool show_msg)
|
||||||
{
|
{
|
||||||
int crossfade = Mpd.GetCrossfade();
|
int crossfade = MpdStatus.crossfade();
|
||||||
mpd_crossfade = crossfade ? 'x' : 0;
|
mpd_crossfade = crossfade ? 'x' : 0;
|
||||||
Statusbar::msg("Crossfade set to %d seconds", crossfade);
|
if (show_msg)
|
||||||
|
Statusbar::msg("Crossfade set to %d seconds", crossfade);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Status::Changes::dbUpdateState()
|
void Status::Changes::dbUpdateState(bool show_msg)
|
||||||
{
|
{
|
||||||
mpd_db_updating = Mpd.GetDBIsUpdating() ? 'U' : 0;
|
mpd_db_updating = MpdStatus.updateID() ? 'U' : 0;
|
||||||
Statusbar::msg(Mpd.GetDBIsUpdating() ? "Database update started" : "Database update finished");
|
if (show_msg)
|
||||||
|
Statusbar::msg(MpdStatus.updateID() ? "Database update started" : "Database update finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Status::Changes::flags()
|
void Status::Changes::flags()
|
||||||
@@ -494,7 +499,7 @@ void Status::Changes::mixer()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
VolumeState = Config.new_design ? " Vol: " : " Volume: ";
|
VolumeState = Config.new_design ? " Vol: " : " Volume: ";
|
||||||
int volume = Mpd.GetVolume();
|
int volume = MpdStatus.volume();
|
||||||
if (volume < 0)
|
if (volume < 0)
|
||||||
VolumeState += "n/a";
|
VolumeState += "n/a";
|
||||||
else
|
else
|
||||||
@@ -515,41 +520,50 @@ void Status::Changes::outputs()
|
|||||||
# endif // ENABLE_OUTPUTS
|
# endif // ENABLE_OUTPUTS
|
||||||
}
|
}
|
||||||
|
|
||||||
void Status::update(MPD::Connection *, MPD::StatusChanges changes, void *)
|
void Status::update(int event)
|
||||||
{
|
{
|
||||||
if (changes.Playlist)
|
MPD::Status old = MpdStatus;
|
||||||
Changes::playlist();
|
MpdStatus = Mpd.getStatus();
|
||||||
if (changes.StoredPlaylists)
|
|
||||||
Changes::storedPlaylists();
|
|
||||||
if (changes.Database)
|
|
||||||
Changes::database();
|
|
||||||
if (changes.PlayerState)
|
|
||||||
Changes::playerState();
|
|
||||||
if (changes.SongID)
|
|
||||||
Changes::songID();
|
|
||||||
if (changes.ElapsedTime)
|
|
||||||
Changes::elapsedTime();
|
|
||||||
if (changes.Repeat)
|
|
||||||
Changes::repeat();
|
|
||||||
if (changes.Random)
|
|
||||||
Changes::random();
|
|
||||||
if (changes.Single)
|
|
||||||
Changes::single();
|
|
||||||
if (changes.Consume)
|
|
||||||
Changes::consume();
|
|
||||||
if (changes.Crossfade)
|
|
||||||
Changes::crossfade();
|
|
||||||
if (changes.DBUpdating)
|
|
||||||
Changes::dbUpdateState();
|
|
||||||
if (changes.StatusFlags)
|
|
||||||
Changes::flags();
|
|
||||||
if (changes.Volume)
|
|
||||||
Changes::mixer();
|
|
||||||
if (changes.Outputs)
|
|
||||||
Changes::outputs();
|
|
||||||
|
|
||||||
if (changes.PlayerState || (changes.ElapsedTime && (!Config.new_design || Mpd.GetState() == MPD::psPlay)))
|
if (event & MPD_IDLE_DATABASE)
|
||||||
|
Changes::database();
|
||||||
|
if (event & MPD_IDLE_STORED_PLAYLIST)
|
||||||
|
Changes::storedPlaylists();
|
||||||
|
if (event & MPD_IDLE_PLAYLIST)
|
||||||
|
Changes::playlist();
|
||||||
|
if (event & MPD_IDLE_PLAYER)
|
||||||
|
{
|
||||||
|
Changes::playerState();
|
||||||
|
if (old.empty() || old.currentSongID() != MpdStatus.currentSongID())
|
||||||
|
Changes::songID();
|
||||||
|
}
|
||||||
|
if (event & MPD_IDLE_MIXER)
|
||||||
|
Changes::mixer();
|
||||||
|
if (event & MPD_IDLE_OUTPUT)
|
||||||
|
Changes::outputs();
|
||||||
|
if (event & (MPD_IDLE_UPDATE | MPD_IDLE_OPTIONS))
|
||||||
|
{
|
||||||
|
if (event & MPD_IDLE_UPDATE)
|
||||||
|
Changes::dbUpdateState(!old.empty());
|
||||||
|
if (event & MPD_IDLE_OPTIONS)
|
||||||
|
{
|
||||||
|
if (old.empty() || old.repeat() != MpdStatus.repeat())
|
||||||
|
Changes::repeat(!old.empty());
|
||||||
|
if (old.empty() || old.random() != MpdStatus.random())
|
||||||
|
Changes::random(!old.empty());
|
||||||
|
if (old.empty() || old.single() != MpdStatus.single())
|
||||||
|
Changes::single(!old.empty());
|
||||||
|
if (old.empty() || old.consume() != MpdStatus.consume())
|
||||||
|
Changes::consume(!old.empty());
|
||||||
|
if (old.empty() || old.crossfade() != MpdStatus.crossfade())
|
||||||
|
Changes::crossfade(!old.empty());
|
||||||
|
}
|
||||||
|
Changes::flags();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event & MPD_IDLE_PLAYER)
|
||||||
wFooter->refresh();
|
wFooter->refresh();
|
||||||
if (changes.Playlist || changes.Database || changes.PlayerState || changes.SongID)
|
|
||||||
|
if (event & (MPD_IDLE_PLAYLIST | MPD_IDLE_DATABASE | MPD_IDLE_PLAYER))
|
||||||
applyToVisibleWindows(&BaseScreen::refreshWindow);
|
applyToVisibleWindows(&BaseScreen::refreshWindow);
|
||||||
}
|
}
|
||||||
|
|||||||
20
src/status.h
20
src/status.h
@@ -26,11 +26,11 @@
|
|||||||
|
|
||||||
namespace Status {//
|
namespace Status {//
|
||||||
|
|
||||||
|
void handleClientError(MPD::ClientError &e);
|
||||||
|
void handleServerError(MPD::ServerError &e);
|
||||||
|
|
||||||
void trace();
|
void trace();
|
||||||
|
void update(int event);
|
||||||
void handleError(MPD::Connection * , int errorid, const char *msg, void *);
|
|
||||||
|
|
||||||
void update(MPD::Connection *, MPD::StatusChanges changes, void *);
|
|
||||||
|
|
||||||
namespace Changes {//
|
namespace Changes {//
|
||||||
|
|
||||||
@@ -40,12 +40,12 @@ void database();
|
|||||||
void playerState();
|
void playerState();
|
||||||
void songID();
|
void songID();
|
||||||
void elapsedTime();
|
void elapsedTime();
|
||||||
void repeat();
|
void repeat(bool show_msg);
|
||||||
void random();
|
void random(bool show_msg);
|
||||||
void single();
|
void single(bool show_msg);
|
||||||
void consume();
|
void consume(bool show_msg);
|
||||||
void crossfade();
|
void crossfade(bool show_msg);
|
||||||
void dbUpdateState();
|
void dbUpdateState(bool show_msg);
|
||||||
void flags();
|
void flags();
|
||||||
void mixer();
|
void mixer();
|
||||||
void outputs();
|
void outputs();
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ bool statusbarAllowUnlock = true;
|
|||||||
|
|
||||||
void showMessage(int time, const char *format, va_list list)
|
void showMessage(int time, const char *format, va_list list)
|
||||||
{
|
{
|
||||||
if (Global::ShowMessages && statusbarAllowUnlock)
|
if (statusbarAllowUnlock)
|
||||||
{
|
{
|
||||||
statusbarLockTime = Global::Timer;
|
statusbarLockTime = Global::Timer;
|
||||||
statusbarLockDelay = time;
|
statusbarLockDelay = time;
|
||||||
@@ -122,10 +122,10 @@ void Statusbar::unlock()
|
|||||||
else
|
else
|
||||||
progressbarBlockUpdate = false;
|
progressbarBlockUpdate = false;
|
||||||
}
|
}
|
||||||
if (!Mpd.isPlaying())
|
if (MpdStatus.playerState() == MPD::psStop)
|
||||||
{
|
{
|
||||||
if (Config.new_design)
|
if (Config.new_design)
|
||||||
Progressbar::draw(Mpd.GetElapsedTime(), Mpd.GetTotalTime());
|
Progressbar::draw(MpdStatus.elapsedTime(), MpdStatus.totalTime());
|
||||||
else
|
else
|
||||||
put() << wclrtoeol;
|
put() << wclrtoeol;
|
||||||
wFooter->refresh();
|
wFooter->refresh();
|
||||||
@@ -150,12 +150,12 @@ void Statusbar::tryRedraw()
|
|||||||
else
|
else
|
||||||
progressbarBlockUpdate = !statusbarAllowUnlock;
|
progressbarBlockUpdate = !statusbarAllowUnlock;
|
||||||
|
|
||||||
if (Mpd.GetState() != MPD::psPlay && !statusbarBlockUpdate && !progressbarBlockUpdate)
|
if (MpdStatus.playerState() != MPD::psStop && !statusbarBlockUpdate && !progressbarBlockUpdate)
|
||||||
{
|
{
|
||||||
if (Config.new_design)
|
if (Config.new_design)
|
||||||
Progressbar::draw(Mpd.GetElapsedTime(), Mpd.GetTotalTime());
|
Progressbar::draw(MpdStatus.elapsedTime(), MpdStatus.totalTime());
|
||||||
else
|
else
|
||||||
put() << wclrtoeol;
|
Status::Changes::elapsedTime();
|
||||||
wFooter->refresh();
|
wFooter->refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -185,7 +185,7 @@ void Statusbar::msg(int time, const char *format, ...)
|
|||||||
|
|
||||||
void Statusbar::Helpers::mpd()
|
void Statusbar::Helpers::mpd()
|
||||||
{
|
{
|
||||||
Mpd.OrderDataFetching();
|
Status::update(Mpd.noidle());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Statusbar::Helpers::getString(const std::wstring &)
|
bool Statusbar::Helpers::getString(const std::wstring &)
|
||||||
|
|||||||
@@ -57,8 +57,6 @@ Visualizer::Visualizer()
|
|||||||
m_fftw_output = static_cast<fftw_complex *>(fftw_malloc(sizeof(fftw_complex)*m_fftw_results));
|
m_fftw_output = static_cast<fftw_complex *>(fftw_malloc(sizeof(fftw_complex)*m_fftw_results));
|
||||||
m_fftw_plan = fftw_plan_dft_r2c_1d(m_samples, m_fftw_input, m_fftw_output, FFTW_ESTIMATE);
|
m_fftw_plan = fftw_plan_dft_r2c_1d(m_samples, m_fftw_input, m_fftw_output, FFTW_ESTIMATE);
|
||||||
# endif // HAVE_FFTW3_H
|
# endif // HAVE_FFTW3_H
|
||||||
|
|
||||||
FindOutputID();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Visualizer::switchTo()
|
void Visualizer::switchTo()
|
||||||
|
|||||||
Reference in New Issue
Block a user