actions: use unique_ptr for storing actions
[ncmpcpp.git] / src / help.cpp
blobe7d9fafd5b7db2d1661d72f1062d37fbeeed823d
1 /***************************************************************************
2 * Copyright (C) 2008-2016 by Andrzej Rybczak *
3 * electricityispower@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
19 ***************************************************************************/
21 #include "mpdpp.h"
23 #include "bindings.h"
24 #include "global.h"
25 #include "help.h"
26 #include "settings.h"
27 #include "status.h"
28 #include "utility/string.h"
29 #include "utility/wide_string.h"
30 #include "title.h"
31 #include "screen_switcher.h"
33 using Global::MainHeight;
34 using Global::MainStartY;
36 Help *myHelp;
38 namespace {
40 std::string align_key_rep(std::wstring keys)
42 size_t i = 0, len = 0;
43 const size_t max_len = 20;
44 for (; i < keys.size(); ++i)
46 int width = std::max(1, wcwidth(keys[i]));
47 if (len+width > max_len)
48 break;
49 else
50 len += width;
52 keys.resize(i + max_len - len, ' ');
53 return ToString(keys);
56 std::string display_keys(const Actions::Type at)
58 std::wstring result, skey;
59 for (auto it = Bindings.begin(); it != Bindings.end(); ++it)
61 for (auto j = it->second.begin(); j != it->second.end(); ++j)
63 if (j->isSingle() && j->action()->type() == at)
65 skey = keyToWString(it->first);
66 if (!skey.empty())
68 result += std::move(skey);
69 result += ' ';
74 return align_key_rep(std::move(result));
77 void section(NC::Scrollpad &w, const char *type_, const char *title_)
79 w << "\n " << NC::Format::Bold;
80 if (type_[0] != '\0')
81 w << type_ << " - ";
82 w << title_ << NC::Format::NoBold << "\n\n";
85 /**********************************************************************/
87 void key_section(NC::Scrollpad &w, const char *title_)
89 section(w, "Keys", title_);
92 void key(NC::Scrollpad &w, const Actions::Type at, const char *desc)
94 w << " " << display_keys(at) << " : " << desc << '\n';
97 void key(NC::Scrollpad &w, const Actions::Type at, const boost::format &desc)
99 w << " " << display_keys(at) << " : " << desc.str() << '\n';
102 void key(NC::Scrollpad &w, NC::Key::Type k, const std::string &desc)
104 w << " " << align_key_rep(keyToWString(k)) << " : " << desc << '\n';
107 /**********************************************************************/
109 void mouse_section(NC::Scrollpad &w, const char *title_)
111 section(w, "Mouse", title_);
114 void mouse(NC::Scrollpad &w, std::string action, const char *desc, bool indent = false)
116 action.resize(31 - (indent ? 2 : 0), ' ');
117 w << " " << (indent ? " " : "") << action;
118 w << ": " << desc << '\n';
121 void mouse_column(NC::Scrollpad &w, const char *column)
123 w << NC::Format::Bold << " " << column << " column:\n" << NC::Format::NoBold;
126 /**********************************************************************/
128 void write_bindings(NC::Scrollpad &w)
130 using Actions::Type;
132 key_section(w, "Movement");
133 key(w, Type::ScrollUp, "Move cursor up");
134 key(w, Type::ScrollDown, "Move cursor down");
135 key(w, Type::ScrollUpAlbum, "Move cursor up one album");
136 key(w, Type::ScrollDownAlbum, "Move cursor down one album");
137 key(w, Type::ScrollUpArtist, "Move cursor up one artist");
138 key(w, Type::ScrollDownArtist, "Move cursor down one artist");
139 key(w, Type::PageUp, "Page up");
140 key(w, Type::PageDown, "Page down");
141 key(w, Type::MoveHome, "Home");
142 key(w, Type::MoveEnd, "End");
143 w << '\n';
144 if (Config.screen_switcher_previous)
146 key(w, Type::NextScreen, "Switch between current and last screen");
147 key(w, Type::PreviousScreen, "Switch between current and last screen");
149 else
151 key(w, Type::NextScreen, "Switch to next screen in sequence");
152 key(w, Type::PreviousScreen, "Switch to previous screen in sequence");
154 key(w, Type::ShowHelp, "Show help");
155 key(w, Type::ShowPlaylist, "Show playlist");
156 key(w, Type::ShowBrowser, "Show browser");
157 key(w, Type::ShowSearchEngine, "Show search engine");
158 key(w, Type::ShowMediaLibrary, "Show media library");
159 key(w, Type::ShowPlaylistEditor, "Show playlist editor");
160 # ifdef HAVE_TAGLIB_H
161 key(w, Type::ShowTagEditor, "Show tag editor");
162 # endif // HAVE_TAGLIB_H
163 # ifdef ENABLE_OUTPUTS
164 key(w, Type::ShowOutputs, "Show outputs");
165 # endif // ENABLE_OUTPUTS
166 # ifdef ENABLE_VISUALIZER
167 key(w, Type::ShowVisualizer, "Show music visualizer");
168 # endif // ENABLE_VISUALIZER
169 # ifdef ENABLE_CLOCK
170 key(w, Type::ShowClock, "Show clock");
171 # endif // ENABLE_CLOCK
172 w << '\n';
173 key(w, Type::ShowServerInfo, "Show server info");
175 key_section(w, "Global");
176 key(w, Type::Stop, "Stop");
177 key(w, Type::Pause, "Pause");
178 key(w, Type::Next, "Next track");
179 key(w, Type::Previous, "Previous track");
180 key(w, Type::ReplaySong, "Replay playing song");
181 key(w, Type::SeekForward, "Seek forward in playing song");
182 key(w, Type::SeekBackward, "Seek backward in playing song");
183 key(w, Type::VolumeDown,
184 boost::format("Decrease volume by %1%%%") % Config.volume_change_step
186 key(w, Type::VolumeUp,
187 boost::format("Increase volume by %1%%%") % Config.volume_change_step
189 w << '\n';
190 key(w, Type::ToggleAddMode, "Toggle add mode (add or remove/always add)");
191 key(w, Type::ToggleMouse, "Toggle mouse support");
192 key(w, Type::SelectRange, "Select range");
193 key(w, Type::ReverseSelection, "Reverse selection");
194 key(w, Type::RemoveSelection, "Remove selection");
195 key(w, Type::SelectItem, "Select current item");
196 key(w, Type::SelectFoundItems, "Select found items");
197 key(w, Type::SelectAlbum, "Select songs of album around the cursor");
198 key(w, Type::AddSelectedItems, "Add selected items to playlist");
199 key(w, Type::AddRandomItems, "Add random items to playlist");
200 w << '\n';
201 key(w, Type::ToggleRepeat, "Toggle repeat mode");
202 key(w, Type::ToggleRandom, "Toggle random mode");
203 key(w, Type::ToggleSingle, "Toggle single mode");
204 key(w, Type::ToggleConsume, "Toggle consume mode");
205 key(w, Type::ToggleReplayGainMode, "Toggle replay gain mode");
206 key(w, Type::ToggleBitrateVisibility, "Toggle bitrate visibility");
207 key(w, Type::ToggleCrossfade, "Toggle crossfade mode");
208 key(w, Type::SetCrossfade, "Set crossfade");
209 key(w, Type::SetVolume, "Set volume");
210 key(w, Type::UpdateDatabase, "Start music database update");
211 w << '\n';
212 key(w, Type::ExecuteCommand, "Execute command");
213 key(w, Type::ApplyFilter, "Apply filter");
214 key(w, Type::FindItemForward, "Find item forward");
215 key(w, Type::FindItemBackward, "Find item backward");
216 key(w, Type::PreviousFoundItem, "Jump to previous found item");
217 key(w, Type::NextFoundItem, "Jump to next found item");
218 key(w, Type::ToggleFindMode, "Toggle find mode (normal/wrapped)");
219 key(w, Type::JumpToBrowser, "Locate song in browser");
220 key(w, Type::JumpToMediaLibrary, "Locate song in media library");
221 key(w, Type::ToggleScreenLock, "Lock/unlock current screen");
222 key(w, Type::MasterScreen, "Switch to master screen (left one)");
223 key(w, Type::SlaveScreen, "Switch to slave screen (right one)");
224 # ifdef HAVE_TAGLIB_H
225 key(w, Type::JumpToTagEditor, "Locate song in tag editor");
226 # endif // HAVE_TAGLIB_H
227 key(w, Type::ToggleDisplayMode, "Toggle display mode");
228 key(w, Type::ToggleInterface, "Toggle user interface");
229 key(w, Type::ToggleSeparatorsBetweenAlbums, "Toggle displaying separators between albums");
230 key(w, Type::JumpToPositionInSong, "Jump to given position in playing song (formats: mm:ss, x%)");
231 key(w, Type::ShowSongInfo, "Show song info");
232 key(w, Type::ShowArtistInfo, "Show artist info");
233 key(w, Type::FetchLyricsInBackground, "Fetch lyrics for selected songs");
234 key(w, Type::ToggleLyricsFetcher, "Toggle lyrics fetcher");
235 key(w, Type::ToggleFetchingLyricsInBackground, "Toggle fetching lyrics for playing songs in background");
236 key(w, Type::ShowLyrics, "Show/hide song lyrics");
237 w << '\n';
238 key(w, Type::Quit, "Quit");
240 key_section(w, "Playlist");
241 key(w, Type::PlayItem, "Play selected item");
242 key(w, Type::DeletePlaylistItems, "Delete selected item(s) from playlist");
243 key(w, Type::ClearMainPlaylist, "Clear playlist");
244 key(w, Type::CropMainPlaylist, "Clear playlist except selected item(s)");
245 key(w, Type::SetSelectedItemsPriority, "Set priority of selected items");
246 key(w, Type::MoveSelectedItemsUp, "Move selected item(s) up");
247 key(w, Type::MoveSelectedItemsDown, "Move selected item(s) down");
248 key(w, Type::MoveSelectedItemsTo, "Move selected item(s) to cursor position");
249 key(w, Type::Add, "Add item to playlist");
250 # ifdef HAVE_TAGLIB_H
251 key(w, Type::EditSong, "Edit song");
252 # endif // HAVE_TAGLIB_H
253 key(w, Type::SavePlaylist, "Save playlist");
254 key(w, Type::Shuffle, "Shuffle range");
255 key(w, Type::SortPlaylist, "Sort range");
256 key(w, Type::ReversePlaylist, "Reverse range");
257 key(w, Type::JumpToPlayingSong, "Jump to current song");
258 key(w, Type::TogglePlayingSongCentering, "Toggle playing song centering");
260 key_section(w, "Browser");
261 key(w, Type::EnterDirectory, "Enter directory");
262 key(w, Type::PlayItem, "Add item to playlist and play it");
263 key(w, Type::AddItemToPlaylist, "Add item to playlist");
264 # ifdef HAVE_TAGLIB_H
265 key(w, Type::EditSong, "Edit song");
266 # endif // HAVE_TAGLIB_H
267 key(w, Type::EditDirectoryName, "Edit directory name");
268 key(w, Type::EditPlaylistName, "Edit playlist name");
269 key(w, Type::ChangeBrowseMode, "Browse MPD database/local filesystem");
270 key(w, Type::ToggleBrowserSortMode, "Toggle sort mode");
271 key(w, Type::JumpToPlayingSong, "Locate playing song");
272 key(w, Type::JumpToParentDirectory, "Jump to parent directory");
273 key(w, Type::DeleteBrowserItems, "Delete selected items from disk");
274 key(w, Type::JumpToPlaylistEditor, "Jump to playlist editor (playlists only)");
276 key_section(w, "Search engine");
277 key(w, Type::RunAction, "Modify option / Run action");
278 key(w, Type::AddItemToPlaylist, "Add item to playlist");
279 key(w, Type::PlayItem, "Add item to playlist and play it");
280 # ifdef HAVE_TAGLIB_H
281 key(w, Type::EditSong, "Edit song");
282 # endif // HAVE_TAGLIB_H
283 key(w, Type::StartSearching, "Start searching");
284 key(w, Type::ResetSearchEngine, "Reset search constraints and clear results");
286 key_section(w, "Media library");
287 key(w, Type::ToggleMediaLibraryColumnsMode, "Switch between two/three columns mode");
288 key(w, Type::PreviousColumn, "Previous column");
289 key(w, Type::NextColumn, "Next column");
290 key(w, Type::PlayItem, "Add item to playlist and play it");
291 key(w, Type::AddItemToPlaylist, "Add item to playlist");
292 # ifdef HAVE_TAGLIB_H
293 key(w, Type::EditSong, "Edit song");
294 # endif // HAVE_TAGLIB_H
295 key(w, Type::EditLibraryTag, "Edit tag (left column)/album (middle/right column)");
296 key(w, Type::ToggleLibraryTagType, "Toggle type of tag used in left column");
297 key(w, Type::ToggleMediaLibrarySortMode, "Toggle sort mode");
299 key_section(w, "Playlist editor");
300 key(w, Type::PreviousColumn, "Previous column");
301 key(w, Type::NextColumn, "Next column");
302 key(w, Type::PlayItem, "Add item to playlist and play it");
303 key(w, Type::AddItemToPlaylist, "Add item to playlist");
304 # ifdef HAVE_TAGLIB_H
305 key(w, Type::EditSong, "Edit song");
306 # endif // HAVE_TAGLIB_H
307 key(w, Type::EditPlaylistName, "Edit playlist name");
308 key(w, Type::MoveSelectedItemsUp, "Move selected item(s) up");
309 key(w, Type::MoveSelectedItemsDown, "Move selected item(s) down");
310 key(w, Type::DeleteStoredPlaylist, "Delete selected playlists (left column)");
311 key(w, Type::DeletePlaylistItems, "Delete selected item(s) from playlist (right column)");
312 key(w, Type::ClearPlaylist, "Clear playlist");
313 key(w, Type::CropPlaylist, "Clear playlist except selected items");
315 key_section(w, "Lyrics");
316 key(w, Type::ToggleLyricsUpdateOnSongChange, "Toggle lyrics update on song change");
317 key(w, Type::EditLyrics, "Open lyrics in external editor");
318 key(w, Type::RefetchLyrics, "Refetch lyrics");
320 # ifdef HAVE_TAGLIB_H
321 key_section(w, "Tiny tag editor");
322 key(w, Type::RunAction, "Edit tag / Run action");
323 key(w, Type::SaveTagChanges, "Save");
325 key_section(w, "Tag editor");
326 key(w, Type::EnterDirectory, "Enter directory (right column)");
327 key(w, Type::RunAction, "Perform operation on selected items (middle column)");
328 key(w, Type::RunAction, "Edit item (left column)");
329 key(w, Type::PreviousColumn, "Previous column");
330 key(w, Type::NextColumn, "Next column");
331 key(w, Type::JumpToParentDirectory, "Jump to parent directory (left column, directories view)");
332 # endif // HAVE_TAGLIB_H
334 # ifdef ENABLE_OUTPUTS
335 key_section(w, "Outputs");
336 key(w, Type::ToggleOutput, "Toggle output");
337 # endif // ENABLE_OUTPUTS
339 # if defined(ENABLE_VISUALIZER) && defined(HAVE_FFTW3_H)
340 key_section(w, "Music visualizer");
341 key(w, Type::ToggleVisualizationType, "Toggle visualization type");
342 key(w, Type::SetVisualizerSampleMultiplier, "Set visualizer sample multiplier");
343 # endif // ENABLE_VISUALIZER && HAVE_FFTW3_H
345 mouse_section(w, "Global");
346 mouse(w, "Left click on \"Playing/Paused\"", "Play/pause");
347 mouse(w, "Left click on progressbar", "Jump to pointed position in playing song");
348 w << '\n';
349 mouse(w, "Mouse wheel on \"Volume: xx\"", "Adjust volume");
350 mouse(w, "Mouse wheel on main window", "Scroll");
352 mouse_section(w, "Playlist");
353 mouse(w, "Left click", "Select pointed item");
354 mouse(w, "Right click", "Play");
356 mouse_section(w, "Browser");
357 mouse(w, "Left click on directory", "Enter pointed directory");
358 mouse(w, "Right click on directory", "Add pointed directory to playlist");
359 w << '\n';
360 mouse(w, "Left click on song/playlist", "Add pointed item to playlist");
361 mouse(w, "Right click on song/playlist", "Add pointed item to playlist and play it");
363 mouse_section(w, "Search engine");
364 mouse(w, "Left click", "Highlight/switch value");
365 mouse(w, "Right click", "Change value");
367 mouse_section(w, "Media library");
368 mouse_column(w, "Left/middle");
369 mouse(w, "Left click", "Select pointed item", true);
370 mouse(w, "Right click", "Add item to playlist", true);
371 w << '\n';
372 mouse_column(w, "Right");
373 mouse(w, "Left Click", "Add pointed item to playlist", true);
374 mouse(w, "Right Click", "Add pointed item to playlist and play it", true);
376 mouse_section(w, "Playlist editor");
377 mouse_column(w, "Left");
378 mouse(w, "Left click", "Select pointed item", true);
379 mouse(w, "Right click", "Add item to playlist", true);
380 w << '\n';
381 mouse_column(w, "Right");
382 mouse(w, "Left click", "Add pointed item to playlist", true);
383 mouse(w, "Right click", "Add pointed item to playlist and play it", true);
385 # ifdef HAVE_TAGLIB_H
386 mouse_section(w, "Tiny tag editor");
387 mouse(w, "Left click", "Select option");
388 mouse(w, "Right click", "Set value/execute");
390 mouse_section(w, "Tag editor");
391 mouse_column(w, "Left");
392 mouse(w, "Left click", "Enter pointed directory/select pointed album", true);
393 mouse(w, "Right click", "Toggle view (directories/albums)", true);
394 w << '\n';
395 mouse_column(w, "Middle");
396 mouse(w, "Left click", "Select option", true);
397 mouse(w, "Right click", "Set value/execute", true);
398 w << '\n';
399 mouse_column(w, "Right");
400 mouse(w, "Left click", "Select pointed item", true);
401 mouse(w, "Right click", "Set value", true);
402 # endif // HAVE_TAGLIB_H
404 # ifdef ENABLE_OUTPUTS
405 mouse_section(w, "Outputs");
406 mouse(w, "Left click", "Select pointed output");
407 mouse(w, "Right click", "Toggle output");
408 # endif // ENABLE_OUTPUTS
410 section(w, "", "Action chains");
411 for (const auto &k : Bindings)
413 for (const auto &binding : k.second)
415 if (!binding.isSingle())
417 std::vector<std::string> commands;
418 for (const auto &action : binding.actions())
419 commands.push_back(action->name());
420 key(w, k.first, join<std::string>(commands, ", "));
425 section(w, "", "List of available colors");
426 for (int i = 0; i < COLORS; ++i)
427 w << NC::Color(i, NC::Color::transparent) << i+1 << NC::Color::End << " ";
432 Help::Help()
433 : Screen(NC::Scrollpad(0, MainStartY, COLS, MainHeight, "", Config.main_color, NC::Border()))
435 write_bindings(w);
436 w.flush();
439 void Help::resize()
441 size_t x_offset, width;
442 getWindowResizeParams(x_offset, width);
443 w.resize(width, MainHeight);
444 w.moveTo(x_offset, MainStartY);
445 hasToBeResized = 0;
448 void Help::switchTo()
450 SwitchTo::execute(this);
451 drawHeader();
454 std::wstring Help::title()
456 return L"Help";