From 035bc65bf986574119ba5018083d1b0d9be84eca Mon Sep 17 00:00:00 2001 From: Andrzej Rybczak Date: Sun, 26 Mar 2017 06:02:53 +0200 Subject: [PATCH] Make single character prompts more robust --- src/actions.cpp | 12 ++++++------ src/curses/window.h | 4 +++- src/statusbar.cpp | 17 +++++++++-------- src/statusbar.h | 4 ++-- 4 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/actions.cpp b/src/actions.cpp index 6374d85..87cca2c 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -281,9 +281,9 @@ void confirmAction(const boost::format &description) << " [" << NC::Format::Bold << 'y' << NC::Format::NoBold << '/' << NC::Format::Bold << 'n' << NC::Format::NoBold << "] "; - auto answer = Statusbar::Helpers::promptReturnOneOf({"y", "n"}); - if (answer == "n") - throw NC::PromptAborted(std::move(answer)); + char answer = Statusbar::Helpers::promptReturnOneOf({'y', 'n'}); + if (answer == 'n') + throw NC::PromptAborted(std::string(1, answer)); } bool isMPDMusicDirSet() @@ -2106,7 +2106,7 @@ void ToggleReplayGainMode::run() << "/" << NC::Format::Bold << 't' << NC::Format::NoBold << "rack" << "/" << NC::Format::Bold << 'a' << NC::Format::NoBold << "lbum" << "] "; - rgm = Statusbar::Helpers::promptReturnOneOf({"t", "a", "o"})[0]; + rgm = Statusbar::Helpers::promptReturnOneOf({'t', 'a', 'o'}); } switch (rgm) { @@ -2176,7 +2176,7 @@ void AddRandomItems::run() << "/" << "album" << NC::Format::Bold << 'A' << NC::Format::NoBold << "rtists" << "/" << "al" << NC::Format::Bold << 'b' << NC::Format::NoBold << "ums" << "] "; - rnd_type = Statusbar::Helpers::promptReturnOneOf({"s", "a", "A", "b"})[0]; + rnd_type = Statusbar::Helpers::promptReturnOneOf({'s', 'a', 'A', 'b'}); } mpd_tag_type tag_type = MPD_TAG_ARTIST; @@ -2262,7 +2262,7 @@ void ToggleLibraryTagType::run() << "/" << NC::Format::Bold << 'c' << NC::Format::NoBold << "omposer" << "/" << NC::Format::Bold << 'p' << NC::Format::NoBold << "erformer" << "] "; - tag_type = Statusbar::Helpers::promptReturnOneOf({"a", "A", "y", "g", "c", "p"})[0]; + tag_type = Statusbar::Helpers::promptReturnOneOf({'a', 'A', 'y', 'g', 'c', 'p'}); } mpd_tag_type new_tagitem = charToTagType(tag_type); if (new_tagitem != Config.media_lib_primary_tag) diff --git a/src/curses/window.h b/src/curses/window.h index 78bfce8..d748a1e 100644 --- a/src/curses/window.h +++ b/src/curses/window.h @@ -132,9 +132,11 @@ const Type EoF = Special | 279; /// @see Window::getString() struct PromptAborted : std::exception { + PromptAborted() { } + template PromptAborted(ArgT &&prompt) - : m_prompt(std::forward(prompt)) { } + : m_prompt(std::forward(prompt)) { } virtual const char *what() const noexcept override { return m_prompt.c_str(); } diff --git a/src/statusbar.cpp b/src/statusbar.cpp index 0ca27a2..09e5e4f 100644 --- a/src/statusbar.cpp +++ b/src/statusbar.cpp @@ -195,18 +195,19 @@ bool Statusbar::Helpers::mainHook(const char *) return true; } -std::string Statusbar::Helpers::promptReturnOneOf(std::vector values) +char Statusbar::Helpers::promptReturnOneOf(const 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; + if (values.empty()) + throw std::logic_error("empty vector of acceptable input"); + NC::Key::Type result; do { - wFooter->goToXY(x, y); - result = wFooter->prompt(); + wFooter->refresh(); + result = wFooter->readKey(); + if (result == NC::Key::Ctrl_C || result == NC::Key::Ctrl_G) + throw NC::PromptAborted(); } - while (!prompt_hook.isOneOf(result)); + while (std::find(values.begin(), values.end(), result) == values.end()); return result; } diff --git a/src/statusbar.h b/src/statusbar.h index efd2abe..58b0d2c 100644 --- a/src/statusbar.h +++ b/src/statusbar.h @@ -69,8 +69,8 @@ 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); +/// prompt and return one of the characters specified in the vector +char promptReturnOneOf(const std::vector &values); struct ImmediatelyReturnOneOf { -- 2.11.4.GIT