From a8b46a8e4707a0a1f8b268188d556832a10cc753 Mon Sep 17 00:00:00 2001 From: Andrzej Rybczak Date: Fri, 31 Oct 2014 20:04:20 +0100 Subject: [PATCH] actions: make askYesNoQuestion use NC::Window::prompt --- src/actions.cpp | 38 ++++++++++++++------------------------ src/actions.h | 6 +++--- src/statusbar.cpp | 21 +++++++++++++++++++++ src/statusbar.h | 20 ++++++++++++++++++++ src/strbuffer.h | 4 ++-- src/tag_editor.cpp | 4 ++-- 6 files changed, 62 insertions(+), 31 deletions(-) diff --git a/src/actions.cpp b/src/actions.cpp index e2e6a322..bf64402c 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -252,22 +252,15 @@ void setWindowsDimensions() FooterHeight = Config.statusbar_visibility ? 2 : 1; } -bool askYesNoQuestion(const boost::format &fmt, void (*callback)()) +bool askYesNoQuestion(const boost::format &fmt) { - using Global::wFooter; - Statusbar::ScopedLock lock; - Statusbar::put() << fmt.str() << " [" << NC::Format::Bold << 'y' << NC::Format::NoBold << '/' << NC::Format::Bold << 'n' << NC::Format::NoBold << "]"; - wFooter->refresh(); - int answer = 0; - do - { - if (callback) - callback(); - answer = wFooter->readKey(); - } - while (answer != 'y' && answer != 'n'); - return answer == 'y'; + Statusbar::put() << fmt.str() + << " [" << NC::Format::Bold << 'y' << NC::Format::NoBold + << '/' << NC::Format::Bold << 'n' << NC::Format::NoBold + << "] "; + auto answer = Statusbar::Helpers::promptReturnOneOf({"y", "n"}); + return answer == "y"; } bool isMPDMusicDirSet() @@ -685,7 +678,7 @@ void DeleteBrowserItems::run() question = boost::format("Delete %1% \"%2%\"?") % itemTypeToString(item.type) % wideShorten(iname, COLS-question.size()-10); } - bool yes = askYesNoQuestion(question, Status::trace); + bool yes = askYesNoQuestion(question); if (yes) { bool success = true; @@ -734,7 +727,7 @@ void DeleteStoredPlaylist::run() else question = boost::format("Delete playlist \"%1%\"?") % wideShorten(myPlaylistEditor->Playlists.current().value(), COLS-question.size()-10); - bool yes = askYesNoQuestion(question, Status::trace); + bool yes = askYesNoQuestion(question); if (yes) { auto list = getSelectedOrCurrent(myPlaylistEditor->Playlists.begin(), myPlaylistEditor->Playlists.end(), myPlaylistEditor->Playlists.currentI()); @@ -806,8 +799,7 @@ void SavePlaylist::run() if (e.code() == MPD_SERVER_ERROR_EXIST) { bool yes = askYesNoQuestion( - boost::format("Playlist \"%1%\" already exists, overwrite?") % playlist_name, - Status::trace + boost::format("Playlist \"%1%\" already exists, overwrite?") % playlist_name ); if (yes) { @@ -1761,7 +1753,7 @@ void CropMainPlaylist::run() return; bool yes = true; if (Config.ask_before_clearing_playlists) - yes = askYesNoQuestion("Do you really want to crop main playlist?", Status::trace); + yes = askYesNoQuestion("Do you really want to crop main playlist?"); if (yes) { Statusbar::print("Cropping playlist..."); @@ -1787,8 +1779,7 @@ void CropPlaylist::run() bool yes = true; if (Config.ask_before_clearing_playlists) yes = askYesNoQuestion( - boost::format("Do you really want to crop playlist \"%1%\"?") % playlist, - Status::trace + boost::format("Do you really want to crop playlist \"%1%\"?") % playlist ); if (yes) { @@ -1803,7 +1794,7 @@ void ClearMainPlaylist::run() { bool yes = true; if (Config.ask_before_clearing_playlists) - yes = askYesNoQuestion("Do you really want to clear main playlist?", Status::trace); + yes = askYesNoQuestion("Do you really want to clear main playlist?"); if (yes) { auto delete_fun = boost::bind(&MPD::Connection::Delete, _1, _2); @@ -1828,8 +1819,7 @@ void ClearPlaylist::run() bool yes = true; if (Config.ask_before_clearing_playlists) yes = askYesNoQuestion( - boost::format("Do you really want to clear playlist \"%1%\"?") % playlist, - Status::trace + boost::format("Do you really want to clear playlist \"%1%\"?") % playlist ); if (yes) { diff --git a/src/actions.h b/src/actions.h index d828c2eb..32fcbd1b 100644 --- a/src/actions.h +++ b/src/actions.h @@ -67,10 +67,10 @@ void setResizeFlags(); void resizeScreen(bool reload_main_window); void setWindowsDimensions(); -bool askYesNoQuestion(const boost::format &question, void (*callback)()); -inline bool askYesNoQuestion(const std::string &question, void (*callback)()) +bool askYesNoQuestion(const boost::format &question); +inline bool askYesNoQuestion(const std::string &question) { - return askYesNoQuestion(boost::format(question), callback); + return askYesNoQuestion(boost::format(question)); } bool isMPDMusicDirSet(); diff --git a/src/statusbar.cpp b/src/statusbar.cpp index 9cda2f03..2baf9e52 100644 --- a/src/statusbar.cpp +++ b/src/statusbar.cpp @@ -199,6 +199,27 @@ bool Statusbar::Helpers::mainHook(const char *) return true; } +std::string Statusbar::Helpers::promptReturnOneOf(std::vector &&values) +{ + Statusbar::Helpers::ImmediatelyReturnOneOf prompt_hook(std::move(values)); + NC::Window::ScopedPromptHook hook(*wFooter, prompt_hook); + int x = wFooter->getX(), y = wFooter->getY(); + std::string result; + do + { + wFooter->goToXY(x, y); + result = wFooter->prompt(); + } + while (!prompt_hook.isOneOf(result)); + return result; +} + +bool Statusbar::Helpers::ImmediatelyReturnOneOf::operator()(const char *s) const +{ + Status::trace(); + return !isOneOf(s); +} + bool Statusbar::Helpers::ApplyFilterImmediately::operator()(const char *s) { using Global::myScreen; diff --git a/src/statusbar.h b/src/statusbar.h index 7d03b28c..655da276 100644 --- a/src/statusbar.h +++ b/src/statusbar.h @@ -69,6 +69,26 @@ void mpd(); /// called each time user types another character while inside Window::getString bool mainHook(const char *); +/// prompt and return one of the strings specified in the vector +std::string promptReturnOneOf(std::vector &&values); + +struct ImmediatelyReturnOneOf +{ + ImmediatelyReturnOneOf(std::vector arg) + : m_values(std::move(arg)) + { } + + bool operator()(const char *s) const; + + template + bool isOneOf(StringT &&s) const { + return std::find(m_values.begin(), m_values.end(), std::forward(s)) != m_values.end(); + } + +private: + std::vector m_values; +}; + /// called each time user changes current filter (while being inside Window::getString) struct ApplyFilterImmediately { diff --git a/src/strbuffer.h b/src/strbuffer.h index 7a23932f..aab7f6da 100644 --- a/src/strbuffer.h +++ b/src/strbuffer.h @@ -91,7 +91,7 @@ public: typedef std::set Properties; template - BasicBuffer(Args... args) + BasicBuffer(Args&&... args) { construct(std::forward(args)...); } @@ -190,7 +190,7 @@ public: private: void construct() { } template - void construct(ArgT &&arg, Args... args) + void construct(ArgT &&arg, Args&&... args) { *this << std::forward(arg); construct(std::forward(args)...); diff --git a/src/tag_editor.cpp b/src/tag_editor.cpp index 79e0453a..be442659 100644 --- a/src/tag_editor.cpp +++ b/src/tag_editor.cpp @@ -468,7 +468,7 @@ void TagEditor::enterPressed() if (w == TagTypes && id == 5) { - bool yes = Actions::askYesNoQuestion("Number tracks?", Status::trace); + bool yes = Actions::askYesNoQuestion("Number tracks?"); if (yes) { auto it = EditedSongs.begin(); @@ -963,7 +963,7 @@ bool TagEditor::ifAnyModifiedAskForDiscarding() { bool result = true; if (isAnyModified(*Tags)) - result = Actions::askYesNoQuestion("There are pending changes, are you sure?", Status::trace); + result = Actions::askYesNoQuestion("There are pending changes, are you sure?"); return result; }