rewrite communication system with mpd

This commit is contained in:
Andrzej Rybczak
2013-04-06 19:01:27 +02:00
parent 153e843774
commit 6a3eb73a49
25 changed files with 1039 additions and 1470 deletions

View File

@@ -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;

View File

@@ -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())

View File

@@ -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 = "/");

View File

@@ -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);
}
}
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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)

View File

@@ -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);

View File

@@ -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()

View File

@@ -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);

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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)

View File

@@ -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)

View File

@@ -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;

View File

@@ -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);

View File

@@ -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()

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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();

View File

@@ -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 &)

View File

@@ -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()