summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/actions.cpp42
-rw-r--r--src/ncmpcpp.cpp2
-rw-r--r--src/search_engine.cpp2
-rw-r--r--src/sel_items_adder.cpp2
-rw-r--r--src/status.cpp4
-rw-r--r--src/tag_editor.cpp8
-rw-r--r--src/tiny_tag_editor.cpp4
-rw-r--r--src/window.cpp33
-rw-r--r--src/window.h70
9 files changed, 72 insertions, 95 deletions
diff --git a/src/actions.cpp b/src/actions.cpp
index 351c4b7a..e2e6a322 100644
--- a/src/actions.cpp
+++ b/src/actions.cpp
@@ -779,7 +779,7 @@ void SavePlaylist::run()
{
Statusbar::ScopedLock lock;
Statusbar::put() << "Save playlist as: ";
- playlist_name = wFooter->getString();
+ playlist_name = wFooter->prompt();
}
if (playlist_name.find("/") != std::string::npos)
{
@@ -842,11 +842,11 @@ void ExecuteCommand::run()
std::string cmd_name;
{
Statusbar::ScopedLock lock;
- NC::Window::ScopedStringHelper helper(*wFooter,
+ NC::Window::ScopedPromptHook helper(*wFooter,
Statusbar::Helpers::TryExecuteImmediateCommand()
);
Statusbar::put() << NC::Format::Bold << ":" << NC::Format::NoBold;
- cmd_name = wFooter->getString();
+ cmd_name = wFooter->prompt();
}
auto cmd = Bindings.findCommand(cmd_name);
@@ -968,7 +968,7 @@ void Add::run()
{
Statusbar::ScopedLock lock;
Statusbar::put() << (myScreen == myPlaylistEditor ? "Add to playlist: " : "Add: ");
- path = wFooter->getString();
+ path = wFooter->prompt();
}
Statusbar::put() << "Adding...";
@@ -1275,7 +1275,7 @@ void SetCrossfade::run()
Statusbar::ScopedLock lock;
Statusbar::put() << "Set crossfade to: ";
- auto crossfade = fromString<unsigned>(wFooter->getString());
+ auto crossfade = fromString<unsigned>(wFooter->prompt());
lowerBoundCheck(crossfade, 0u);
Config.crossfade_time = crossfade;
Mpd.SetCrossfade(crossfade);
@@ -1289,7 +1289,7 @@ void SetVolume::run()
{
Statusbar::ScopedLock lock;
Statusbar::put() << "Set volume to: ";
- volume = fromString<unsigned>(wFooter->getString());
+ volume = fromString<unsigned>(wFooter->prompt());
boundsCheck(volume, 0u, 100u);
Mpd.SetVolume(volume);
}
@@ -1335,7 +1335,7 @@ void EditLibraryTag::run()
{
Statusbar::ScopedLock lock;
Statusbar::put() << NC::Format::Bold << tagTypeToString(Config.media_lib_primary_tag) << NC::Format::NoBold << ": ";
- new_tag = wFooter->getString(myLibrary->Tags.current().value().tag());
+ new_tag = wFooter->prompt(myLibrary->Tags.current().value().tag());
}
if (!new_tag.empty() && new_tag != myLibrary->Tags.current().value().tag())
{
@@ -1393,7 +1393,7 @@ void EditLibraryAlbum::run()
{
Statusbar::ScopedLock lock;
Statusbar::put() << NC::Format::Bold << "Album: " << NC::Format::NoBold;
- new_album = wFooter->getString(myLibrary->Albums.current().value().entry().album());
+ new_album = wFooter->prompt(myLibrary->Albums.current().value().entry().album());
}
if (!new_album.empty() && new_album != myLibrary->Albums.current().value().entry().album())
{
@@ -1452,7 +1452,7 @@ void EditDirectoryName::run()
{
Statusbar::ScopedLock lock;
Statusbar::put() << NC::Format::Bold << "Directory: " << NC::Format::NoBold;
- new_dir = wFooter->getString(old_dir);
+ new_dir = wFooter->prompt(old_dir);
}
if (!new_dir.empty() && new_dir != old_dir)
{
@@ -1487,7 +1487,7 @@ void EditDirectoryName::run()
{
Statusbar::ScopedLock lock;
Statusbar::put() << NC::Format::Bold << "Directory: " << NC::Format::NoBold;
- new_dir = wFooter->getString(old_dir);
+ new_dir = wFooter->prompt(old_dir);
}
if (!new_dir.empty() && new_dir != old_dir)
{
@@ -1530,7 +1530,7 @@ void EditPlaylistName::run()
{
Statusbar::ScopedLock lock;
Statusbar::put() << NC::Format::Bold << "Playlist: " << NC::Format::NoBold;
- new_name = wFooter->getString(old_name);
+ new_name = wFooter->prompt(old_name);
}
if (!new_name.empty() && new_name != old_name)
{
@@ -1604,7 +1604,7 @@ void ToggleScreenLock::run()
{
Statusbar::ScopedLock lock;
Statusbar::put() << "% of the locked screen's width to be reserved (20-80): ";
- part = fromString<unsigned>(wFooter->getString(boost::lexical_cast<std::string>(part)));
+ part = fromString<unsigned>(wFooter->prompt(boost::lexical_cast<std::string>(part)));
}
boundsCheck(part, 20u, 80u);
Config.locked_screen_width_part = part/100.0;
@@ -1648,7 +1648,7 @@ void JumpToPositionInSong::run()
{
Statusbar::ScopedLock lock;
Statusbar::put() << "Position to go (in %/m:ss/seconds(s)): ";
- spos = wFooter->getString();
+ spos = wFooter->prompt();
}
boost::regex rx;
@@ -1883,11 +1883,11 @@ void ApplyFilter::run()
try
{
Statusbar::ScopedLock lock;
- NC::Window::ScopedStringHelper helper(*wFooter,
+ NC::Window::ScopedPromptHook helper(*wFooter,
Statusbar::Helpers::ApplyFilterImmediately(f, filter)
);
Statusbar::put() << NC::Format::Bold << "Apply filter: " << NC::Format::NoBold;
- wFooter->getString(filter);
+ wFooter->prompt(filter);
}
catch (NC::PromptAborted &)
{
@@ -1935,7 +1935,7 @@ void Find::run()
{
Statusbar::ScopedLock lock;
Statusbar::put() << "Find: ";
- token = wFooter->getString();
+ token = wFooter->prompt();
}
Statusbar::print("Searching...");
@@ -2110,7 +2110,7 @@ void AddRandomItems::run()
{
Statusbar::ScopedLock lock;
Statusbar::put() << "Number of random " << tag_type_str << "s: ";
- number = fromString<unsigned>(wFooter->getString());
+ number = fromString<unsigned>(wFooter->prompt());
}
if (number && (rnd_type == 's' ? Mpd.AddRandomSongs(number) : Mpd.AddRandomTag(tag_type, number)))
{
@@ -2247,7 +2247,7 @@ void SetSelectedItemsPriority::run()
{
Statusbar::ScopedLock lock;
Statusbar::put() << "Set priority [0-255]: ";
- prio = fromString<unsigned>(wFooter->getString());
+ prio = fromString<unsigned>(wFooter->prompt());
boundsCheck(prio, 0u, 255u);
}
myPlaylist->SetSelectedItemsPriority(prio);
@@ -2271,7 +2271,7 @@ void SetVisualizerSampleMultiplier::run()
{
Statusbar::ScopedLock lock;
Statusbar::put() << "Set visualizer sample multiplier: ";
- multiplier = fromString<double>(wFooter->getString());
+ multiplier = fromString<double>(wFooter->prompt());
lowerBoundCheck(multiplier, 0.0);
Config.visualizer_sample_multiplier = multiplier;
}
@@ -2292,7 +2292,7 @@ void FilterPlaylistOnPriorities::run()
{
Statusbar::ScopedLock lock;
Statusbar::put() << "Show songs with priority higher than: ";
- prio = fromString<unsigned>(wFooter->getString());
+ prio = fromString<unsigned>(wFooter->prompt());
boundsCheck(prio, 0u, 255u);
myPlaylist->main().filter(myPlaylist->main().begin(), myPlaylist->main().end(),
[prio](const NC::Menu<MPD::Song>::Item &s) {
@@ -2844,7 +2844,7 @@ void findItem(const Find direction)
{
Statusbar::ScopedLock lock;
Statusbar::put() << "Find " << (direction == Find::Forward ? "forward" : "backward") << ": ";
- token = wFooter->getString();
+ token = wFooter->prompt();
}
Statusbar::print("Searching...");
diff --git a/src/ncmpcpp.cpp b/src/ncmpcpp.cpp
index 1dfcea46..21ba4c3c 100644
--- a/src/ncmpcpp.cpp
+++ b/src/ncmpcpp.cpp
@@ -123,7 +123,7 @@ int main(int argc, char **argv)
wHeader->display();
wFooter = new NC::Window(0, Actions::FooterStartY, COLS, Actions::FooterHeight, "", Config.statusbar_color, NC::Border::None);
- wFooter->setGetStringHelper(Statusbar::Helpers::getString);
+ wFooter->setPromptHook(Statusbar::Helpers::getString);
// initialize global timer
Timer = boost::posix_time::microsec_clock::local_time();
diff --git a/src/search_engine.cpp b/src/search_engine.cpp
index eb81e941..6c5b817b 100644
--- a/src/search_engine.cpp
+++ b/src/search_engine.cpp
@@ -158,7 +158,7 @@ void SearchEngine::enterPressed()
Statusbar::ScopedLock lock;
std::string constraint = ConstraintsNames[option];
Statusbar::put() << NC::Format::Bold << constraint << NC::Format::NoBold << ": ";
- itsConstraints[option] = Global::wFooter->getString(itsConstraints[option]);
+ itsConstraints[option] = Global::wFooter->prompt(itsConstraints[option]);
w.current().value().buffer().clear();
constraint.resize(13, ' ');
w.current().value().buffer() << NC::Format::Bold << constraint << NC::Format::NoBold << ": ";
diff --git a/src/sel_items_adder.cpp b/src/sel_items_adder.cpp
index 8b143e69..db6d17df 100644
--- a/src/sel_items_adder.cpp
+++ b/src/sel_items_adder.cpp
@@ -227,7 +227,7 @@ void SelectedItemsAdder::addToNewPlaylist() const
{
Statusbar::ScopedLock lock;
Statusbar::put() << "Save playlist as: ";
- playlist = Global::wFooter->getString();
+ playlist = Global::wFooter->prompt();
}
addToExistingPlaylist(playlist);
}
diff --git a/src/status.cpp b/src/status.cpp
index bb2e2656..b57f25f0 100644
--- a/src/status.cpp
+++ b/src/status.cpp
@@ -167,9 +167,9 @@ void Status::handleServerError(MPD::ServerError &e)
Statusbar::printf("MPD: %1%", e.what());
if (e.code() == MPD_SERVER_ERROR_PERMISSION)
{
- NC::Window::ScopedStringHelper helper(*wFooter, nullptr);
+ NC::Window::ScopedPromptHook helper(*wFooter, nullptr);
Statusbar::put() << "Password: ";
- Mpd.SetPassword(wFooter->getString(0, true));
+ Mpd.SetPassword(wFooter->prompt("", -1, true));
try {
Mpd.SendPassword();
Statusbar::print("Password accepted");
diff --git a/src/tag_editor.cpp b/src/tag_editor.cpp
index 1a5a424b..79e0453a 100644
--- a/src/tag_editor.cpp
+++ b/src/tag_editor.cpp
@@ -360,7 +360,7 @@ void TagEditor::enterPressed()
{
Statusbar::ScopedLock lock;
Statusbar::put() << "Pattern: ";
- new_pattern = wFooter->getString(Config.pattern);
+ new_pattern = wFooter->prompt(Config.pattern);
}
Config.pattern = new_pattern;
FParser->at(0).value() = "Pattern: ";
@@ -494,7 +494,7 @@ void TagEditor::enterPressed()
{
Statusbar::ScopedLock lock;
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->prompt(Tags->current().value().getTags(get, Config.tags_separator));
for (auto it = EditedSongs.begin(); it != EditedSongs.end(); ++it)
(*it)->setTags(set, new_tag, Config.tags_separator);
}
@@ -502,7 +502,7 @@ void TagEditor::enterPressed()
{
Statusbar::ScopedLock lock;
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->prompt(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->scroll(NC::Scroll::Down);
@@ -526,7 +526,7 @@ void TagEditor::enterPressed()
std::string extension = old_name.substr(last_dot);
old_name = old_name.substr(0, last_dot);
Statusbar::put() << NC::Format::Bold << "New filename: " << NC::Format::NoBold;
- std::string new_name = wFooter->getString(old_name);
+ std::string new_name = wFooter->prompt(old_name);
if (!new_name.empty())
s.setNewName(new_name + extension);
Tags->scroll(NC::Scroll::Down);
diff --git a/src/tiny_tag_editor.cpp b/src/tiny_tag_editor.cpp
index 34cc23de..12281a26 100644
--- a/src/tiny_tag_editor.cpp
+++ b/src/tiny_tag_editor.cpp
@@ -106,7 +106,7 @@ void TinyTagEditor::enterPressed()
Statusbar::ScopedLock lock;
size_t pos = option-8;
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->prompt(
itsEdited.getTags(SongInfo::Tags[pos].Get, Config.tags_separator)), Config.tags_separator);
w.at(option).value().clear();
w.at(option).value() << NC::Format::Bold << SongInfo::Tags[pos].Name << ':' << NC::Format::NoBold << ' ';
@@ -120,7 +120,7 @@ void TinyTagEditor::enterPressed()
size_t dot = filename.rfind(".");
std::string extension = filename.substr(dot);
filename = filename.substr(0, dot);
- std::string new_name = Global::wFooter->getString(filename);
+ std::string new_name = Global::wFooter->prompt(filename);
if (!new_name.empty())
{
itsEdited.setNewName(new_name + extension);
diff --git a/src/window.cpp b/src/window.cpp
index 9edc377d..511bdcd5 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -57,7 +57,7 @@ int read_key(FILE *)
do
{
x = w->getX();
- if (w->runGetStringHelper(rl_line_buffer, &done))
+ if (w->runPromptHook(rl_line_buffer, &done))
{
if (done)
{
@@ -431,7 +431,7 @@ Window::Window(size_t startx,
m_base_color(color),
m_base_bg_color(Color::Default),
m_border(border),
- m_get_string_helper(0),
+ m_prompt_hook(0),
m_title(title),
m_bold_counter(0),
m_underline_counter(0),
@@ -479,7 +479,7 @@ Window::Window(const Window &rhs)
, m_base_color(rhs.m_base_color)
, m_base_bg_color(rhs.m_base_bg_color)
, m_border(rhs.m_border)
-, m_get_string_helper(rhs.m_get_string_helper)
+, m_prompt_hook(rhs.m_prompt_hook)
, m_title(rhs.m_title)
, m_color_stack(rhs.m_color_stack)
, m_input_queue(rhs.m_input_queue)
@@ -504,7 +504,7 @@ Window::Window(Window &&rhs)
, m_base_color(rhs.m_base_color)
, m_base_bg_color(rhs.m_base_bg_color)
, m_border(rhs.m_border)
-, m_get_string_helper(rhs.m_get_string_helper)
+, m_prompt_hook(rhs.m_prompt_hook)
, m_title(std::move(rhs.m_title))
, m_color_stack(std::move(rhs.m_color_stack))
, m_input_queue(std::move(rhs.m_input_queue))
@@ -532,7 +532,7 @@ Window &Window::operator=(Window rhs)
std::swap(m_base_color, rhs.m_base_color);
std::swap(m_base_bg_color, rhs.m_base_bg_color);
std::swap(m_border, rhs.m_border);
- std::swap(m_get_string_helper, rhs.m_get_string_helper);
+ std::swap(m_prompt_hook, rhs.m_prompt_hook);
std::swap(m_title, rhs.m_title);
std::swap(m_color_stack, rhs.m_color_stack);
std::swap(m_input_queue, rhs.m_input_queue);
@@ -665,13 +665,10 @@ void Window::resize(size_t new_width, size_t new_height)
recreate(m_width, m_height);
}
-void Window::showBorder() const
+void Window::refreshBorder() const
{
if (m_border != Border::None)
- {
- ::refresh();
prefresh(m_border_window, 0, 0, getStarty(), getStartX(), m_start_y+m_height, m_start_x+m_width);
- }
if (!m_title.empty())
{
if (m_border != Border::None)
@@ -689,7 +686,7 @@ void Window::showBorder() const
void Window::display()
{
- showBorder();
+ refreshBorder();
refresh();
}
@@ -806,21 +803,15 @@ void Window::pushChar(int ch)
m_input_queue.push(ch);
}
-std::string Window::getString(const std::string &base, size_t width, bool encrypted)
+std::string Window::prompt(const std::string &base, size_t width, bool encrypted)
{
rl::aborted = false;
rl::w = this;
getyx(m_window, rl::start_y, rl::start_x);
- rl::width = width;
+ rl::width = std::min(m_width-rl::start_x-1, width-1);
rl::encrypted = encrypted;
rl::base = base.c_str();
- width--;
- if (width == size_t(-1))
- rl::width = m_width-rl::start_x-1;
- else
- rl::width = width;
-
mmask_t oldmask;
std::string result;
@@ -878,11 +869,11 @@ bool Window::hasCoords(int &x, int &y)
# endif
}
-bool Window::runGetStringHelper(const char *arg, bool *done) const
+bool Window::runPromptHook(const char *arg, bool *done) const
{
- if (m_get_string_helper)
+ if (m_prompt_hook)
{
- bool continue_ = m_get_string_helper(arg);
+ bool continue_ = m_prompt_hook(arg);
if (done != nullptr)
*done = !continue_;
return true;
diff --git a/src/window.h b/src/window.h
index 8d61e47e..ba40e09c 100644
--- a/src/window.h
+++ b/src/window.h
@@ -109,10 +109,10 @@
#endif
/// NC namespace provides set of easy-to-use
-/// wrappers over original curses library
-namespace NC {//
+/// wrappers over original curses library.
+namespace NC {
-/// Thrown if Ctrl-G is pressed during the call to Window::getString().
+/// Thrown if Ctrl-C or Ctrl-G is pressed during the call to Window::getString()
/// @see Window::getString()
struct PromptAborted : std::exception
{
@@ -154,11 +154,6 @@ enum class Scroll { Up, Down, PageUp, PageDown, Home, End };
std::ostream &operator<<(std::ostream &os, Scroll s);
-/// Helper function that is invoked each time one will want
-/// to obtain string from Window::getString() function
-/// @see Window::getString()
-typedef std::function<bool(const char *)> GetStringHelper;
-
/// Initializes curses screen and sets some additional attributes
/// @param window_title title of the window (has an effect only if pdcurses lib is used)
/// @param enable_colors enables colors
@@ -188,21 +183,26 @@ struct XY
/// Main class of NCurses namespace, used as base for other specialized windows
struct Window
{
+ /// Helper function that is periodically invoked
+ // inside Window::getString() function
+ /// @see Window::getString()
+ typedef std::function<bool(const char *)> PromptHook;
+
/// Sets helper to a specific value for the current scope
- struct ScopedStringHelper
+ struct ScopedPromptHook
{
template <typename HelperT>
- ScopedStringHelper(Window &w, HelperT &&helper) noexcept
- : m_w(w), m_helper(std::move(w.m_get_string_helper)) {
- m_w.m_get_string_helper = std::forward<HelperT>(helper);
+ ScopedPromptHook(Window &w, HelperT &&helper) noexcept
+ : m_w(w), m_hook(std::move(w.m_prompt_hook)) {
+ m_w.m_prompt_hook = std::forward<HelperT>(helper);
}
- ~ScopedStringHelper() noexcept {
- m_w.m_get_string_helper = std::move(m_helper);
+ ~ScopedPromptHook() noexcept {
+ m_w.m_prompt_hook = std::move(m_hook);
}
private:
Window &m_w;
- GetStringHelper m_helper;
+ PromptHook m_hook;
};
Window() : m_window(0), m_border_window(0) { }
@@ -253,14 +253,9 @@ struct Window
/// @return current window's timeout
int getTimeout() const;
- /// Reads the string from standard input. Note that this is much more complex
- /// function than getstr() from curses library. It allows for moving through
- /// letters with arrows, supports scrolling if string's length is bigger than
- /// given area, supports history of previous strings and each time it receives
- /// an input from the keyboard or the timeout is reached, it calls helper function
- /// (if it's set) that takes as an argument currently edited string.
+ /// Reads the string from standard input using readline library.
/// @param base base string that has to be edited
- /// @param length max length of string, unlimited by default
+ /// @param length max length of the string, unlimited by default
/// @param width width of area that entry field can take. if it's reached, string
/// will be scrolled. if value is 0, field will be from cursor position to the end
/// of current line wide.
@@ -268,17 +263,9 @@ struct Window
/// actual text.
/// @return edited string
///
- /// @see setGetStringHelper()
+ /// @see setPromptHook()
/// @see SetTimeout()
- /// @see CreateHistory()
- std::string getString(const std::string &base, size_t width = 0, bool encrypted = false);
-
- /// Wrapper for above function that doesn't take base string (it will be empty).
- /// Taken parameters are the same as for above.
- std::string getString(size_t width = 0, bool encrypted = false)
- {
- return getString("", width, encrypted);
- }
+ std::string prompt(const std::string &base = "", size_t width = -1, bool encrypted = false);
/// Moves cursor to given coordinates
/// @param x given X position
@@ -299,19 +286,18 @@ struct Window
/// @return true if it transformed variables, false otherwise
bool hasCoords(int &x, int &y);
- /// Sets helper function used in getString()
- /// @param helper pointer to function that matches getStringHelper prototype
+ /// Sets hook used in getString()
+ /// @param hook pointer to function that matches getStringHelper prototype
/// @see getString()
- template <typename HelperT>
- void setGetStringHelper(HelperT &&helper)
- {
- m_get_string_helper = std::forward<HelperT>(helper);
+ template <typename HookT>
+ void setPromptHook(HookT &&hook) {
+ m_prompt_hook = std::forward<HookT>(hook);
}
/// Run current GetString helper function (if defined).
/// @see getString()
/// @return true if helper was run, false otherwise
- bool runGetStringHelper(const char *arg, bool *done) const;
+ bool runPromptHook(const char *arg, bool *done) const;
/// Sets window's base color
/// @param fg foregound base color
@@ -352,7 +338,7 @@ struct Window
virtual void clear();
/// Adds given file descriptor to the list that will be polled in
- /// ReadKey() along with stdin and callback that will be invoked
+ /// readKey() along with stdin and callback that will be invoked
/// when there is data waiting for reading in it
/// @param fd file descriptor
/// @param callback callback
@@ -466,7 +452,7 @@ protected:
/// Refreshes window's border
///
- void showBorder() const;
+ void refreshBorder() const;
/// Changes dimensions of window, called from resize()
/// @param width new window's width
@@ -533,7 +519,7 @@ private:
/// pointer to helper function used by getString()
/// @see getString()
///
- GetStringHelper m_get_string_helper;
+ PromptHook m_prompt_hook;
/// window title
std::string m_title;