1 /***************************************************************************
2 * Copyright (C) 2008-2016 by Andrzej Rybczak *
3 * electricityispower@gmail.com *
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. *
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. *
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 ***************************************************************************/
25 #include "screens/help.h"
28 #include "utility/string.h"
29 #include "utility/wide_string.h"
31 #include "screens/screen_switcher.h"
33 using Global::MainHeight
;
34 using Global::MainStartY
;
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
)
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
);
68 result
+= std::move(skey
);
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
;
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
)
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");
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");
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
170 key(w
, Type::ShowClock
, "Show clock");
171 # endif // ENABLE_CLOCK
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
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");
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");
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");
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 # endif // ENABLE_VISUALIZER && HAVE_FFTW3_H
344 mouse_section(w
, "Global");
345 mouse(w
, "Left click on \"Playing/Paused\"", "Play/pause");
346 mouse(w
, "Left click on progressbar", "Jump to pointed position in playing song");
348 mouse(w
, "Mouse wheel on \"Volume: xx\"", "Adjust volume");
349 mouse(w
, "Mouse wheel on main window", "Scroll");
351 mouse_section(w
, "Playlist");
352 mouse(w
, "Left click", "Select pointed item");
353 mouse(w
, "Right click", "Play");
355 mouse_section(w
, "Browser");
356 mouse(w
, "Left click on directory", "Enter pointed directory");
357 mouse(w
, "Right click on directory", "Add pointed directory to playlist");
359 mouse(w
, "Left click on song/playlist", "Add pointed item to playlist");
360 mouse(w
, "Right click on song/playlist", "Add pointed item to playlist and play it");
362 mouse_section(w
, "Search engine");
363 mouse(w
, "Left click", "Highlight/switch value");
364 mouse(w
, "Right click", "Change value");
366 mouse_section(w
, "Media library");
367 mouse_column(w
, "Left/middle");
368 mouse(w
, "Left click", "Select pointed item", true);
369 mouse(w
, "Right click", "Add item to playlist", true);
371 mouse_column(w
, "Right");
372 mouse(w
, "Left Click", "Add pointed item to playlist", true);
373 mouse(w
, "Right Click", "Add pointed item to playlist and play it", true);
375 mouse_section(w
, "Playlist editor");
376 mouse_column(w
, "Left");
377 mouse(w
, "Left click", "Select pointed item", true);
378 mouse(w
, "Right click", "Add item to playlist", true);
380 mouse_column(w
, "Right");
381 mouse(w
, "Left click", "Add pointed item to playlist", true);
382 mouse(w
, "Right click", "Add pointed item to playlist and play it", true);
384 # ifdef HAVE_TAGLIB_H
385 mouse_section(w
, "Tiny tag editor");
386 mouse(w
, "Left click", "Select option");
387 mouse(w
, "Right click", "Set value/execute");
389 mouse_section(w
, "Tag editor");
390 mouse_column(w
, "Left");
391 mouse(w
, "Left click", "Enter pointed directory/select pointed album", true);
392 mouse(w
, "Right click", "Toggle view (directories/albums)", true);
394 mouse_column(w
, "Middle");
395 mouse(w
, "Left click", "Select option", true);
396 mouse(w
, "Right click", "Set value/execute", true);
398 mouse_column(w
, "Right");
399 mouse(w
, "Left click", "Select pointed item", true);
400 mouse(w
, "Right click", "Set value", true);
401 # endif // HAVE_TAGLIB_H
403 # ifdef ENABLE_OUTPUTS
404 mouse_section(w
, "Outputs");
405 mouse(w
, "Left click", "Select pointed output");
406 mouse(w
, "Right click", "Toggle output");
407 # endif // ENABLE_OUTPUTS
409 section(w
, "", "Action chains");
410 for (const auto &k
: Bindings
)
412 for (const auto &binding
: k
.second
)
414 if (!binding
.isSingle())
416 std::vector
<std::string
> commands
;
417 for (const auto &action
: binding
.actions())
418 commands
.push_back(action
->name());
419 key(w
, k
.first
, join
<std::string
>(commands
, ", "));
424 section(w
, "", "List of available colors");
425 for (int i
= 0; i
< COLORS
; ++i
)
426 w
<< NC::Color(i
, NC::Color::transparent
) << i
+1 << NC::Color::End
<< " ";
432 : Screen(NC::Scrollpad(0, MainStartY
, COLS
, MainHeight
, "", Config
.main_color
, NC::Border()))
440 size_t x_offset
, width
;
441 getWindowResizeParams(x_offset
, width
);
442 w
.resize(width
, MainHeight
);
443 w
.moveTo(x_offset
, MainStartY
);
447 void Help::switchTo()
449 SwitchTo::execute(this);
453 std::wstring
Help::title()