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()
|
||||
{
|
||||
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 << "(host = " << Mpd.GetHostname() << ", port = " << Mpd.GetPort() << ")";
|
||||
std::cout << ": " << Mpd.GetErrorMessage() << std::endl;
|
||||
std::cout << ": " << e.what() << std::endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -341,13 +350,13 @@ void MouseEvent::run()
|
||||
&& m_mouse_event.y == LINES-(Config.statusbar_visibility ? 2 : 1)
|
||||
) // progressbar
|
||||
{
|
||||
if (!Mpd.isPlaying())
|
||||
if (MpdStatus.playerState() == MPD::psStop)
|
||||
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
|
||||
&& (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
|
||||
) // playing/paused
|
||||
{
|
||||
@@ -359,9 +368,9 @@ void MouseEvent::run()
|
||||
) // volume
|
||||
{
|
||||
if (m_mouse_event.bstate & BUTTON2_PRESSED)
|
||||
Mpd.SetVolume(Mpd.GetVolume()-2);
|
||||
Mpd.SetVolume(MpdStatus.volume()-2);
|
||||
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))
|
||||
myScreen->mouseButtonPressed(m_mouse_event);
|
||||
@@ -503,8 +512,8 @@ void ToggleInterface::run()
|
||||
Progressbar::unlock();
|
||||
Statusbar::unlock();
|
||||
resizeScreen(false);
|
||||
if (!Mpd.isPlaying())
|
||||
Status::Changes::mixer();
|
||||
Status::Changes::mixer();
|
||||
Status::Changes::elapsedTime();
|
||||
Statusbar::msg("User interface: %s", Config.new_design ? "Alternative" : "Classic");
|
||||
}
|
||||
|
||||
@@ -615,13 +624,13 @@ void SlaveScreen::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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -637,16 +646,16 @@ void DeletePlaylistItems::run()
|
||||
{
|
||||
Statusbar::msg("Deleting items...");
|
||||
auto delete_fun = std::bind(&MPD::Connection::Delete, _1, _2);
|
||||
if (deleteSelectedSongs(myPlaylist->main(), delete_fun))
|
||||
Statusbar::msg("Item(s) deleted");
|
||||
deleteSelectedSongs(myPlaylist->main(), delete_fun);
|
||||
Statusbar::msg("Item(s) deleted");
|
||||
}
|
||||
else if (myScreen->isActiveWindow(myPlaylistEditor->Content))
|
||||
{
|
||||
std::string playlist = myPlaylistEditor->Playlists.current().value();
|
||||
auto delete_fun = std::bind(&MPD::Connection::PlaylistDelete, _1, playlist, _2);
|
||||
Statusbar::msg("Deleting items...");
|
||||
if (deleteSelectedSongs(myPlaylistEditor->Content, delete_fun))
|
||||
Statusbar::msg("Item(s) deleted");
|
||||
deleteSelectedSongs(myPlaylistEditor->Content, delete_fun);
|
||||
Statusbar::msg("Item(s) deleted");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -730,8 +739,8 @@ void DeleteStoredPlaylist::run()
|
||||
Mpd.StartCommandsList();
|
||||
for (auto it = list.begin(); it != list.end(); ++it)
|
||||
Mpd.DeletePlaylist((*it)->value());
|
||||
if (Mpd.CommitCommandsList())
|
||||
Statusbar::msg("Playlist%s deleted", list.size() == 1 ? "" : "s");
|
||||
Mpd.CommitCommandsList();
|
||||
Statusbar::msg("Playlist%s deleted", list.size() == 1 ? "" : "s");
|
||||
}
|
||||
else
|
||||
Statusbar::msg("Aborted");
|
||||
@@ -739,7 +748,7 @@ void DeleteStoredPlaylist::run()
|
||||
|
||||
void ReplaySong::run()
|
||||
{
|
||||
if (Mpd.isPlaying())
|
||||
if (MpdStatus.playerState() != MPD::psStop)
|
||||
Mpd.Seek(0);
|
||||
}
|
||||
|
||||
@@ -779,29 +788,33 @@ void SavePlaylist::run()
|
||||
for (size_t i = 0; i < myPlaylist->main().size(); ++i)
|
||||
Mpd.AddToPlaylist(playlist_name, myPlaylist->main()[i].value());
|
||||
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
|
||||
{
|
||||
int result = Mpd.SavePlaylist(playlist_name);
|
||||
if (result == MPD_ERROR_SUCCESS)
|
||||
try
|
||||
{
|
||||
Mpd.SavePlaylist(playlist_name);
|
||||
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 (yes)
|
||||
if (e.code() == MPD_SERVER_ERROR_EXIST)
|
||||
{
|
||||
Mpd.DeletePlaylist(playlist_name);
|
||||
if (Mpd.SavePlaylist(playlist_name) == MPD_ERROR_SUCCESS)
|
||||
bool yes = askYesNoQuestion("Playlist \"" + playlist_name + "\" already exists, overwrite?", Status::trace);
|
||||
if (yes)
|
||||
{
|
||||
Mpd.DeletePlaylist(playlist_name);
|
||||
Mpd.SavePlaylist(playlist_name);
|
||||
Statusbar::msg("Playlist overwritten");
|
||||
}
|
||||
else
|
||||
Statusbar::msg("Aborted");
|
||||
if (myScreen == myPlaylist)
|
||||
myPlaylist->EnableHighlighting();
|
||||
}
|
||||
else
|
||||
Statusbar::msg("Aborted");
|
||||
if (myScreen == myPlaylist)
|
||||
myPlaylist->EnableHighlighting();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -964,7 +977,7 @@ void Add::run()
|
||||
|
||||
bool SeekForward::canBeRun() const
|
||||
{
|
||||
return Mpd.isPlaying() && Mpd.GetTotalTime() > 0;
|
||||
return MpdStatus.playerState() != MPD::psStop && MpdStatus.totalTime() > 0;
|
||||
}
|
||||
|
||||
void SeekForward::run()
|
||||
@@ -974,7 +987,7 @@ void SeekForward::run()
|
||||
|
||||
bool SeekBackward::canBeRun() const
|
||||
{
|
||||
return Mpd.isPlaying() && Mpd.GetTotalTime() > 0;
|
||||
return MpdStatus.playerState() != MPD::psStop && MpdStatus.totalTime() > 0;
|
||||
}
|
||||
|
||||
void SeekBackward::run()
|
||||
@@ -1079,8 +1092,10 @@ void TogglePlayingSongCentering::run()
|
||||
{
|
||||
Config.autocenter_mode = !Config.autocenter_mode;
|
||||
Statusbar::msg("Centering playing song: %s", Config.autocenter_mode ? "On" : "Off");
|
||||
if (Config.autocenter_mode && Mpd.isPlaying() && !myPlaylist->main().isFiltered())
|
||||
myPlaylist->main().highlight(Mpd.GetCurrentSongPos());
|
||||
if (Config.autocenter_mode
|
||||
&& MpdStatus.playerState() != MPD::psStop
|
||||
&& !myPlaylist->main().isFiltered())
|
||||
myPlaylist->main().highlight(MpdStatus.currentSongPosition());
|
||||
}
|
||||
|
||||
void UpdateDatabase::run()
|
||||
@@ -1100,13 +1115,13 @@ bool JumpToPlayingSong::canBeRun() const
|
||||
return ((myScreen == myPlaylist && !myPlaylist->isFiltered())
|
||||
|| myScreen == myBrowser
|
||||
|| myScreen == myLibrary)
|
||||
&& Mpd.isPlaying();
|
||||
&& MpdStatus.playerState() != MPD::psStop;
|
||||
}
|
||||
|
||||
void JumpToPlayingSong::run()
|
||||
{
|
||||
if (myScreen == myPlaylist)
|
||||
myPlaylist->main().highlight(Mpd.GetCurrentSongPos());
|
||||
myPlaylist->main().highlight(MpdStatus.currentSongPosition());
|
||||
else if (myScreen == myBrowser)
|
||||
{
|
||||
myBrowser->LocateSong(myPlaylist->nowPlayingSong());
|
||||
@@ -1120,7 +1135,7 @@ void JumpToPlayingSong::run()
|
||||
|
||||
void ToggleRepeat::run()
|
||||
{
|
||||
Mpd.SetRepeat(!Mpd.GetRepeat());
|
||||
Mpd.SetRepeat(!MpdStatus.repeat());
|
||||
}
|
||||
|
||||
void Shuffle::run()
|
||||
@@ -1130,7 +1145,7 @@ void Shuffle::run()
|
||||
|
||||
void ToggleRandom::run()
|
||||
{
|
||||
Mpd.SetRandom(!Mpd.GetRandom());
|
||||
Mpd.SetRandom(!MpdStatus.random());
|
||||
}
|
||||
|
||||
bool StartSearching::canBeRun() const
|
||||
@@ -1175,17 +1190,17 @@ void SaveTagChanges::run()
|
||||
|
||||
void ToggleSingle::run()
|
||||
{
|
||||
Mpd.SetSingle(!Mpd.GetSingle());
|
||||
Mpd.SetSingle(!MpdStatus.single());
|
||||
}
|
||||
|
||||
void ToggleConsume::run()
|
||||
{
|
||||
Mpd.SetConsume(!Mpd.GetConsume());
|
||||
Mpd.SetConsume(!MpdStatus.consume());
|
||||
}
|
||||
|
||||
void ToggleCrossfade::run()
|
||||
{
|
||||
Mpd.SetCrossfade(Mpd.GetCrossfade() ? 0 : Config.crossfade_time);
|
||||
Mpd.SetCrossfade(MpdStatus.crossfade() ? 0 : Config.crossfade_time);
|
||||
}
|
||||
|
||||
void SetCrossfade::run()
|
||||
@@ -1215,8 +1230,8 @@ void SetVolume::run()
|
||||
int volume = boost::lexical_cast<int>(strvolume);
|
||||
if (volume >= 0 && volume <= 100)
|
||||
{
|
||||
if (Mpd.SetVolume(volume))
|
||||
Statusbar::msg("Volume set to %d%%", volume);
|
||||
Mpd.SetVolume(volume);
|
||||
Statusbar::msg("Volume set to %d%%", volume);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1451,13 +1466,11 @@ void EditPlaylistName::run()
|
||||
Statusbar::unlock();
|
||||
if (!new_name.empty() && new_name != old_name)
|
||||
{
|
||||
if (Mpd.Rename(old_name, new_name))
|
||||
{
|
||||
const char msg[] = "Playlist renamed to \"%ls\"";
|
||||
Statusbar::msg(msg, wideShorten(ToWString(new_name), COLS-const_strlen(msg)).c_str());
|
||||
if (!myBrowser->isLocal())
|
||||
myBrowser->GetDirectory("/");
|
||||
}
|
||||
Mpd.Rename(old_name, new_name);
|
||||
const char msg[] = "Playlist renamed to \"%ls\"";
|
||||
Statusbar::msg(msg, wideShorten(ToWString(new_name), COLS-const_strlen(msg)).c_str());
|
||||
if (!myBrowser->isLocal())
|
||||
myBrowser->GetDirectory("/");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1562,7 +1575,7 @@ void JumpToTagEditor::run()
|
||||
|
||||
bool JumpToPositionInSong::canBeRun() const
|
||||
{
|
||||
return Mpd.isPlaying() && Mpd.GetTotalTime() > 0;
|
||||
return MpdStatus.playerState() != MPD::psStop && MpdStatus.totalTime() > 0;
|
||||
}
|
||||
|
||||
void JumpToPositionInSong::run()
|
||||
@@ -1579,12 +1592,12 @@ void JumpToPositionInSong::run()
|
||||
if (position.empty())
|
||||
return;
|
||||
|
||||
int newpos = 0;
|
||||
unsigned newpos = 0;
|
||||
if (position.find(':') != std::string::npos) // probably time in mm:ss
|
||||
{
|
||||
newpos = boost::lexical_cast<int>(position)*60
|
||||
+ boost::lexical_cast<int>(position.substr(position.find(':')+1));
|
||||
if (newpos >= 0 && newpos <= Mpd.GetTotalTime())
|
||||
if (newpos <= MpdStatus.totalTime())
|
||||
Mpd.Seek(newpos);
|
||||
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());
|
||||
@@ -1592,7 +1605,7 @@ void JumpToPositionInSong::run()
|
||||
else if (position.find('s') != std::string::npos) // probably position in seconds
|
||||
{
|
||||
newpos = boost::lexical_cast<int>(position);
|
||||
if (newpos >= 0 && newpos <= Mpd.GetTotalTime())
|
||||
if (newpos <= MpdStatus.totalTime())
|
||||
Mpd.Seek(newpos);
|
||||
else
|
||||
Statusbar::msg("Out of bounds, 0-%d possible for seconds, %d given", s.getDuration(), newpos);
|
||||
@@ -1600,8 +1613,8 @@ void JumpToPositionInSong::run()
|
||||
else
|
||||
{
|
||||
newpos = boost::lexical_cast<int>(position);
|
||||
if (newpos >= 0 && newpos <= 100)
|
||||
Mpd.Seek(Mpd.GetTotalTime()*newpos/100.0);
|
||||
if (newpos <= 100)
|
||||
Mpd.Seek(MpdStatus.totalTime()*newpos/100.0);
|
||||
else
|
||||
Statusbar::msg("Out of bounds, 0-100 possible for %%, %d given", newpos);
|
||||
}
|
||||
@@ -1689,8 +1702,8 @@ void CropMainPlaylist::run()
|
||||
if (yes)
|
||||
{
|
||||
Statusbar::msg("Cropping playlist...");
|
||||
if (cropPlaylist(myPlaylist->main(), std::bind(&MPD::Connection::Delete, _1, _2)))
|
||||
Statusbar::msg("Cropping playlist...");
|
||||
cropPlaylist(myPlaylist->main(), std::bind(&MPD::Connection::Delete, _1, _2));
|
||||
Statusbar::msg("Cropping playlist...");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1710,8 +1723,8 @@ void CropPlaylist::run()
|
||||
{
|
||||
auto delete_fun = std::bind(&MPD::Connection::PlaylistDelete, _1, playlist, _2);
|
||||
Statusbar::msg("Cropping playlist \"%s\"...", playlist.c_str());
|
||||
if (cropPlaylist(myPlaylistEditor->Content, delete_fun))
|
||||
Statusbar::msg("Playlist \"%s\" cropped", playlist.c_str());
|
||||
cropPlaylist(myPlaylistEditor->Content, delete_fun);
|
||||
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 clear_fun = std::bind(&MPD::Connection::ClearMainPlaylist, _1);
|
||||
Statusbar::msg("Deleting items...");
|
||||
if (clearPlaylist(myPlaylist->main(), delete_fun, clear_fun))
|
||||
Statusbar::msg("Items deleted");
|
||||
clearPlaylist(myPlaylist->main(), delete_fun, clear_fun);
|
||||
Statusbar::msg("Items deleted");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1747,8 +1760,8 @@ void ClearPlaylist::run()
|
||||
auto delete_fun = std::bind(&MPD::Connection::PlaylistDelete, _1, playlist, _2);
|
||||
auto clear_fun = std::bind(&MPD::Connection::ClearPlaylist, _1, playlist);
|
||||
Statusbar::msg("Deleting items from \"%s\"...", playlist.c_str());
|
||||
if (clearPlaylist(myPlaylistEditor->Content, delete_fun, clear_fun))
|
||||
Statusbar::msg("Items deleted from \"%s\"", playlist.c_str());
|
||||
clearPlaylist(myPlaylistEditor->Content, delete_fun, clear_fun);
|
||||
Statusbar::msg("Items deleted from \"%s\"", playlist.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2578,7 +2591,7 @@ void seek()
|
||||
using Global::Timer;
|
||||
using Global::SeekingInProgress;
|
||||
|
||||
if (!Mpd.GetTotalTime())
|
||||
if (!MpdStatus.totalTime())
|
||||
{
|
||||
Statusbar::msg("Unknown item length");
|
||||
return;
|
||||
@@ -2587,7 +2600,7 @@ void seek()
|
||||
Progressbar::lock();
|
||||
Statusbar::lock();
|
||||
|
||||
int songpos = Mpd.GetElapsedTime();
|
||||
unsigned songpos = MpdStatus.elapsedTime();
|
||||
timeval t = Timer;
|
||||
|
||||
int old_timeout = wFooter->getTimeout();
|
||||
@@ -2602,7 +2615,7 @@ void seek()
|
||||
Status::trace();
|
||||
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);
|
||||
auto k = Bindings.get(input);
|
||||
@@ -2611,20 +2624,17 @@ void seek()
|
||||
auto a = k.first->action();
|
||||
if (a == seekForward)
|
||||
{
|
||||
if (songpos < Mpd.GetTotalTime())
|
||||
{
|
||||
songpos += howmuch;
|
||||
if (songpos > Mpd.GetTotalTime())
|
||||
songpos = Mpd.GetTotalTime();
|
||||
}
|
||||
if (songpos < MpdStatus.totalTime())
|
||||
songpos = std::min(songpos + howmuch, MpdStatus.totalTime());
|
||||
}
|
||||
else if (a == seekBackward)
|
||||
{
|
||||
if (songpos > 0)
|
||||
{
|
||||
songpos -= howmuch;
|
||||
if (songpos < 0)
|
||||
if (songpos < howmuch)
|
||||
songpos = 0;
|
||||
else
|
||||
songpos -= howmuch;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -2637,12 +2647,12 @@ void seek()
|
||||
if (Config.display_remaining_time)
|
||||
{
|
||||
tracklength = "-";
|
||||
tracklength += MPD::Song::ShowTime(Mpd.GetTotalTime()-songpos);
|
||||
tracklength += MPD::Song::ShowTime(MpdStatus.totalTime()-songpos);
|
||||
}
|
||||
else
|
||||
tracklength = MPD::Song::ShowTime(songpos);
|
||||
tracklength += "/";
|
||||
tracklength += MPD::Song::ShowTime(Mpd.GetTotalTime());
|
||||
tracklength += MPD::Song::ShowTime(MpdStatus.totalTime());
|
||||
*wHeader << NC::XY(0, 0) << tracklength << " ";
|
||||
wHeader->refresh();
|
||||
}
|
||||
@@ -2652,17 +2662,17 @@ void seek()
|
||||
if (Config.display_remaining_time)
|
||||
{
|
||||
tracklength += "-";
|
||||
tracklength += MPD::Song::ShowTime(Mpd.GetTotalTime()-songpos);
|
||||
tracklength += MPD::Song::ShowTime(MpdStatus.totalTime()-songpos);
|
||||
}
|
||||
else
|
||||
tracklength += MPD::Song::ShowTime(songpos);
|
||||
tracklength += "/";
|
||||
tracklength += MPD::Song::ShowTime(Mpd.GetTotalTime());
|
||||
tracklength += MPD::Song::ShowTime(MpdStatus.totalTime());
|
||||
tracklength += "]";
|
||||
*wFooter << NC::XY(wFooter->getWidth()-tracklength.length(), 1) << tracklength;
|
||||
}
|
||||
*wFooter << NC::Format::NoBold;
|
||||
Progressbar::draw(songpos, Mpd.GetTotalTime());
|
||||
Progressbar::draw(songpos, MpdStatus.totalTime());
|
||||
wFooter->refresh();
|
||||
}
|
||||
SeekingInProgress = false;
|
||||
|
||||
@@ -74,9 +74,6 @@ Browser::Browser() : itsBrowseLocally(0), itsScrollBeginning(0), itsBrowsedDir("
|
||||
w.setSelectedPrefix(Config.selected_item_prefix);
|
||||
w.setSelectedSuffix(Config.selected_item_suffix);
|
||||
w.setItemDisplayer(std::bind(Display::Items, _1, proxySongList()));
|
||||
|
||||
if (SupportedExtensions.empty())
|
||||
Mpd.GetSupportedExtensions(SupportedExtensions);
|
||||
}
|
||||
|
||||
void Browser::resize()
|
||||
@@ -136,11 +133,9 @@ void Browser::enterPressed()
|
||||
}
|
||||
case itPlaylist:
|
||||
{
|
||||
if (Mpd.LoadPlaylist(item.name))
|
||||
{
|
||||
Statusbar::msg("Playlist \"%s\" loaded", item.name.c_str());
|
||||
myPlaylist->PlayNewlyAddedSongs();
|
||||
}
|
||||
Mpd.LoadPlaylist(item.name);
|
||||
Statusbar::msg("Playlist \"%s\" loaded", item.name.c_str());
|
||||
myPlaylist->PlayNewlyAddedSongs();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -168,7 +163,6 @@ void Browser::spacePressed()
|
||||
{
|
||||
case itDirectory:
|
||||
{
|
||||
bool result;
|
||||
# ifndef WIN32
|
||||
if (isLocal())
|
||||
{
|
||||
@@ -179,13 +173,12 @@ void Browser::spacePressed()
|
||||
list.reserve(items.size());
|
||||
for (MPD::ItemList::const_iterator it = items.begin(); it != items.end(); ++it)
|
||||
list.push_back(*it->song);
|
||||
result = addSongsToPlaylist(list, false, -1);
|
||||
addSongsToPlaylist(list, false, -1);
|
||||
}
|
||||
else
|
||||
# endif // !WIN32
|
||||
result = Mpd.Add(item.name);
|
||||
if (result)
|
||||
Statusbar::msg("Directory \"%s\" added", item.name.c_str());
|
||||
Mpd.Add(item.name);
|
||||
Statusbar::msg("Directory \"%s\" added", item.name.c_str());
|
||||
break;
|
||||
}
|
||||
case itSong:
|
||||
@@ -195,8 +188,8 @@ void Browser::spacePressed()
|
||||
}
|
||||
case itPlaylist:
|
||||
{
|
||||
if (Mpd.LoadPlaylist(item.name))
|
||||
Statusbar::msg("Playlist \"%s\" loaded", item.name.c_str());
|
||||
Mpd.LoadPlaylist(item.name);
|
||||
Statusbar::msg("Playlist \"%s\" loaded", item.name.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -363,6 +356,12 @@ MPD::SongList Browser::getSelectedSongs()
|
||||
return result;
|
||||
}
|
||||
|
||||
void Browser::fetchSupportedExtensions()
|
||||
{
|
||||
SupportedExtensions.clear();
|
||||
Mpd.GetSupportedExtensions(SupportedExtensions);
|
||||
}
|
||||
|
||||
void Browser::LocateSong(const MPD::Song &s)
|
||||
{
|
||||
if (s.getDirectory().empty())
|
||||
@@ -580,7 +579,7 @@ bool Browser::deleteItem(const MPD::Item &item)
|
||||
|
||||
// playlist created by mpd
|
||||
if (!isLocal() && item.type == itPlaylist && CurrentDir() == "/")
|
||||
return Mpd.DeletePlaylist(item.name);
|
||||
Mpd.DeletePlaylist(item.name);
|
||||
|
||||
std::string path;
|
||||
if (!isLocal())
|
||||
|
||||
@@ -65,6 +65,8 @@ struct Browser: Screen<NC::Menu<MPD::Item>>, Filterable, HasSongs, Searchable, T
|
||||
// private members
|
||||
const std::string &CurrentDir() { return itsBrowsedDir; }
|
||||
|
||||
void fetchSupportedExtensions();
|
||||
|
||||
bool isLocal() { return itsBrowseLocally; }
|
||||
void LocateSong(const MPD::Song &);
|
||||
void GetDirectory(std::string, std::string = "/");
|
||||
|
||||
@@ -117,13 +117,11 @@ void ParseArgv(int argc, char **argv)
|
||||
<< " -s, --screen <name> specify the startup screen\n"
|
||||
<< " -?, --help show help message\n"
|
||||
<< " -v, --version display version information\n"
|
||||
<< " --now-playing display now playing song [" << now_playing_format << "]\n"
|
||||
;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (!Actions::connectToMPD())
|
||||
exit(1);
|
||||
Actions::connectToMPD();
|
||||
|
||||
if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "--screen"))
|
||||
{
|
||||
@@ -164,34 +162,6 @@ void ParseArgv(int argc, char **argv)
|
||||
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"))
|
||||
{
|
||||
// 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;
|
||||
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;
|
||||
|
||||
int song_pos = menu.isFiltered() ? s.getPosition() : drawn_pos;
|
||||
is_now_playing = Mpd.isPlaying() && myPlaylist->isActiveWindow(menu)
|
||||
&& song_pos == Mpd.GetCurrentSongPos();
|
||||
is_now_playing = MpdStatus.playerState() != MPD::psStop && myPlaylist->isActiveWindow(menu)
|
||||
&& song_pos == MpdStatus.currentSongPosition();
|
||||
if (is_now_playing)
|
||||
menu << Config.now_playing_prefix;
|
||||
}
|
||||
|
||||
@@ -24,8 +24,6 @@
|
||||
#include <string>
|
||||
#include "gcc.h"
|
||||
|
||||
#define Error(msg) std::cerr << "ncmpcpp: " << msg;
|
||||
|
||||
void FatalError(const std::string &msg) GNUC_NORETURN;
|
||||
|
||||
#endif // NCMPCPP_ERROR_H
|
||||
|
||||
@@ -49,9 +49,6 @@ extern size_t MainStartY;
|
||||
// height of main window
|
||||
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
|
||||
extern bool SeekingInProgress;
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ bool addSongToPlaylist(const MPD::Song &s, bool play, size_t position)
|
||||
}
|
||||
else
|
||||
{
|
||||
position = std::min(position, Mpd.GetPlaylistLength());
|
||||
position = std::min(position, myPlaylist->main().size());
|
||||
int id = Mpd.AddSong(s, position);
|
||||
if (id >= 0)
|
||||
{
|
||||
@@ -64,18 +64,18 @@ bool addSongToPlaylist(const MPD::Song &s, bool play, size_t position)
|
||||
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())
|
||||
return false;
|
||||
position = std::min(position, Mpd.GetPlaylistLength());
|
||||
return;
|
||||
position = std::min(position, myPlaylist->main().size());
|
||||
Mpd.StartCommandsList();
|
||||
for (auto s = list.rbegin(); s != list.rend(); ++s)
|
||||
if (Mpd.AddSong(*s, position) < 0)
|
||||
break;
|
||||
if (play)
|
||||
Mpd.Play(position);
|
||||
return Mpd.CommitCommandsList();
|
||||
Mpd.CommitCommandsList();
|
||||
}
|
||||
|
||||
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();
|
||||
for (auto it = list.begin(); it != list.end(); ++it)
|
||||
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);
|
||||
}
|
||||
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);
|
||||
(*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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -186,24 +184,22 @@ void moveSelectedItemsDown(NC::Menu<MPD::Song> &m, F swap_fun)
|
||||
Mpd.StartCommandsList();
|
||||
for (auto it = list.begin(); it != list.end(); ++it)
|
||||
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);
|
||||
}
|
||||
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);
|
||||
(*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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -236,14 +232,12 @@ void moveSelectedItemsTo(NC::Menu<MPD::Song> &m, F move_fun)
|
||||
size_t i = list.size()-1;
|
||||
for (auto it = list.rbegin(); it != list.rend(); ++it, --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;
|
||||
for (auto it = list.rbegin(); it != list.rend(); ++it, --i)
|
||||
{
|
||||
(*it)->setSelected(false);
|
||||
m[pos+i].setSelected(true);
|
||||
}
|
||||
(*it)->setSelected(false);
|
||||
m[pos+i].setSelected(true);
|
||||
}
|
||||
}
|
||||
else if (diff < 0) // move up
|
||||
@@ -251,23 +245,20 @@ void moveSelectedItemsTo(NC::Menu<MPD::Song> &m, F move_fun)
|
||||
size_t i = 0;
|
||||
for (auto it = list.begin(); it != list.end(); ++it, ++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;
|
||||
for (auto it = list.begin(); it != list.end(); ++it, ++i)
|
||||
{
|
||||
(*it)->setSelected(false);
|
||||
m[pos+i].setSelected(true);
|
||||
}
|
||||
(*it)->setSelected(false);
|
||||
m[pos+i].setSelected(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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);
|
||||
// ok, this is tricky. we need to operate on whole playlist
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
if (Mpd.CommitCommandsList())
|
||||
result = true;
|
||||
return result;
|
||||
Mpd.CommitCommandsList();
|
||||
}
|
||||
|
||||
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());
|
||||
return deleteSelectedSongs(m, delete_fun);
|
||||
deleteSelectedSongs(m, delete_fun);
|
||||
}
|
||||
|
||||
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())
|
||||
{
|
||||
for (auto it = m.begin(); it != m.end(); ++it)
|
||||
it->setSelected(true);
|
||||
result = deleteSelectedSongs(m, delete_fun);
|
||||
deleteSelectedSongs(m, delete_fun);
|
||||
}
|
||||
else
|
||||
result = clear_fun(Mpd);
|
||||
return result;
|
||||
clear_fun(Mpd);
|
||||
}
|
||||
|
||||
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 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);
|
||||
|
||||
|
||||
@@ -191,7 +191,7 @@ void Lastfm::Save(const std::string &data)
|
||||
output.close();
|
||||
}
|
||||
else
|
||||
Error("couldn't save file \"" << itsFilename << "\"");
|
||||
std::cerr << "ncmpcpp: couldn't save file \"" << itsFilename << "\"\n";
|
||||
}
|
||||
|
||||
void Lastfm::Refetch()
|
||||
|
||||
@@ -249,8 +249,6 @@ std::wstring MediaLibrary::title()
|
||||
|
||||
void MediaLibrary::update()
|
||||
{
|
||||
Mpd.BlockIdle(true);
|
||||
|
||||
if (hasTwoColumns)
|
||||
{
|
||||
if (Albums.reallyEmpty() || m_albums_update_request)
|
||||
@@ -407,8 +405,6 @@ void MediaLibrary::update()
|
||||
});
|
||||
Songs.refresh();
|
||||
}
|
||||
|
||||
Mpd.BlockIdle(false);
|
||||
}
|
||||
|
||||
void MediaLibrary::enterPressed()
|
||||
@@ -969,22 +965,20 @@ void MediaLibrary::AddToPlaylist(bool add_n_play)
|
||||
addSongToPlaylist(Songs.current().value(), add_n_play);
|
||||
else
|
||||
{
|
||||
auto list = getSelectedSongs();
|
||||
if (addSongsToPlaylist(list, add_n_play))
|
||||
addSongsToPlaylist(getSelectedSongs(), add_n_play);
|
||||
if ((!Tags.empty() && isActiveWindow(Tags))
|
||||
|| (isActiveWindow(Albums) && Albums.current().value().isAllTracksEntry()))
|
||||
{
|
||||
if ((!Tags.empty() && isActiveWindow(Tags))
|
||||
|| (isActiveWindow(Albums) && Albums.current().value().isAllTracksEntry()))
|
||||
{
|
||||
std::string tag_type = boost::locale::to_lower(
|
||||
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());
|
||||
std::string tag_type = boost::locale::to_lower(
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
if (!add_n_play)
|
||||
{
|
||||
w->scroll(NC::Scroll::Down);
|
||||
|
||||
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
|
||||
|
||||
#include <cassert>
|
||||
#include <exception>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
@@ -34,6 +35,36 @@ enum ItemType { itDirectory, itSong, itPlaylist };
|
||||
enum PlayerState { psUnknown, psStop, psPlay, psPause };
|
||||
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
|
||||
{
|
||||
friend class Connection;
|
||||
@@ -54,6 +85,40 @@ private:
|
||||
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
|
||||
{
|
||||
std::shared_ptr<Song> song;
|
||||
@@ -61,26 +126,6 @@ struct Item
|
||||
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
|
||||
{
|
||||
Output(const std::string &name_, bool enabled) : m_name(name_), m_enabled(enabled) { }
|
||||
@@ -99,7 +144,6 @@ typedef std::vector<Output> OutputList;
|
||||
|
||||
class Connection
|
||||
{
|
||||
typedef void (*StatusUpdater) (Connection *, StatusChanges, void *);
|
||||
typedef void (*ErrorHandler) (Connection *, int, const char *, void *);
|
||||
|
||||
typedef std::function<void(Item &&)> ItemConsumer;
|
||||
@@ -111,33 +155,27 @@ public:
|
||||
Connection();
|
||||
~Connection();
|
||||
|
||||
bool Connect();
|
||||
void Connect();
|
||||
bool Connected() const;
|
||||
void Disconnect();
|
||||
|
||||
const std::string & GetHostname() { return itsHost; }
|
||||
int GetPort() { return itsPort; }
|
||||
const std::string &GetHostname() { return m_host; }
|
||||
int GetPort() { return m_port; }
|
||||
|
||||
unsigned Version() const;
|
||||
|
||||
void SetIdleEnabled(bool val) { isIdleEnabled = val; }
|
||||
void BlockIdle(bool val) { itsIdleBlocked = val; }
|
||||
bool SupportsIdle() const { return supportsIdle; }
|
||||
void OrderDataFetching() { hasData = 1; }
|
||||
int GetFD() const { return itsFD; }
|
||||
int GetFD() const { return m_fd; }
|
||||
|
||||
void SetHostname(const std::string &);
|
||||
void SetPort(int port) { itsPort = port; }
|
||||
void SetTimeout(int timeout) { itsTimeout = timeout; }
|
||||
void SetPassword(const std::string &password) { itsPassword = password; }
|
||||
bool SendPassword();
|
||||
void SetPort(int port) { m_port = port; }
|
||||
void SetTimeout(int timeout) { m_timeout = timeout; }
|
||||
void SetPassword(const std::string &password) { m_password = password; }
|
||||
void SendPassword();
|
||||
|
||||
Statistics getStatistics();
|
||||
Status getStatus();
|
||||
|
||||
void SetStatusUpdater(StatusUpdater, void *);
|
||||
void SetErrorHandler(ErrorHandler, void *);
|
||||
void UpdateStatus();
|
||||
bool UpdateDirectory(const std::string &);
|
||||
void UpdateDirectory(const std::string &);
|
||||
|
||||
void Play();
|
||||
void Play(int);
|
||||
@@ -147,36 +185,15 @@ public:
|
||||
void Stop();
|
||||
void Next();
|
||||
void Prev();
|
||||
bool Move(unsigned, unsigned);
|
||||
void Move(unsigned int from, unsigned int to);
|
||||
void Swap(unsigned, unsigned);
|
||||
void Seek(unsigned);
|
||||
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);
|
||||
|
||||
const std::string &GetErrorMessage() const { return itsErrorMessage; }
|
||||
|
||||
Song GetCurrentlyPlayingSong();
|
||||
int GetCurrentSongPos() const;
|
||||
Song GetSong(const std::string &);
|
||||
void GetPlaylistContent(const std::string &name, SongConsumer f);
|
||||
|
||||
@@ -187,36 +204,35 @@ public:
|
||||
void SetSingle(bool);
|
||||
void SetConsume(bool);
|
||||
void SetCrossfade(unsigned);
|
||||
bool SetVolume(unsigned);
|
||||
void SetVolume(unsigned int vol);
|
||||
|
||||
std::string GetReplayGainMode();
|
||||
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 Song &, int = -1); // returns id of added song
|
||||
bool AddRandomTag(mpd_tag_type, size_t);
|
||||
bool AddRandomSongs(size_t);
|
||||
bool Add(const std::string &path);
|
||||
bool Delete(unsigned);
|
||||
bool DeleteID(unsigned);
|
||||
bool PlaylistDelete(const std::string &, unsigned);
|
||||
void Add(const std::string &path);
|
||||
void Delete(unsigned int pos);
|
||||
void PlaylistDelete(const std::string &playlist, unsigned int pos);
|
||||
void StartCommandsList();
|
||||
bool CommitCommandsList();
|
||||
void CommitCommandsList();
|
||||
|
||||
bool DeletePlaylist(const std::string &);
|
||||
bool LoadPlaylist(const std::string &name);
|
||||
int SavePlaylist(const std::string &);
|
||||
bool ClearPlaylist(const std::string &);
|
||||
void DeletePlaylist(const std::string &name);
|
||||
void LoadPlaylist(const std::string &name);
|
||||
void SavePlaylist(const std::string &);
|
||||
void ClearPlaylist(const std::string &playlist);
|
||||
void AddToPlaylist(const std::string &, const Song &);
|
||||
void AddToPlaylist(const std::string &, const std::string &);
|
||||
bool PlaylistMove(const std::string &, int, int);
|
||||
bool Rename(const std::string &, const std::string &);
|
||||
void PlaylistMove(const std::string &path, int from, int to);
|
||||
void Rename(const std::string &from, const std::string &to);
|
||||
|
||||
void StartSearch(bool);
|
||||
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 AddSearchURI(const std::string &str) const;
|
||||
void CommitSearchSongs(SongConsumer f);
|
||||
@@ -230,53 +246,39 @@ public:
|
||||
void GetDirectories(const std::string &directory, StringConsumer f);
|
||||
|
||||
void GetOutputs(OutputConsumer f);
|
||||
bool EnableOutput(int);
|
||||
bool DisableOutput(int);
|
||||
void EnableOutput(int id);
|
||||
void DisableOutput(int id);
|
||||
|
||||
void GetURLHandlers(StringConsumer f);
|
||||
void GetTagTypes(StringConsumer f);
|
||||
|
||||
void idle();
|
||||
int noidle();
|
||||
|
||||
private:
|
||||
void GoIdle();
|
||||
int GoBusy();
|
||||
|
||||
int CheckForErrors();
|
||||
void checkConnection() const;
|
||||
void prechecks();
|
||||
void prechecksNoCommandsList();
|
||||
void checkErrors() const;
|
||||
|
||||
mpd_connection *itsConnection;
|
||||
bool isCommandsListEnabled;
|
||||
mpd_connection *m_connection;
|
||||
bool m_command_list_active;
|
||||
|
||||
std::string itsErrorMessage;
|
||||
int m_fd;
|
||||
bool m_idle;
|
||||
|
||||
int itsFD;
|
||||
bool isIdle;
|
||||
bool isIdleEnabled;
|
||||
bool itsIdleBlocked;
|
||||
bool supportsIdle;
|
||||
bool hasData;
|
||||
std::string m_host;
|
||||
int m_port;
|
||||
int m_timeout;
|
||||
std::string m_password;
|
||||
|
||||
std::string itsHost;
|
||||
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;
|
||||
mpd_tag_type m_searched_field;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
extern MPD::Connection Mpd;
|
||||
extern MPD::Status MpdStatus;
|
||||
|
||||
#endif // NCMPCPP_MPDPP_H
|
||||
|
||||
157
src/ncmpcpp.cpp
157
src/ncmpcpp.cpp
@@ -40,6 +40,7 @@
|
||||
#include "error.h"
|
||||
#include "helpers.h"
|
||||
#include "lyrics.h"
|
||||
#include "outputs.h"
|
||||
#include "playlist.h"
|
||||
#include "settings.h"
|
||||
#include "status.h"
|
||||
@@ -97,7 +98,6 @@ int main(int argc, char **argv)
|
||||
using Global::wHeader;
|
||||
using Global::wFooter;
|
||||
|
||||
using Global::ShowMessages;
|
||||
using Global::VolumeState;
|
||||
using Global::Timer;
|
||||
|
||||
@@ -126,20 +126,10 @@ int main(int argc, char **argv)
|
||||
Mpd.SetPort(Config.mpd_port);
|
||||
|
||||
Mpd.SetTimeout(Config.mpd_connection_timeout);
|
||||
Mpd.SetIdleEnabled(Config.enable_idle_notifications);
|
||||
|
||||
if (argc > 1)
|
||||
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);
|
||||
|
||||
// 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->setTimeout(500);
|
||||
wFooter->setGetStringHelper(Statusbar::Helpers::getString);
|
||||
if (Mpd.SupportsIdle())
|
||||
wFooter->addFDCallback(Mpd.GetFD(), Statusbar::Helpers::mpd);
|
||||
wFooter->createHistory();
|
||||
|
||||
// initialize global timer
|
||||
@@ -186,9 +174,6 @@ int main(int argc, char **argv)
|
||||
if (Config.startup_screen != myScreen)
|
||||
Config.startup_screen->switchTo();
|
||||
|
||||
Mpd.SetStatusUpdater(Status::update, 0);
|
||||
Mpd.SetErrorHandler(Status::handleError, 0);
|
||||
|
||||
// local variables
|
||||
Key input(0, Key::Standard);
|
||||
timeval past = { 0, 0 };
|
||||
@@ -198,15 +183,6 @@ int main(int argc, char **argv)
|
||||
if (Config.mouse_support)
|
||||
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
|
||||
signal(SIGPIPE, sighandler);
|
||||
signal(SIGWINCH, sighandler);
|
||||
@@ -214,66 +190,95 @@ int main(int argc, char **argv)
|
||||
|
||||
while (!Actions::ExitMainLoop)
|
||||
{
|
||||
if (!Mpd.Connected())
|
||||
try
|
||||
{
|
||||
if (!wFooter->FDCallbacksListEmpty())
|
||||
wFooter->clearFDCallbacksList();
|
||||
Statusbar::msg("Attempting to reconnect...");
|
||||
if (Mpd.Connect())
|
||||
if (!Mpd.Connected())
|
||||
{
|
||||
Statusbar::msg("Connected to %s", Mpd.GetHostname().c_str());
|
||||
if (Mpd.SupportsIdle())
|
||||
wFooter->clearFDCallbacksList();
|
||||
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);
|
||||
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
|
||||
}
|
||||
|
||||
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)
|
||||
)
|
||||
catch (MPD::ClientError &e)
|
||||
{
|
||||
drawHeader();
|
||||
past = Timer;
|
||||
Status::handleClientError(e);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -46,7 +46,6 @@ Outputs::Outputs()
|
||||
w.setItemDisplayer([](NC::Menu<MPD::Output> &menu) {
|
||||
menu << Charset::utf8ToLocale(menu.drawn()->value().name());
|
||||
});
|
||||
FetchList();
|
||||
}
|
||||
|
||||
void Outputs::switchTo()
|
||||
@@ -73,16 +72,14 @@ void Outputs::enterPressed()
|
||||
{
|
||||
if (w.current().value().isEnabled())
|
||||
{
|
||||
if (Mpd.DisableOutput(w.choice()))
|
||||
Statusbar::msg("Output \"%s\" disabled", w.current().value().name().c_str());
|
||||
Mpd.DisableOutput(w.choice());
|
||||
Statusbar::msg("Output \"%s\" disabled", w.current().value().name().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Mpd.EnableOutput(w.choice()))
|
||||
Statusbar::msg("Output \"%s\" enabled", w.current().value().name().c_str());
|
||||
Mpd.EnableOutput(w.choice());
|
||||
Statusbar::msg("Output \"%s\" enabled", w.current().value().name().c_str());
|
||||
}
|
||||
if (!Mpd.SupportsIdle())
|
||||
FetchList();
|
||||
}
|
||||
|
||||
void Outputs::mouseButtonPressed(MEVENT me)
|
||||
|
||||
@@ -43,6 +43,7 @@ Playlist *myPlaylist;
|
||||
|
||||
bool Playlist::ReloadTotalLength = 0;
|
||||
bool Playlist::ReloadRemaining = false;
|
||||
unsigned Playlist::Version = 0;
|
||||
|
||||
namespace {//
|
||||
|
||||
@@ -217,9 +218,9 @@ MPD::SongList Playlist::getSelectedSongs()
|
||||
MPD::Song Playlist::nowPlayingSong()
|
||||
{
|
||||
MPD::Song s;
|
||||
if (Mpd.isPlaying())
|
||||
if (MpdStatus.playerState() != MPD::psStop)
|
||||
withUnfilteredMenu(w, [this, &s]() {
|
||||
s = w.at(Mpd.GetCurrentSongPos()).value();
|
||||
s = w.at(MpdStatus.currentSongPosition()).value();
|
||||
});
|
||||
return s;
|
||||
}
|
||||
@@ -242,8 +243,8 @@ void Playlist::Reverse()
|
||||
Mpd.StartCommandsList();
|
||||
for (--end; begin < end; ++begin, --end)
|
||||
Mpd.Swap(begin->value().getPosition(), end->value().getPosition());
|
||||
if (Mpd.CommitCommandsList())
|
||||
Statusbar::msg("Playlist reversed");
|
||||
Mpd.CommitCommandsList();
|
||||
Statusbar::msg("Playlist reversed");
|
||||
}
|
||||
|
||||
void Playlist::EnableHighlighting()
|
||||
@@ -271,7 +272,7 @@ std::string Playlist::TotalLength()
|
||||
if (Config.playlist_show_remaining_time && ReloadRemaining && !w.isFiltered())
|
||||
{
|
||||
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();
|
||||
ReloadRemaining = false;
|
||||
}
|
||||
@@ -284,7 +285,7 @@ std::string Playlist::TotalLength()
|
||||
size_t real_size = w.size();
|
||||
w.showFiltered();
|
||||
if (w.size() != real_size)
|
||||
result << " (out of " << Mpd.GetPlaylistLength() << ")";
|
||||
result << " (out of " << real_size << ")";
|
||||
}
|
||||
|
||||
if (itsTotalLength)
|
||||
@@ -307,7 +308,7 @@ void Playlist::PlayNewlyAddedSongs()
|
||||
bool is_filtered = w.isFiltered();
|
||||
w.showAll();
|
||||
size_t old_size = w.size();
|
||||
Mpd.UpdateStatus();
|
||||
//Mpd.UpdateStatus();
|
||||
if (old_size < w.size())
|
||||
Mpd.Play(old_size);
|
||||
if (is_filtered)
|
||||
@@ -320,8 +321,8 @@ void Playlist::SetSelectedItemsPriority(int prio)
|
||||
Mpd.StartCommandsList();
|
||||
for (auto it = list.begin(); it != list.end(); ++it)
|
||||
Mpd.SetPriority((*it)->value(), prio);
|
||||
if (Mpd.CommitCommandsList())
|
||||
Statusbar::msg("Priority set");
|
||||
Mpd.CommitCommandsList();
|
||||
Statusbar::msg("Priority set");
|
||||
}
|
||||
|
||||
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 unregisterHash(size_t hash);
|
||||
|
||||
static unsigned Version;
|
||||
static bool ReloadTotalLength;
|
||||
static bool ReloadRemaining;
|
||||
|
||||
|
||||
@@ -221,12 +221,10 @@ void PlaylistEditor::AddToPlaylist(bool add_n_play)
|
||||
|
||||
if (isActiveWindow(Playlists) && !Playlists.empty())
|
||||
{
|
||||
if (Mpd.LoadPlaylist(Playlists.current().value()))
|
||||
{
|
||||
Statusbar::msg("Playlist \"%s\" loaded", Playlists.current().value().c_str());
|
||||
if (add_n_play)
|
||||
myPlaylist->PlayNewlyAddedSongs();
|
||||
}
|
||||
Mpd.LoadPlaylist(Playlists.current().value());
|
||||
Statusbar::msg("Playlist \"%s\" loaded", Playlists.current().value().c_str());
|
||||
if (add_n_play)
|
||||
myPlaylist->PlayNewlyAddedSongs();
|
||||
}
|
||||
else if (isActiveWindow(Content) && !Content.empty())
|
||||
addSongToPlaylist(Content.current().value(), add_n_play);
|
||||
|
||||
@@ -234,61 +234,54 @@ void SelectedItemsAdder::addToExistingPlaylist(const std::string &playlist) cons
|
||||
Mpd.StartCommandsList();
|
||||
for (auto s = m_selected_items.begin(); s != m_selected_items.end(); ++s)
|
||||
Mpd.AddToPlaylist(playlist, *s);
|
||||
if (Mpd.CommitCommandsList())
|
||||
{
|
||||
Statusbar::msg("Selected item(s) added to playlist \"%s\"", playlist.c_str());
|
||||
switchToPreviousScreen();
|
||||
}
|
||||
Mpd.CommitCommandsList();
|
||||
Statusbar::msg("Selected item(s) added to playlist \"%s\"", playlist.c_str());
|
||||
switchToPreviousScreen();
|
||||
}
|
||||
|
||||
void SelectedItemsAdder::addAtTheEndOfPlaylist() const
|
||||
{
|
||||
bool success = addSongsToPlaylist(m_selected_items, false);
|
||||
if (success)
|
||||
exitSuccessfully();
|
||||
addSongsToPlaylist(m_selected_items, false);
|
||||
exitSuccessfully();
|
||||
}
|
||||
|
||||
void SelectedItemsAdder::addAtTheBeginningOfPlaylist() const
|
||||
{
|
||||
bool success = addSongsToPlaylist(m_selected_items, false, 0);
|
||||
if (success)
|
||||
exitSuccessfully();
|
||||
addSongsToPlaylist(m_selected_items, false, 0);
|
||||
exitSuccessfully();
|
||||
}
|
||||
|
||||
void SelectedItemsAdder::addAfterCurrentSong() const
|
||||
{
|
||||
if (!Mpd.isPlaying())
|
||||
if (MpdStatus.playerState() == MPD::psStop)
|
||||
return;
|
||||
size_t pos = Mpd.GetCurrentSongPos();
|
||||
size_t pos = MpdStatus.currentSongPosition();
|
||||
++pos;
|
||||
bool success = addSongsToPlaylist(m_selected_items, false, pos);
|
||||
if (success)
|
||||
exitSuccessfully();
|
||||
addSongsToPlaylist(m_selected_items, false, pos);
|
||||
exitSuccessfully();
|
||||
}
|
||||
|
||||
void SelectedItemsAdder::addAfterCurrentAlbum() const
|
||||
{
|
||||
if (!Mpd.isPlaying())
|
||||
if (MpdStatus.playerState() == MPD::psStop)
|
||||
return;
|
||||
auto &pl = myPlaylist->main();
|
||||
size_t pos = Mpd.GetCurrentSongPos();
|
||||
size_t pos = MpdStatus.currentSongPosition();
|
||||
withUnfilteredMenu(pl, [&pos, &pl]() {
|
||||
std::string album = pl[pos].value().getAlbum();
|
||||
while (pos < pl.size() && pl[pos].value().getAlbum() == album)
|
||||
++pos;
|
||||
});
|
||||
bool success = addSongsToPlaylist(m_selected_items, false, pos);
|
||||
if (success)
|
||||
exitSuccessfully();
|
||||
addSongsToPlaylist(m_selected_items, false, pos);
|
||||
exitSuccessfully();
|
||||
}
|
||||
|
||||
void SelectedItemsAdder::addAfterHighlightedSong() const
|
||||
{
|
||||
size_t pos = myPlaylist->main().current().value().getPosition();
|
||||
++pos;
|
||||
bool success = addSongsToPlaylist(m_selected_items, false, pos);
|
||||
if (success)
|
||||
exitSuccessfully();
|
||||
addSongsToPlaylist(m_selected_items, false, pos);
|
||||
exitSuccessfully();
|
||||
}
|
||||
|
||||
void SelectedItemsAdder::cancel()
|
||||
|
||||
@@ -36,19 +36,25 @@ ServerInfo::ServerInfo()
|
||||
{
|
||||
SetDimensions();
|
||||
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()
|
||||
{
|
||||
using Global::myScreen;
|
||||
if (myScreen != 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
|
||||
switchToPreviousScreen();
|
||||
}
|
||||
|
||||
@@ -201,11 +201,9 @@ void SortPlaylistDialog::sort() const
|
||||
Statusbar::msg("Sorting...");
|
||||
Mpd.StartCommandsList();
|
||||
quick_sort(playlist.begin(), playlist.end());
|
||||
if (Mpd.CommitCommandsList())
|
||||
{
|
||||
Statusbar::msg("Playlist sorted");
|
||||
switchToPreviousScreen();
|
||||
}
|
||||
Mpd.CommitCommandsList();
|
||||
Statusbar::msg("Playlist sorted");
|
||||
switchToPreviousScreen();
|
||||
}
|
||||
|
||||
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 (Mpd.Connected() && (Mpd.SupportsIdle() || Timer.tv_sec > past.tv_sec))
|
||||
{
|
||||
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();
|
||||
if (!e.clearable())
|
||||
Mpd.Disconnect();
|
||||
Statusbar::msg("NCMPCPP: %s", e.what());
|
||||
}
|
||||
|
||||
void Status::handleError(MPD::Connection * , int errorid, const char *msg, void *)
|
||||
void Status::handleServerError(MPD::ServerError &e)
|
||||
{
|
||||
// for errorid:
|
||||
// - 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)
|
||||
if (e.code() == MPD_SERVER_ERROR_PERMISSION)
|
||||
{
|
||||
wFooter->setGetStringHelper(0);
|
||||
wFooter->setGetStringHelper(nullptr);
|
||||
Statusbar::put() << "Password: ";
|
||||
Mpd.SetPassword(wFooter->getString(-1, 0, 1));
|
||||
if (Mpd.SendPassword())
|
||||
Statusbar::msg("Password accepted");
|
||||
Mpd.SendPassword();
|
||||
Statusbar::msg("Password accepted");
|
||||
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->refresh();
|
||||
}
|
||||
else
|
||||
Statusbar::msg("MPD: %s", msg);
|
||||
Statusbar::msg("MPD: %s", e.what());
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
myPlaylist->main().clearSearchResults();
|
||||
withUnfilteredMenuReapplyFilter(myPlaylist->main(), []() {
|
||||
size_t playlist_length = Mpd.GetPlaylistLength();
|
||||
size_t playlist_length = MpdStatus.playlistLength();
|
||||
if (playlist_length < myPlaylist->main().size())
|
||||
{
|
||||
auto it = myPlaylist->main().begin()+playlist_length;
|
||||
@@ -142,7 +142,7 @@ void Status::Changes::playlist()
|
||||
myPlaylist->main().resizeList(playlist_length);
|
||||
}
|
||||
|
||||
Mpd.GetPlaylistChanges(Mpd.GetOldPlaylistID(), [](MPD::Song &&s) {
|
||||
Mpd.GetPlaylistChanges(myPlaylist->Version, [](MPD::Song &&s) {
|
||||
size_t pos = s.getPosition();
|
||||
if (pos < myPlaylist->main().size())
|
||||
{
|
||||
@@ -155,9 +155,11 @@ void Status::Changes::playlist()
|
||||
myPlaylist->main().addItem(s);
|
||||
myPlaylist->registerHash(s.getHash());
|
||||
});
|
||||
|
||||
myPlaylist->Version = MpdStatus.playlistVersion();
|
||||
});
|
||||
|
||||
if (Mpd.isPlaying())
|
||||
if (MpdStatus.playerState() != MPD::psStop)
|
||||
drawTitle(myPlaylist->nowPlayingSong());
|
||||
|
||||
Playlist::ReloadTotalLength = true;
|
||||
@@ -201,7 +203,7 @@ void Status::Changes::database()
|
||||
|
||||
void Status::Changes::playerState()
|
||||
{
|
||||
MPD::PlayerState state = Mpd.GetState();
|
||||
MPD::PlayerState state = MpdStatus.playerState();
|
||||
switch (state)
|
||||
{
|
||||
case MPD::psUnknown:
|
||||
@@ -214,8 +216,6 @@ void Status::Changes::playerState()
|
||||
drawTitle(myPlaylist->nowPlayingSong());
|
||||
player_state = Config.new_design ? "[playing]" : "Playing: ";
|
||||
Playlist::ReloadRemaining = true;
|
||||
if (Mpd.GetOldState() == MPD::psStop) // show track info in status immediately
|
||||
elapsedTime();
|
||||
break;
|
||||
}
|
||||
case MPD::psPause:
|
||||
@@ -272,7 +272,7 @@ void Status::Changes::songID()
|
||||
playing_song_scroll_begin = 0;
|
||||
first_line_scroll_begin = 0;
|
||||
second_line_scroll_begin = 0;
|
||||
if (Mpd.isPlaying())
|
||||
if (MpdStatus.playerState() != MPD::psStop)
|
||||
{
|
||||
GNUC_UNUSED int res;
|
||||
if (!Config.execute_on_song_change.empty())
|
||||
@@ -286,18 +286,17 @@ void Status::Changes::songID()
|
||||
drawTitle(myPlaylist->nowPlayingSong());
|
||||
|
||||
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)
|
||||
myLyrics->ReloadNP = 1;
|
||||
|
||||
elapsedTime();
|
||||
}
|
||||
elapsedTime();
|
||||
}
|
||||
|
||||
void Status::Changes::elapsedTime()
|
||||
{
|
||||
if (!Mpd.isPlaying())
|
||||
if (MpdStatus.playerState() == MPD::psStop)
|
||||
{
|
||||
if (Statusbar::isUnlocked() && Config.statusbar_visibility)
|
||||
*wFooter << NC::XY(0, 1) << wclrtoeol;
|
||||
@@ -313,20 +312,20 @@ void Status::Changes::elapsedTime()
|
||||
if (Config.display_remaining_time)
|
||||
{
|
||||
tracklength = "-";
|
||||
tracklength += MPD::Song::ShowTime(Mpd.GetTotalTime()-Mpd.GetElapsedTime());
|
||||
tracklength += MPD::Song::ShowTime(MpdStatus.totalTime()-MpdStatus.elapsedTime());
|
||||
}
|
||||
else
|
||||
tracklength = MPD::Song::ShowTime(Mpd.GetElapsedTime());
|
||||
if (Mpd.GetTotalTime())
|
||||
tracklength = MPD::Song::ShowTime(MpdStatus.elapsedTime());
|
||||
if (MpdStatus.totalTime())
|
||||
{
|
||||
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
|
||||
if (Config.display_bitrate && Mpd.GetBitrate())
|
||||
if (Config.display_bitrate && MpdStatus.kbps())
|
||||
{
|
||||
tracklength += " ";
|
||||
tracklength += boost::lexical_cast<std::string>(Mpd.GetBitrate());
|
||||
tracklength += boost::lexical_cast<std::string>(MpdStatus.kbps());
|
||||
tracklength += " kbps";
|
||||
}
|
||||
|
||||
@@ -357,29 +356,29 @@ void Status::Changes::elapsedTime()
|
||||
}
|
||||
else if (Statusbar::isUnlocked() && Config.statusbar_visibility)
|
||||
{
|
||||
if (Config.display_bitrate && Mpd.GetBitrate())
|
||||
if (Config.display_bitrate && MpdStatus.kbps())
|
||||
{
|
||||
tracklength += " [";
|
||||
tracklength += boost::lexical_cast<std::string>(Mpd.GetBitrate());
|
||||
tracklength += boost::lexical_cast<std::string>(MpdStatus.kbps());
|
||||
tracklength += " kbps]";
|
||||
}
|
||||
tracklength += " [";
|
||||
if (Mpd.GetTotalTime())
|
||||
if (MpdStatus.totalTime())
|
||||
{
|
||||
if (Config.display_remaining_time)
|
||||
{
|
||||
tracklength += "-";
|
||||
tracklength += MPD::Song::ShowTime(Mpd.GetTotalTime()-Mpd.GetElapsedTime());
|
||||
tracklength += MPD::Song::ShowTime(MpdStatus.totalTime()-MpdStatus.elapsedTime());
|
||||
}
|
||||
else
|
||||
tracklength += MPD::Song::ShowTime(Mpd.GetElapsedTime());
|
||||
tracklength += MPD::Song::ShowTime(MpdStatus.elapsedTime());
|
||||
tracklength += "/";
|
||||
tracklength += MPD::Song::ShowTime(Mpd.GetTotalTime());
|
||||
tracklength += MPD::Song::ShowTime(MpdStatus.totalTime());
|
||||
tracklength += "]";
|
||||
}
|
||||
else
|
||||
{
|
||||
tracklength += MPD::Song::ShowTime(Mpd.GetElapsedTime());
|
||||
tracklength += MPD::Song::ShowTime(MpdStatus.elapsedTime());
|
||||
tracklength += "]";
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
Statusbar::msg("Repeat mode is %s", !mpd_repeat ? "off" : "on");
|
||||
mpd_repeat = MpdStatus.repeat() ? 'r' : 0;
|
||||
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;
|
||||
Statusbar::msg("Random mode is %s", !mpd_random ? "off" : "on");
|
||||
mpd_random = MpdStatus.random() ? 'z' : 0;
|
||||
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;
|
||||
Statusbar::msg("Single mode is %s", !mpd_single ? "off" : "on");
|
||||
mpd_single = MpdStatus.single() ? 's' : 0;
|
||||
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;
|
||||
Statusbar::msg("Consume mode is %s", !mpd_consume ? "off" : "on");
|
||||
mpd_consume = MpdStatus.consume() ? 'c' : 0;
|
||||
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;
|
||||
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;
|
||||
Statusbar::msg(Mpd.GetDBIsUpdating() ? "Database update started" : "Database update finished");
|
||||
mpd_db_updating = MpdStatus.updateID() ? 'U' : 0;
|
||||
if (show_msg)
|
||||
Statusbar::msg(MpdStatus.updateID() ? "Database update started" : "Database update finished");
|
||||
}
|
||||
|
||||
void Status::Changes::flags()
|
||||
@@ -494,7 +499,7 @@ void Status::Changes::mixer()
|
||||
return;
|
||||
|
||||
VolumeState = Config.new_design ? " Vol: " : " Volume: ";
|
||||
int volume = Mpd.GetVolume();
|
||||
int volume = MpdStatus.volume();
|
||||
if (volume < 0)
|
||||
VolumeState += "n/a";
|
||||
else
|
||||
@@ -515,41 +520,50 @@ void Status::Changes::outputs()
|
||||
# endif // ENABLE_OUTPUTS
|
||||
}
|
||||
|
||||
void Status::update(MPD::Connection *, MPD::StatusChanges changes, void *)
|
||||
void Status::update(int event)
|
||||
{
|
||||
if (changes.Playlist)
|
||||
Changes::playlist();
|
||||
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();
|
||||
MPD::Status old = MpdStatus;
|
||||
MpdStatus = Mpd.getStatus();
|
||||
|
||||
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();
|
||||
if (changes.Playlist || changes.Database || changes.PlayerState || changes.SongID)
|
||||
|
||||
if (event & (MPD_IDLE_PLAYLIST | MPD_IDLE_DATABASE | MPD_IDLE_PLAYER))
|
||||
applyToVisibleWindows(&BaseScreen::refreshWindow);
|
||||
}
|
||||
|
||||
20
src/status.h
20
src/status.h
@@ -26,11 +26,11 @@
|
||||
|
||||
namespace Status {//
|
||||
|
||||
void handleClientError(MPD::ClientError &e);
|
||||
void handleServerError(MPD::ServerError &e);
|
||||
|
||||
void trace();
|
||||
|
||||
void handleError(MPD::Connection * , int errorid, const char *msg, void *);
|
||||
|
||||
void update(MPD::Connection *, MPD::StatusChanges changes, void *);
|
||||
void update(int event);
|
||||
|
||||
namespace Changes {//
|
||||
|
||||
@@ -40,12 +40,12 @@ void database();
|
||||
void playerState();
|
||||
void songID();
|
||||
void elapsedTime();
|
||||
void repeat();
|
||||
void random();
|
||||
void single();
|
||||
void consume();
|
||||
void crossfade();
|
||||
void dbUpdateState();
|
||||
void repeat(bool show_msg);
|
||||
void random(bool show_msg);
|
||||
void single(bool show_msg);
|
||||
void consume(bool show_msg);
|
||||
void crossfade(bool show_msg);
|
||||
void dbUpdateState(bool show_msg);
|
||||
void flags();
|
||||
void mixer();
|
||||
void outputs();
|
||||
|
||||
@@ -38,7 +38,7 @@ bool statusbarAllowUnlock = true;
|
||||
|
||||
void showMessage(int time, const char *format, va_list list)
|
||||
{
|
||||
if (Global::ShowMessages && statusbarAllowUnlock)
|
||||
if (statusbarAllowUnlock)
|
||||
{
|
||||
statusbarLockTime = Global::Timer;
|
||||
statusbarLockDelay = time;
|
||||
@@ -122,10 +122,10 @@ void Statusbar::unlock()
|
||||
else
|
||||
progressbarBlockUpdate = false;
|
||||
}
|
||||
if (!Mpd.isPlaying())
|
||||
if (MpdStatus.playerState() == MPD::psStop)
|
||||
{
|
||||
if (Config.new_design)
|
||||
Progressbar::draw(Mpd.GetElapsedTime(), Mpd.GetTotalTime());
|
||||
Progressbar::draw(MpdStatus.elapsedTime(), MpdStatus.totalTime());
|
||||
else
|
||||
put() << wclrtoeol;
|
||||
wFooter->refresh();
|
||||
@@ -150,12 +150,12 @@ void Statusbar::tryRedraw()
|
||||
else
|
||||
progressbarBlockUpdate = !statusbarAllowUnlock;
|
||||
|
||||
if (Mpd.GetState() != MPD::psPlay && !statusbarBlockUpdate && !progressbarBlockUpdate)
|
||||
if (MpdStatus.playerState() != MPD::psStop && !statusbarBlockUpdate && !progressbarBlockUpdate)
|
||||
{
|
||||
if (Config.new_design)
|
||||
Progressbar::draw(Mpd.GetElapsedTime(), Mpd.GetTotalTime());
|
||||
Progressbar::draw(MpdStatus.elapsedTime(), MpdStatus.totalTime());
|
||||
else
|
||||
put() << wclrtoeol;
|
||||
Status::Changes::elapsedTime();
|
||||
wFooter->refresh();
|
||||
}
|
||||
}
|
||||
@@ -185,7 +185,7 @@ void Statusbar::msg(int time, const char *format, ...)
|
||||
|
||||
void Statusbar::Helpers::mpd()
|
||||
{
|
||||
Mpd.OrderDataFetching();
|
||||
Status::update(Mpd.noidle());
|
||||
}
|
||||
|
||||
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_plan = fftw_plan_dft_r2c_1d(m_samples, m_fftw_input, m_fftw_output, FFTW_ESTIMATE);
|
||||
# endif // HAVE_FFTW3_H
|
||||
|
||||
FindOutputID();
|
||||
}
|
||||
|
||||
void Visualizer::switchTo()
|
||||
|
||||
Reference in New Issue
Block a user