statusbar: use scoped locks instead of lock/unlock functions

This commit is contained in:
Andrzej Rybczak
2014-10-31 15:05:57 +01:00
parent 9e6b8533f1
commit fa1cd965fa
7 changed files with 319 additions and 298 deletions

View File

@@ -256,7 +256,7 @@ bool askYesNoQuestion(const boost::format &fmt, void (*callback)())
{ {
using Global::wFooter; using Global::wFooter;
Statusbar::lock(); Statusbar::ScopedLock lock;
Statusbar::put() << fmt.str() << " [" << NC::Format::Bold << 'y' << NC::Format::NoBold << '/' << NC::Format::Bold << 'n' << NC::Format::NoBold << "]"; Statusbar::put() << fmt.str() << " [" << NC::Format::Bold << 'y' << NC::Format::NoBold << '/' << NC::Format::Bold << 'n' << NC::Format::NoBold << "]";
wFooter->refresh(); wFooter->refresh();
int answer = 0; int answer = 0;
@@ -267,7 +267,6 @@ bool askYesNoQuestion(const boost::format &fmt, void (*callback)())
answer = wFooter->readKey(); answer = wFooter->readKey();
} }
while (answer != 'y' && answer != 'n'); while (answer != 'y' && answer != 'n');
Statusbar::unlock();
return answer == 'y'; return answer == 'y';
} }
@@ -509,8 +508,6 @@ void ToggleInterface::run()
break; break;
} }
setWindowsDimensions(); setWindowsDimensions();
Progressbar::unlock();
Statusbar::unlock();
resizeScreen(false); resizeScreen(false);
Status::Changes::mixer(); Status::Changes::mixer();
Status::Changes::elapsedTime(false); Status::Changes::elapsedTime(false);
@@ -778,54 +775,53 @@ void SavePlaylist::run()
{ {
using Global::wFooter; using Global::wFooter;
Statusbar::lock(); std::string playlist_name;
Statusbar::put() << "Save playlist as: "; {
std::string playlist_name = wFooter->getString(); Statusbar::ScopedLock lock;
Statusbar::unlock(); Statusbar::put() << "Save playlist as: ";
playlist_name = wFooter->getString();
}
if (playlist_name.find("/") != std::string::npos) if (playlist_name.find("/") != std::string::npos)
{ {
Statusbar::print("Playlist name must not contain slashes"); Statusbar::print("Playlist name must not contain slashes");
return; return;
} }
if (!playlist_name.empty()) if (myPlaylist->main().isFiltered())
{ {
if (myPlaylist->main().isFiltered()) Mpd.StartCommandsList();
for (size_t i = 0; i < myPlaylist->main().size(); ++i)
Mpd.AddToPlaylist(playlist_name, myPlaylist->main()[i].value());
Mpd.CommitCommandsList();
Statusbar::printf("Filtered items added to playlist \"%1%\"", playlist_name);
}
else
{
try
{ {
Mpd.StartCommandsList(); Mpd.SavePlaylist(playlist_name);
for (size_t i = 0; i < myPlaylist->main().size(); ++i) Statusbar::printf("Playlist saved as \"%1%\"", playlist_name);
Mpd.AddToPlaylist(playlist_name, myPlaylist->main()[i].value());
Mpd.CommitCommandsList();
Statusbar::printf("Filtered items added to playlist \"%1%\"", playlist_name);
} }
else catch (MPD::ServerError &e)
{ {
try if (e.code() == MPD_SERVER_ERROR_EXIST)
{ {
Mpd.SavePlaylist(playlist_name); bool yes = askYesNoQuestion(
Statusbar::printf("Playlist saved as \"%1%\"", playlist_name); boost::format("Playlist \"%1%\" already exists, overwrite?") % playlist_name,
} Status::trace
catch (MPD::ServerError &e) );
{ if (yes)
if (e.code() == MPD_SERVER_ERROR_EXIST)
{ {
bool yes = askYesNoQuestion( Mpd.DeletePlaylist(playlist_name);
boost::format("Playlist \"%1%\" already exists, overwrite?") % playlist_name, Mpd.SavePlaylist(playlist_name);
Status::trace Statusbar::print("Playlist overwritten");
);
if (yes)
{
Mpd.DeletePlaylist(playlist_name);
Mpd.SavePlaylist(playlist_name);
Statusbar::print("Playlist overwritten");
}
else
Statusbar::print("Aborted");
if (myScreen == myPlaylist)
myPlaylist->EnableHighlighting();
} }
else else
throw e; Statusbar::print("Aborted");
if (myScreen == myPlaylist)
myPlaylist->EnableHighlighting();
} }
else
throw e;
} }
} }
if (!myBrowser->isLocal() if (!myBrowser->isLocal()
@@ -842,14 +838,16 @@ void Stop::run()
void ExecuteCommand::run() void ExecuteCommand::run()
{ {
using Global::wFooter; using Global::wFooter;
Statusbar::lock();
Statusbar::put() << NC::Format::Bold << ":" << NC::Format::NoBold; std::string cmd_name;
wFooter->setGetStringHelper(Statusbar::Helpers::TryExecuteImmediateCommand()); {
std::string cmd_name = wFooter->getString(); Statusbar::ScopedLock lock;
wFooter->setGetStringHelper(Statusbar::Helpers::getString); Statusbar::put() << NC::Format::Bold << ":" << NC::Format::NoBold;
Statusbar::unlock(); wFooter->setGetStringHelper(Statusbar::Helpers::TryExecuteImmediateCommand());
if (cmd_name.empty()) cmd_name = wFooter->getString();
return; wFooter->setGetStringHelper(Statusbar::Helpers::getString);
}
auto cmd = Bindings.findCommand(cmd_name); auto cmd = Bindings.findCommand(cmd_name);
if (cmd) if (cmd)
{ {
@@ -965,29 +963,29 @@ void Add::run()
{ {
using Global::wFooter; using Global::wFooter;
Statusbar::lock(); std::string path;
Statusbar::put() << (myScreen == myPlaylistEditor ? "Add to playlist: " : "Add: ");
std::string path = wFooter->getString();
Statusbar::unlock();
if (!path.empty())
{ {
Statusbar::put() << "Adding..."; Statusbar::ScopedLock lock;
wFooter->refresh(); Statusbar::put() << (myScreen == myPlaylistEditor ? "Add to playlist: " : "Add: ");
if (myScreen == myPlaylistEditor) path = wFooter->getString();
Mpd.AddToPlaylist(myPlaylistEditor->Playlists.current().value(), path); }
Statusbar::put() << "Adding...";
wFooter->refresh();
if (myScreen == myPlaylistEditor)
Mpd.AddToPlaylist(myPlaylistEditor->Playlists.current().value(), path);
else
{
const char lastfm_url[] = "lastfm://";
if (path.compare(0, const_strlen(lastfm_url), lastfm_url) == 0
|| path.find(".asx", path.length()-4) != std::string::npos
|| path.find(".cue", path.length()-4) != std::string::npos
|| path.find(".m3u", path.length()-4) != std::string::npos
|| path.find(".pls", path.length()-4) != std::string::npos
|| path.find(".xspf", path.length()-5) != std::string::npos)
Mpd.LoadPlaylist(path);
else else
{ Mpd.Add(path);
const char lastfm_url[] = "lastfm://";
if (path.compare(0, const_strlen(lastfm_url), lastfm_url) == 0
|| path.find(".asx", path.length()-4) != std::string::npos
|| path.find(".cue", path.length()-4) != std::string::npos
|| path.find(".m3u", path.length()-4) != std::string::npos
|| path.find(".pls", path.length()-4) != std::string::npos
|| path.find(".xspf", path.length()-5) != std::string::npos)
Mpd.LoadPlaylist(path);
else
Mpd.Add(path);
}
} }
} }
@@ -1274,27 +1272,26 @@ void SetCrossfade::run()
{ {
using Global::wFooter; using Global::wFooter;
Statusbar::lock(); Statusbar::ScopedLock lock;
Statusbar::put() << "Set crossfade to: "; Statusbar::put() << "Set crossfade to: ";
std::string crossfade = wFooter->getString(); auto crossfade = fromString<unsigned>(wFooter->getString());
Statusbar::unlock(); lowerBoundCheck(crossfade, 0u);
int cf = fromString<unsigned>(crossfade); Config.crossfade_time = crossfade;
lowerBoundCheck(cf, 1); Mpd.SetCrossfade(crossfade);
Config.crossfade_time = cf;
Mpd.SetCrossfade(cf);
} }
void SetVolume::run() void SetVolume::run()
{ {
using Global::wFooter; using Global::wFooter;
Statusbar::lock(); unsigned volume;
Statusbar::put() << "Set volume to: "; {
std::string strvolume = wFooter->getString(); Statusbar::ScopedLock lock;
Statusbar::unlock(); Statusbar::put() << "Set volume to: ";
int volume = fromString<unsigned>(strvolume); volume = fromString<unsigned>(wFooter->getString());
boundsCheck(volume, 0, 100); boundsCheck(volume, 0u, 100u);
Mpd.SetVolume(volume); Mpd.SetVolume(volume);
}
Statusbar::printf("Volume set to %1%%%", volume); Statusbar::printf("Volume set to %1%%%", volume);
} }
@@ -1333,10 +1330,12 @@ void EditLibraryTag::run()
# ifdef HAVE_TAGLIB_H # ifdef HAVE_TAGLIB_H
using Global::wFooter; using Global::wFooter;
Statusbar::lock(); std::string new_tag;
Statusbar::put() << NC::Format::Bold << tagTypeToString(Config.media_lib_primary_tag) << NC::Format::NoBold << ": "; {
std::string new_tag = wFooter->getString(myLibrary->Tags.current().value().tag()); Statusbar::ScopedLock lock;
Statusbar::unlock(); Statusbar::put() << NC::Format::Bold << tagTypeToString(Config.media_lib_primary_tag) << NC::Format::NoBold << ": ";
new_tag = wFooter->getString(myLibrary->Tags.current().value().tag());
}
if (!new_tag.empty() && new_tag != myLibrary->Tags.current().value().tag()) if (!new_tag.empty() && new_tag != myLibrary->Tags.current().value().tag())
{ {
Statusbar::print("Updating tags..."); Statusbar::print("Updating tags...");
@@ -1388,11 +1387,13 @@ void EditLibraryAlbum::run()
{ {
# ifdef HAVE_TAGLIB_H # ifdef HAVE_TAGLIB_H
using Global::wFooter; using Global::wFooter;
// FIXME: merge this and EditLibraryTag. also, prompt on failure if user wants to continue
Statusbar::lock(); std::string new_album;
Statusbar::put() << NC::Format::Bold << "Album: " << NC::Format::NoBold; {
std::string new_album = wFooter->getString(myLibrary->Albums.current().value().entry().album()); Statusbar::ScopedLock lock;
Statusbar::unlock(); Statusbar::put() << NC::Format::Bold << "Album: " << NC::Format::NoBold;
new_album = wFooter->getString(myLibrary->Albums.current().value().entry().album());
}
if (!new_album.empty() && new_album != myLibrary->Albums.current().value().entry().album()) if (!new_album.empty() && new_album != myLibrary->Albums.current().value().entry().album())
{ {
bool success = 1; bool success = 1;
@@ -1443,14 +1444,15 @@ bool EditDirectoryName::canBeRun() const
void EditDirectoryName::run() void EditDirectoryName::run()
{ {
using Global::wFooter; using Global::wFooter;
// FIXME: use boost::filesystem and better error reporting
if (myScreen == myBrowser) if (myScreen == myBrowser)
{ {
std::string old_dir = myBrowser->main().current().value().name; std::string old_dir = myBrowser->main().current().value().name, new_dir;
Statusbar::lock(); {
Statusbar::put() << NC::Format::Bold << "Directory: " << NC::Format::NoBold; Statusbar::ScopedLock lock;
std::string new_dir = wFooter->getString(old_dir); Statusbar::put() << NC::Format::Bold << "Directory: " << NC::Format::NoBold;
Statusbar::unlock(); new_dir = wFooter->getString(old_dir);
}
if (!new_dir.empty() && new_dir != old_dir) if (!new_dir.empty() && new_dir != old_dir)
{ {
std::string full_old_dir; std::string full_old_dir;
@@ -1480,11 +1482,12 @@ void EditDirectoryName::run()
# ifdef HAVE_TAGLIB_H # ifdef HAVE_TAGLIB_H
else if (myScreen->activeWindow() == myTagEditor->Dirs) else if (myScreen->activeWindow() == myTagEditor->Dirs)
{ {
std::string old_dir = myTagEditor->Dirs->current().value().first; std::string old_dir = myTagEditor->Dirs->current().value().first, new_dir;
Statusbar::lock(); {
Statusbar::put() << NC::Format::Bold << "Directory: " << NC::Format::NoBold; Statusbar::ScopedLock lock;
std::string new_dir = wFooter->getString(old_dir); Statusbar::put() << NC::Format::Bold << "Directory: " << NC::Format::NoBold;
Statusbar::unlock(); new_dir = wFooter->getString(old_dir);
}
if (!new_dir.empty() && new_dir != old_dir) if (!new_dir.empty() && new_dir != old_dir)
{ {
std::string full_old_dir = Config.mpd_music_dir + myTagEditor->CurrentDir() + "/" + old_dir; std::string full_old_dir = Config.mpd_music_dir + myTagEditor->CurrentDir() + "/" + old_dir;
@@ -1517,16 +1520,17 @@ bool EditPlaylistName::canBeRun() const
void EditPlaylistName::run() void EditPlaylistName::run()
{ {
using Global::wFooter; using Global::wFooter;
// FIXME: support local browser more generally
std::string old_name; std::string old_name, new_name;
if (myScreen->isActiveWindow(myPlaylistEditor->Playlists)) if (myScreen->isActiveWindow(myPlaylistEditor->Playlists))
old_name = myPlaylistEditor->Playlists.current().value(); old_name = myPlaylistEditor->Playlists.current().value();
else else
old_name = myBrowser->main().current().value().name; old_name = myBrowser->main().current().value().name;
Statusbar::lock(); {
Statusbar::put() << NC::Format::Bold << "Playlist: " << NC::Format::NoBold; Statusbar::ScopedLock lock;
std::string new_name = wFooter->getString(old_name); Statusbar::put() << NC::Format::Bold << "Playlist: " << NC::Format::NoBold;
Statusbar::unlock(); new_name = wFooter->getString(old_name);
}
if (!new_name.empty() && new_name != old_name) if (!new_name.empty() && new_name != old_name)
{ {
Mpd.Rename(old_name, new_name); Mpd.Rename(old_name, new_name);
@@ -1584,7 +1588,7 @@ void ToggleScreenLock::run()
{ {
using Global::wFooter; using Global::wFooter;
using Global::myLockedScreen; using Global::myLockedScreen;
// FIXME: check if screen can be locked before prompting for width
if (myLockedScreen != 0) if (myLockedScreen != 0)
{ {
BaseScreen::unlock(); BaseScreen::unlock();
@@ -1594,16 +1598,14 @@ void ToggleScreenLock::run()
} }
else else
{ {
int part = Config.locked_screen_width_part*100; unsigned part = Config.locked_screen_width_part*100;
if (Config.ask_for_locked_screen_width_part) if (Config.ask_for_locked_screen_width_part)
{ {
Statusbar::lock(); Statusbar::ScopedLock lock;
Statusbar::put() << "% of the locked screen's width to be reserved (20-80): "; Statusbar::put() << "% of the locked screen's width to be reserved (20-80): ";
std::string strpart = wFooter->getString(boost::lexical_cast<std::string>(part)); part = fromString<unsigned>(wFooter->getString(boost::lexical_cast<std::string>(part)));
Statusbar::unlock();
part = fromString<unsigned>(strpart);
} }
boundsCheck(part, 20, 80); boundsCheck(part, 20u, 80u);
Config.locked_screen_width_part = part/100.0; Config.locked_screen_width_part = part/100.0;
if (myScreen->lock()) if (myScreen->lock())
Statusbar::printf("Screen locked (with %1%%% width)", part); Statusbar::printf("Screen locked (with %1%%% width)", part);
@@ -1641,30 +1643,31 @@ void JumpToPositionInSong::run()
const MPD::Song s = myPlaylist->nowPlayingSong(); const MPD::Song s = myPlaylist->nowPlayingSong();
Statusbar::lock(); std::string spos;
Statusbar::put() << "Position to go (in %/m:ss/seconds(s)): "; {
std::string strpos = wFooter->getString(); Statusbar::ScopedLock lock;
Statusbar::unlock(); Statusbar::put() << "Position to go (in %/m:ss/seconds(s)): ";
spos = wFooter->getString();
}
boost::regex rx; boost::regex rx;
boost::smatch what; boost::smatch what;
if (boost::regex_match(spos, what, rx.assign("([0-9]+):([0-9]{2})"))) // mm:ss
if (boost::regex_match(strpos, what, rx.assign("([0-9]+):([0-9]{2})"))) // mm:ss
{ {
int mins = fromString<int>(what[1]); auto mins = fromString<unsigned>(what[1]);
int secs = fromString<int>(what[2]); auto secs = fromString<unsigned>(what[2]);
boundsCheck(secs, 0, 60); boundsCheck(secs, 0u, 60u);
Mpd.Seek(s.getPosition(), mins * 60 + secs); Mpd.Seek(s.getPosition(), mins * 60 + secs);
} }
else if (boost::regex_match(strpos, what, rx.assign("([0-9]+)s"))) // position in seconds else if (boost::regex_match(spos, what, rx.assign("([0-9]+)s"))) // position in seconds
{ {
int secs = fromString<int>(what[1]); auto secs = fromString<unsigned>(what[1]);
Mpd.Seek(s.getPosition(), secs); Mpd.Seek(s.getPosition(), secs);
} }
else if (boost::regex_match(strpos, what, rx.assign("([0-9]+)[%]{0,1}"))) // position in % else if (boost::regex_match(spos, what, rx.assign("([0-9]+)[%]{0,1}"))) // position in %
{ {
int percent = fromString<int>(what[1]); auto percent = fromString<unsigned>(what[1]);
boundsCheck(percent, 0, 100); boundsCheck(percent, 0u, 100u);
int secs = (percent * s.getDuration()) / 100.0; int secs = (percent * s.getDuration()) / 100.0;
Mpd.Seek(s.getPosition(), secs); Mpd.Seek(s.getPosition(), secs);
} }
@@ -1876,12 +1879,20 @@ void ApplyFilter::run()
myScreen->refreshWindow(); myScreen->refreshWindow();
} }
Statusbar::lock(); try
Statusbar::put() << NC::Format::Bold << "Apply filter: " << NC::Format::NoBold; {
wFooter->setGetStringHelper(Statusbar::Helpers::ApplyFilterImmediately(f, filter)); Statusbar::ScopedLock lock;
wFooter->getString(filter); Statusbar::put() << NC::Format::Bold << "Apply filter: " << NC::Format::NoBold;
wFooter->setGetStringHelper(Statusbar::Helpers::getString); wFooter->setGetStringHelper(Statusbar::Helpers::ApplyFilterImmediately(f, filter));
Statusbar::unlock(); wFooter->getString(filter);
wFooter->setGetStringHelper(Statusbar::Helpers::getString);
}
catch (NC::PromptAborted &)
{
// restore previous filter
f->applyFilter(filter);
throw;
}
filter = f->currentFilter(); filter = f->currentFilter();
if (filter.empty()) if (filter.empty())
@@ -1897,12 +1908,10 @@ void ApplyFilter::run()
Statusbar::printf("Using filter \"%1%\"", filter); Statusbar::printf("Using filter \"%1%\"", filter);
} }
// recalculate total length of songs in playlist as it probably changed.
// TODO: check where drawHeader is invoked.
if (myScreen == myPlaylist) if (myScreen == myPlaylist)
{
myPlaylist->EnableHighlighting();
myPlaylist->reloadTotalLength(); myPlaylist->reloadTotalLength();
drawHeader();
}
listsChangeFinisher(); listsChangeFinisher();
} }
@@ -1920,15 +1929,17 @@ void Find::run()
{ {
using Global::wFooter; using Global::wFooter;
Statusbar::lock(); std::string token;
Statusbar::put() << "Find: "; {
std::string findme = wFooter->getString(); Statusbar::ScopedLock lock;
Statusbar::unlock(); Statusbar::put() << "Find: ";
token = wFooter->getString();
}
Statusbar::print("Searching..."); Statusbar::print("Searching...");
auto s = static_cast<Screen<NC::Scrollpad> *>(myScreen); auto s = static_cast<Screen<NC::Scrollpad> *>(myScreen);
s->main().removeProperties(); s->main().removeProperties();
if (findme.empty() || s->main().setProperties(NC::Format::Reverse, findme, NC::Format::NoReverse)) if (token.empty() || s->main().setProperties(NC::Format::Reverse, token, NC::Format::NoReverse))
Statusbar::print("Done"); Statusbar::print("Done");
else else
Statusbar::print("No matching patterns found"); Statusbar::print("No matching patterns found");
@@ -1995,18 +2006,34 @@ void ToggleReplayGainMode::run()
{ {
using Global::wFooter; using Global::wFooter;
Statusbar::lock(); char rgm = 0;
Statusbar::put() << "Replay gain mode? [" << NC::Format::Bold << 'o' << NC::Format::NoBold << "ff/" << NC::Format::Bold << 't' << NC::Format::NoBold << "rack/" << NC::Format::Bold << 'a' << NC::Format::NoBold << "lbum]";
wFooter->refresh();
int answer = 0;
do
{ {
Status::trace(); Statusbar::ScopedLock lock;
answer = wFooter->readKey(); Statusbar::put() << "Replay gain mode? [" << NC::Format::Bold << 'o' << NC::Format::NoBold << "ff/" << NC::Format::Bold << 't' << NC::Format::NoBold << "rack/" << NC::Format::Bold << 'a' << NC::Format::NoBold << "lbum]";
wFooter->refresh();
do
{
Status::trace();
rgm = wFooter->readKey();
}
while (rgm != 't' && rgm != 'a' && rgm != 'o');
}
switch (rgm)
{
case 't':
Mpd.SetReplayGainMode(MPD::rgmTrack);
break;
case 'a':
Mpd.SetReplayGainMode(MPD::rgmAlbum);
break;
case 'o':
Mpd.SetReplayGainMode(MPD::rgmOff);
break;
default: // impossible
throw std::runtime_error(
(boost::format("ToggleReplayGainMode: impossible case reached: %1%") % rgm).str()
);
} }
while (answer != 'o' && answer != 't' && answer != 'a');
Statusbar::unlock();
Mpd.SetReplayGainMode(answer == 't' ? MPD::rgmTrack : (answer == 'a' ? MPD::rgmAlbum : MPD::rgmOff));
Statusbar::printf("Replay gain mode: %1%", Mpd.GetReplayGainMode()); Statusbar::printf("Replay gain mode: %1%", Mpd.GetReplayGainMode());
} }
@@ -2053,35 +2080,37 @@ void ToggleBitrateVisibility::run()
void AddRandomItems::run() void AddRandomItems::run()
{ {
using Global::wFooter; using Global::wFooter;
// FIXME: generalize this type of prompt
Statusbar::lock(); char rnd_type = 0;
Statusbar::put() << "Add random? [" << NC::Format::Bold << 's' << NC::Format::NoBold << "ongs/" << NC::Format::Bold << 'a' << NC::Format::NoBold << "rtists/al" << NC::Format::Bold << 'b' << NC::Format::NoBold << "ums] ";
wFooter->refresh();
int answer = 0;
do
{ {
Status::trace(); Statusbar::ScopedLock lock;
answer = wFooter->readKey(); Statusbar::put() << "Add random? [" << NC::Format::Bold << 's' << NC::Format::NoBold << "ongs/" << NC::Format::Bold << 'a' << NC::Format::NoBold << "rtists/al" << NC::Format::Bold << 'b' << NC::Format::NoBold << "ums] ";
wFooter->refresh();
do
{
Status::trace();
rnd_type = wFooter->readKey();
}
while (rnd_type != 's' && rnd_type != 'a' && rnd_type != 'b');
} }
while (answer != 's' && answer != 'a' && answer != 'b');
Statusbar::unlock();
mpd_tag_type tag_type = MPD_TAG_ARTIST; mpd_tag_type tag_type = MPD_TAG_ARTIST;
std::string tag_type_str ; std::string tag_type_str ;
if (answer != 's') if (rnd_type != 's')
{ {
tag_type = charToTagType(answer); tag_type = charToTagType(rnd_type);
tag_type_str = boost::locale::to_lower(tagTypeToString(tag_type)); tag_type_str = boost::locale::to_lower(tagTypeToString(tag_type));
} }
else else
tag_type_str = "song"; tag_type_str = "song";
Statusbar::lock(); unsigned number;
Statusbar::put() << "Number of random " << tag_type_str << "s: "; {
std::string strnum = wFooter->getString(); Statusbar::ScopedLock lock;
Statusbar::unlock(); Statusbar::put() << "Number of random " << tag_type_str << "s: ";
size_t number = fromString<size_t>(strnum); number = fromString<unsigned>(wFooter->getString());
if (number && (answer == 's' ? Mpd.AddRandomSongs(number) : Mpd.AddRandomTag(tag_type, number))) }
if (number && (rnd_type == 's' ? Mpd.AddRandomSongs(number) : Mpd.AddRandomTag(tag_type, number)))
{ {
Statusbar::printf("%1% random %2%%3% added to playlist", Statusbar::printf("%1% random %2%%3% added to playlist",
number, tag_type_str, number == 1 ? "" : "s" number, tag_type_str, number == 1 ? "" : "s"
@@ -2132,18 +2161,19 @@ void ToggleLibraryTagType::run()
{ {
using Global::wFooter; using Global::wFooter;
Statusbar::lock(); char tag_type = 0;
Statusbar::put() << "Tag type? [" << NC::Format::Bold << 'a' << NC::Format::NoBold << "rtist/album" << NC::Format::Bold << 'A' << NC::Format::NoBold << "rtist/" << NC::Format::Bold << 'y' << NC::Format::NoBold << "ear/" << NC::Format::Bold << 'g' << NC::Format::NoBold << "enre/" << NC::Format::Bold << 'c' << NC::Format::NoBold << "omposer/" << NC::Format::Bold << 'p' << NC::Format::NoBold << "erformer] ";
wFooter->refresh();
int answer = 0;
do
{ {
Status::trace(); Statusbar::ScopedLock lock;
answer = wFooter->readKey(); Statusbar::put() << "Tag type? [" << NC::Format::Bold << 'a' << NC::Format::NoBold << "rtist/album" << NC::Format::Bold << 'A' << NC::Format::NoBold << "rtist/" << NC::Format::Bold << 'y' << NC::Format::NoBold << "ear/" << NC::Format::Bold << 'g' << NC::Format::NoBold << "enre/" << NC::Format::Bold << 'c' << NC::Format::NoBold << "omposer/" << NC::Format::Bold << 'p' << NC::Format::NoBold << "erformer] ";
wFooter->refresh();
do
{
Status::trace();
tag_type = wFooter->readKey();
}
while (tag_type != 'a' && tag_type != 'A' && tag_type != 'y' && tag_type != 'g' && tag_type != 'c' && tag_type != 'p');
} }
while (answer != 'a' && answer != 'A' && answer != 'y' && answer != 'g' && answer != 'c' && answer != 'p'); mpd_tag_type new_tagitem = charToTagType(tag_type);
Statusbar::unlock();
mpd_tag_type new_tagitem = charToTagType(answer);
if (new_tagitem != Config.media_lib_primary_tag) if (new_tagitem != Config.media_lib_primary_tag)
{ {
Config.media_lib_primary_tag = new_tagitem; Config.media_lib_primary_tag = new_tagitem;
@@ -2211,12 +2241,13 @@ void SetSelectedItemsPriority::run()
{ {
using Global::wFooter; using Global::wFooter;
Statusbar::lock(); unsigned prio;
Statusbar::put() << "Set priority [0-255]: "; {
std::string strprio = wFooter->getString(); Statusbar::ScopedLock lock;
Statusbar::unlock(); Statusbar::put() << "Set priority [0-255]: ";
unsigned prio = fromString<unsigned>(strprio); prio = fromString<unsigned>(wFooter->getString());
boundsCheck(prio, 0u, 255u); boundsCheck(prio, 0u, 255u);
}
myPlaylist->SetSelectedItemsPriority(prio); myPlaylist->SetSelectedItemsPriority(prio);
} }
@@ -2234,14 +2265,15 @@ void SetVisualizerSampleMultiplier::run()
# ifdef ENABLE_VISUALIZER # ifdef ENABLE_VISUALIZER
using Global::wFooter; using Global::wFooter;
Statusbar::lock(); double multiplier;
Statusbar::put() << "Set visualizer sample multiplier: "; {
std::string smultiplier = wFooter->getString(); Statusbar::ScopedLock lock;
Statusbar::unlock(); Statusbar::put() << "Set visualizer sample multiplier: ";
multiplier = fromString<double>(wFooter->getString());
double multiplier = fromString<double>(smultiplier); lowerBoundCheck(multiplier, 0.0);
lowerBoundCheck(multiplier, 0.0); Config.visualizer_sample_multiplier = multiplier;
Config.visualizer_sample_multiplier = multiplier; }
Statusbar::printf("Visualizer sample multiplier set to %1%", multiplier);
# endif // ENABLE_VISUALIZER # endif // ENABLE_VISUALIZER
} }
@@ -2254,16 +2286,17 @@ void FilterPlaylistOnPriorities::run()
{ {
using Global::wFooter; using Global::wFooter;
Statusbar::lock(); unsigned prio;
Statusbar::put() << "Show songs with priority higher than: "; {
std::string strprio = wFooter->getString(); Statusbar::ScopedLock lock;
Statusbar::unlock(); Statusbar::put() << "Show songs with priority higher than: ";
unsigned prio = fromString<unsigned>(strprio); prio = fromString<unsigned>(wFooter->getString());
boundsCheck(prio, 0u, 255u); boundsCheck(prio, 0u, 255u);
myPlaylist->main().filter(myPlaylist->main().begin(), myPlaylist->main().end(), myPlaylist->main().filter(myPlaylist->main().begin(), myPlaylist->main().end(),
[prio](const NC::Menu<MPD::Song>::Item &s) { [prio](const NC::Menu<MPD::Song>::Item &s) {
return s.value().getPrio() > prio; return s.value().getPrio() > prio;
}); });
}
Statusbar::printf("Playlist filtered (songs with priority higher than %1%)", prio); Statusbar::printf("Playlist filtered (songs with priority higher than %1%)", prio);
} }
@@ -2710,8 +2743,8 @@ void seek()
return; return;
} }
Progressbar::lock(); Progressbar::ScopedLock progressbar_lock;
Statusbar::lock(); Statusbar::ScopedLock statusbar_lock;
unsigned songpos = Status::State::elapsedTime(); unsigned songpos = Status::State::elapsedTime();
auto t = Timer; auto t = Timer;
@@ -2756,6 +2789,7 @@ void seek()
*wFooter << NC::Format::Bold; *wFooter << NC::Format::Bold;
std::string tracklength; std::string tracklength;
// FIXME: merge this with the code in status.cpp
switch (Config.design) switch (Config.design)
{ {
case Design::Classic: case Design::Classic:
@@ -2794,9 +2828,6 @@ void seek()
Mpd.Seek(Status::State::currentSongPosition(), songpos); Mpd.Seek(Status::State::currentSongPosition(), songpos);
wFooter->setTimeout(old_timeout); wFooter->setTimeout(old_timeout);
Progressbar::unlock();
Statusbar::unlock();
} }
void findItem(const Find direction) void findItem(const Find direction)
@@ -2807,31 +2838,25 @@ void findItem(const Find direction)
assert(w); assert(w);
assert(w->allowsSearching()); assert(w->allowsSearching());
Statusbar::lock(); std::string token;
Statusbar::put() << "Find " << (direction == Find::Forward ? "forward" : "backward") << ": "; {
std::string findme = wFooter->getString(); Statusbar::ScopedLock lock;
Statusbar::unlock(); Statusbar::put() << "Find " << (direction == Find::Forward ? "forward" : "backward") << ": ";
token = wFooter->getString();
}
if (!findme.empty()) Statusbar::print("Searching...");
Statusbar::print("Searching..."); bool success = w->search(token);
bool success = w->search(findme);
if (findme.empty())
return;
if (success) if (success)
Statusbar::print("Searching finished"); Statusbar::print("Searching finished");
else else
Statusbar::printf("Unable to find \"%1%\"", findme); Statusbar::printf("Unable to find \"%1%\"", token);
if (direction == ::Find::Forward) if (direction == Find::Forward)
w->nextFound(Config.wrapped_search); w->nextFound(Config.wrapped_search);
else else
w->prevFound(Config.wrapped_search); w->prevFound(Config.wrapped_search);
if (myScreen == myPlaylist)
myPlaylist->EnableHighlighting();
} }
void listsChangeFinisher() void listsChangeFinisher()

View File

@@ -152,11 +152,10 @@ void SearchEngine::enterPressed()
size_t option = w.choice(); size_t option = w.choice();
if (option > ConstraintsNumber && option < SearchButton) if (option > ConstraintsNumber && option < SearchButton)
w.current().value().buffer().clear(); w.current().value().buffer().clear();
if (option < SearchButton)
Statusbar::lock();
if (option < ConstraintsNumber) if (option < ConstraintsNumber)
{ {
Statusbar::ScopedLock lock;
std::string constraint = ConstraintsNames[option]; std::string constraint = ConstraintsNames[option];
Statusbar::put() << NC::Format::Bold << constraint << NC::Format::NoBold << ": "; Statusbar::put() << NC::Format::Bold << constraint << NC::Format::NoBold << ": ";
itsConstraints[option] = Global::wFooter->getString(itsConstraints[option]); itsConstraints[option] = Global::wFooter->getString(itsConstraints[option]);
@@ -210,9 +209,6 @@ void SearchEngine::enterPressed()
} }
else else
addSongToPlaylist(w.current().value().song(), true); addSongToPlaylist(w.current().value().song(), true);
if (option < SearchButton)
Statusbar::unlock();
} }
void SearchEngine::spacePressed() void SearchEngine::spacePressed()

View File

@@ -223,12 +223,13 @@ void SelectedItemsAdder::addToCurrentPlaylist()
void SelectedItemsAdder::addToNewPlaylist() const void SelectedItemsAdder::addToNewPlaylist() const
{ {
Statusbar::lock(); std::string playlist;
Statusbar::put() << "Save playlist as: "; {
std::string playlist = Global::wFooter->getString(); Statusbar::ScopedLock lock;
Statusbar::unlock(); Statusbar::put() << "Save playlist as: ";
if (!playlist.empty()) playlist = Global::wFooter->getString();
addToExistingPlaylist(playlist); }
addToExistingPlaylist(playlist);
} }
void SelectedItemsAdder::addToExistingPlaylist(const std::string &playlist) const void SelectedItemsAdder::addToExistingPlaylist(const std::string &playlist) const

View File

@@ -28,30 +28,31 @@
using Global::wFooter; using Global::wFooter;
namespace {// namespace {
boost::posix_time::ptime statusbarLockTime; bool progressbar_block_update = false;
boost::posix_time::seconds statusbarLockDelay(-1);
bool statusbarBlockUpdate = false; boost::posix_time::ptime statusbar_lock_time;
bool progressbarBlockUpdate = false; boost::posix_time::seconds statusbar_lock_delay(-1);
bool statusbarAllowUnlock = true;
bool statusbar_block_update = false;
bool statusbar_allow_unlock = true;
} }
void Progressbar::lock() Progressbar::ScopedLock::ScopedLock() noexcept
{ {
progressbarBlockUpdate = true; progressbar_block_update = true;
} }
void Progressbar::unlock() Progressbar::ScopedLock::~ScopedLock() noexcept
{ {
progressbarBlockUpdate = false; progressbar_block_update = false;
} }
bool Progressbar::isUnlocked() bool Progressbar::isUnlocked()
{ {
return !progressbarBlockUpdate; return !progressbar_block_update;
} }
void Progressbar::draw(unsigned int elapsed, unsigned int time) void Progressbar::draw(unsigned int elapsed, unsigned int time)
@@ -85,24 +86,26 @@ void Progressbar::draw(unsigned int elapsed, unsigned int time)
*wFooter << NC::Format::NoBold; *wFooter << NC::Format::NoBold;
} }
void Statusbar::lock() Statusbar::ScopedLock::ScopedLock() noexcept
{ {
// lock
if (Config.statusbar_visibility) if (Config.statusbar_visibility)
statusbarBlockUpdate = true; statusbar_block_update = true;
else else
progressbarBlockUpdate = true; progressbar_block_update = true;
statusbarAllowUnlock = false; statusbar_allow_unlock = false;
} }
void Statusbar::unlock() Statusbar::ScopedLock::~ScopedLock() noexcept
{ {
statusbarAllowUnlock = true; // unlock
if (statusbarLockDelay.is_negative()) statusbar_allow_unlock = true;
if (statusbar_lock_delay.is_negative())
{ {
if (Config.statusbar_visibility) if (Config.statusbar_visibility)
statusbarBlockUpdate = false; statusbar_block_update = false;
else else
progressbarBlockUpdate = false; progressbar_block_update = false;
} }
if (Status::State::player() == MPD::psStop) if (Status::State::player() == MPD::psStop)
{ {
@@ -121,23 +124,23 @@ void Statusbar::unlock()
bool Statusbar::isUnlocked() bool Statusbar::isUnlocked()
{ {
return !statusbarBlockUpdate; return !statusbar_block_update;
} }
void Statusbar::tryRedraw() void Statusbar::tryRedraw()
{ {
using Global::Timer; using Global::Timer;
if (statusbarLockDelay > boost::posix_time::seconds(0) if (statusbar_lock_delay > boost::posix_time::seconds(0)
&& Timer - statusbarLockTime > statusbarLockDelay) && Timer - statusbar_lock_time > statusbar_lock_delay)
{ {
statusbarLockDelay = boost::posix_time::seconds(-1); statusbar_lock_delay = boost::posix_time::seconds(-1);
if (Config.statusbar_visibility) if (Config.statusbar_visibility)
statusbarBlockUpdate = !statusbarAllowUnlock; statusbar_block_update = !statusbar_allow_unlock;
else else
progressbarBlockUpdate = !statusbarAllowUnlock; progressbar_block_update = !statusbar_allow_unlock;
if (!statusbarBlockUpdate && !progressbarBlockUpdate) if (!statusbar_block_update && !progressbar_block_update)
{ {
switch (Config.design) switch (Config.design)
{ {
@@ -171,14 +174,14 @@ NC::Window &Statusbar::put()
void Statusbar::print(int delay, const std::string &message) void Statusbar::print(int delay, const std::string &message)
{ {
if (statusbarAllowUnlock) if (statusbar_allow_unlock)
{ {
statusbarLockTime = Global::Timer; statusbar_lock_time = Global::Timer;
statusbarLockDelay = boost::posix_time::seconds(delay); statusbar_lock_delay = boost::posix_time::seconds(delay);
if (Config.statusbar_visibility) if (Config.statusbar_visibility)
statusbarBlockUpdate = true; statusbar_block_update = true;
else else
progressbarBlockUpdate = true; progressbar_block_update = true;
wFooter->goToXY(0, Config.statusbar_visibility); wFooter->goToXY(0, Config.statusbar_visibility);
*wFooter << message << wclrtoeol; *wFooter << message << wclrtoeol;
wFooter->refresh(); wFooter->refresh();

View File

@@ -29,11 +29,11 @@
namespace Progressbar {// namespace Progressbar {//
/// locks progressbar (usually used for seeking) struct ScopedLock
void lock(); {
ScopedLock() noexcept;
/// unlocks progressbar (usually right after seeking is done) ~ScopedLock() noexcept;
void unlock(); };
/// @return true if progressbar is unlocked /// @return true if progressbar is unlocked
bool isUnlocked(); bool isUnlocked();
@@ -43,13 +43,13 @@ void draw(unsigned elapsed, unsigned time);
} }
namespace Statusbar{// namespace Statusbar {
/// locks statusbar (usually for prompting the user) struct ScopedLock
void lock(); {
ScopedLock() noexcept;
/// unlocks statusbar (usually after prompting the user) ~ScopedLock() noexcept;
void unlock(); };
/// @return true if statusbar is unlocked /// @return true if statusbar is unlocked
bool isUnlocked(); bool isUnlocked();

View File

@@ -356,16 +356,15 @@ void TagEditor::enterPressed()
if (pos == 0) // change pattern if (pos == 0) // change pattern
{ {
Statusbar::lock(); std::string new_pattern;
Statusbar::put() << "Pattern: ";
std::string new_pattern = wFooter->getString(Config.pattern);
Statusbar::unlock();
if (!new_pattern.empty())
{ {
Config.pattern = new_pattern; Statusbar::ScopedLock lock;
FParser->at(0).value() = "Pattern: "; Statusbar::put() << "Pattern: ";
FParser->at(0).value() += Config.pattern; new_pattern = wFooter->getString(Config.pattern);
} }
Config.pattern = new_pattern;
FParser->at(0).value() = "Pattern: ";
FParser->at(0).value() += Config.pattern;
} }
else if (pos == 1 || pos == 4) // preview or proceed else if (pos == 1 || pos == 4) // preview or proceed
{ {
@@ -493,19 +492,17 @@ void TagEditor::enterPressed()
MPD::MutableSong::SetFunction set = SongInfo::Tags[id].Set; MPD::MutableSong::SetFunction set = SongInfo::Tags[id].Set;
if (id > 0 && w == TagTypes) if (id > 0 && w == TagTypes)
{ {
Statusbar::lock(); Statusbar::ScopedLock lock;
Statusbar::put() << NC::Format::Bold << TagTypes->current().value() << NC::Format::NoBold << ": "; Statusbar::put() << NC::Format::Bold << TagTypes->current().value() << NC::Format::NoBold << ": ";
std::string new_tag = wFooter->getString(Tags->current().value().getTags(get, Config.tags_separator)); std::string new_tag = wFooter->getString(Tags->current().value().getTags(get, Config.tags_separator));
Statusbar::unlock();
for (auto it = EditedSongs.begin(); it != EditedSongs.end(); ++it) for (auto it = EditedSongs.begin(); it != EditedSongs.end(); ++it)
(*it)->setTags(set, new_tag, Config.tags_separator); (*it)->setTags(set, new_tag, Config.tags_separator);
} }
else if (w == Tags) else if (w == Tags)
{ {
Statusbar::lock(); Statusbar::ScopedLock lock;
Statusbar::put() << NC::Format::Bold << TagTypes->current().value() << NC::Format::NoBold << ": "; Statusbar::put() << NC::Format::Bold << TagTypes->current().value() << NC::Format::NoBold << ": ";
std::string new_tag = wFooter->getString(Tags->current().value().getTags(get, Config.tags_separator)); std::string new_tag = wFooter->getString(Tags->current().value().getTags(get, Config.tags_separator));
Statusbar::unlock();
if (new_tag != Tags->current().value().getTags(get, Config.tags_separator)) if (new_tag != Tags->current().value().getTags(get, Config.tags_separator))
Tags->current().value().setTags(set, new_tag, Config.tags_separator); Tags->current().value().setTags(set, new_tag, Config.tags_separator);
Tags->scroll(NC::Scroll::Down); Tags->scroll(NC::Scroll::Down);
@@ -522,15 +519,14 @@ void TagEditor::enterPressed()
} }
else if (w == Tags) else if (w == Tags)
{ {
Statusbar::ScopedLock lock;
MPD::MutableSong &s = Tags->current().value(); MPD::MutableSong &s = Tags->current().value();
std::string old_name = s.getNewName().empty() ? s.getName() : s.getNewName(); std::string old_name = s.getNewName().empty() ? s.getName() : s.getNewName();
size_t last_dot = old_name.rfind("."); size_t last_dot = old_name.rfind(".");
std::string extension = old_name.substr(last_dot); std::string extension = old_name.substr(last_dot);
old_name = old_name.substr(0, last_dot); old_name = old_name.substr(0, last_dot);
Statusbar::lock();
Statusbar::put() << NC::Format::Bold << "New filename: " << NC::Format::NoBold; Statusbar::put() << NC::Format::Bold << "New filename: " << NC::Format::NoBold;
std::string new_name = wFooter->getString(old_name); std::string new_name = wFooter->getString(old_name);
Statusbar::unlock();
if (!new_name.empty()) if (!new_name.empty())
s.setNewName(new_name + extension); s.setNewName(new_name + extension);
Tags->scroll(NC::Scroll::Down); Tags->scroll(NC::Scroll::Down);

View File

@@ -101,9 +101,9 @@ std::wstring TinyTagEditor::title()
void TinyTagEditor::enterPressed() void TinyTagEditor::enterPressed()
{ {
size_t option = w.choice(); size_t option = w.choice();
Statusbar::lock();
if (option < 19) // separator after comment if (option < 19) // separator after comment
{ {
Statusbar::ScopedLock lock;
size_t pos = option-8; size_t pos = option-8;
Statusbar::put() << NC::Format::Bold << SongInfo::Tags[pos].Name << ": " << NC::Format::NoBold; Statusbar::put() << NC::Format::Bold << SongInfo::Tags[pos].Name << ": " << NC::Format::NoBold;
itsEdited.setTags(SongInfo::Tags[pos].Set, Global::wFooter->getString( itsEdited.setTags(SongInfo::Tags[pos].Set, Global::wFooter->getString(
@@ -114,6 +114,7 @@ void TinyTagEditor::enterPressed()
} }
else if (option == 20) else if (option == 20)
{ {
Statusbar::ScopedLock lock;
Statusbar::put() << NC::Format::Bold << "Filename: " << NC::Format::NoBold; Statusbar::put() << NC::Format::Bold << "Filename: " << NC::Format::NoBold;
std::string filename = itsEdited.getNewName().empty() ? itsEdited.getName() : itsEdited.getNewName(); std::string filename = itsEdited.getNewName().empty() ? itsEdited.getName() : itsEdited.getNewName();
size_t dot = filename.rfind("."); size_t dot = filename.rfind(".");
@@ -127,7 +128,6 @@ void TinyTagEditor::enterPressed()
w.at(option).value() << NC::Format::Bold << "Filename:" << NC::Format::NoBold << ' ' << (itsEdited.getNewName().empty() ? itsEdited.getName() : itsEdited.getNewName()); w.at(option).value() << NC::Format::Bold << "Filename:" << NC::Format::NoBold << ' ' << (itsEdited.getNewName().empty() ? itsEdited.getName() : itsEdited.getNewName());
} }
} }
Statusbar::unlock();
if (option == 22) if (option == 22)
{ {