keys: implement parsing key configuration file
This commit is contained in:
268
src/actions.cpp
268
src/actions.cpp
@@ -69,7 +69,14 @@ size_t Action::HeaderHeight;
|
|||||||
size_t Action::FooterHeight;
|
size_t Action::FooterHeight;
|
||||||
size_t Action::FooterStartY;
|
size_t Action::FooterStartY;
|
||||||
|
|
||||||
std::map<ActionType, Action *> Action::Actions;
|
namespace {//
|
||||||
|
|
||||||
|
std::map<ActionType, Action *> Actions;
|
||||||
|
|
||||||
|
void insertAction(Action *a);
|
||||||
|
void populateActions();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void Action::ValidateScreenSize()
|
void Action::ValidateScreenSize()
|
||||||
{
|
{
|
||||||
@@ -418,6 +425,29 @@ bool Action::isMPDMusicDirSet()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Action *Action::Get(ActionType at)
|
||||||
|
{
|
||||||
|
if (Actions.empty())
|
||||||
|
populateActions();
|
||||||
|
return Actions[at];
|
||||||
|
}
|
||||||
|
|
||||||
|
Action *Action::Get(const std::string &name)
|
||||||
|
{
|
||||||
|
Action *result = 0;
|
||||||
|
if (Actions.empty())
|
||||||
|
populateActions();
|
||||||
|
for (auto it = Actions.begin(); it != Actions.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it->second->Name() == name)
|
||||||
|
{
|
||||||
|
result = it->second;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
bool MouseEvent::canBeRun() const
|
bool MouseEvent::canBeRun() const
|
||||||
{
|
{
|
||||||
return Config.mouse_support;
|
return Config.mouse_support;
|
||||||
@@ -2478,120 +2508,126 @@ void ShowServerInfo::Run()
|
|||||||
myServerInfo->SwitchTo();
|
myServerInfo->SwitchTo();
|
||||||
}
|
}
|
||||||
|
|
||||||
Action *Action::Get(ActionType at)
|
namespace {//
|
||||||
|
|
||||||
|
void insertAction(Action *a)
|
||||||
{
|
{
|
||||||
if (Actions.empty())
|
Actions[a->Type()] = a;
|
||||||
{
|
}
|
||||||
insertAction(new MouseEvent());
|
|
||||||
insertAction(new ScrollUp());
|
void populateActions()
|
||||||
insertAction(new ScrollDown());
|
{
|
||||||
insertAction(new ScrollUpArtist());
|
insertAction(new Dummy());
|
||||||
insertAction(new ScrollUpAlbum());
|
insertAction(new MouseEvent());
|
||||||
insertAction(new ScrollDownArtist());
|
insertAction(new ScrollUp());
|
||||||
insertAction(new ScrollDownAlbum());
|
insertAction(new ScrollDown());
|
||||||
insertAction(new PageUp());
|
insertAction(new ScrollUpArtist());
|
||||||
insertAction(new PageDown());
|
insertAction(new ScrollUpAlbum());
|
||||||
insertAction(new MoveHome());
|
insertAction(new ScrollDownArtist());
|
||||||
insertAction(new MoveEnd());
|
insertAction(new ScrollDownAlbum());
|
||||||
insertAction(new ToggleInterface());
|
insertAction(new PageUp());
|
||||||
insertAction(new JumpToParentDir());
|
insertAction(new PageDown());
|
||||||
insertAction(new PressEnter());
|
insertAction(new MoveHome());
|
||||||
insertAction(new PressSpace());
|
insertAction(new MoveEnd());
|
||||||
insertAction(new PreviousColumn());
|
insertAction(new ToggleInterface());
|
||||||
insertAction(new NextColumn());
|
insertAction(new JumpToParentDir());
|
||||||
insertAction(new MasterScreen());
|
insertAction(new PressEnter());
|
||||||
insertAction(new SlaveScreen());
|
insertAction(new PressSpace());
|
||||||
insertAction(new VolumeUp());
|
insertAction(new PreviousColumn());
|
||||||
insertAction(new VolumeDown());
|
insertAction(new NextColumn());
|
||||||
insertAction(new Delete());
|
insertAction(new MasterScreen());
|
||||||
insertAction(new ReplaySong());
|
insertAction(new SlaveScreen());
|
||||||
insertAction(new PreviousSong());
|
insertAction(new VolumeUp());
|
||||||
insertAction(new NextSong());
|
insertAction(new VolumeDown());
|
||||||
insertAction(new Pause());
|
insertAction(new Delete());
|
||||||
insertAction(new Stop());
|
insertAction(new ReplaySong());
|
||||||
insertAction(new SavePlaylist());
|
insertAction(new PreviousSong());
|
||||||
insertAction(new MoveSortOrderUp());
|
insertAction(new NextSong());
|
||||||
insertAction(new MoveSortOrderDown());
|
insertAction(new Pause());
|
||||||
insertAction(new MoveSelectedItemsUp());
|
insertAction(new Stop());
|
||||||
insertAction(new MoveSelectedItemsDown());
|
insertAction(new SavePlaylist());
|
||||||
insertAction(new MoveSelectedItemsTo());
|
insertAction(new MoveSortOrderUp());
|
||||||
insertAction(new Add());
|
insertAction(new MoveSortOrderDown());
|
||||||
insertAction(new SeekForward());
|
insertAction(new MoveSelectedItemsUp());
|
||||||
insertAction(new SeekBackward());
|
insertAction(new MoveSelectedItemsDown());
|
||||||
insertAction(new ToggleDisplayMode());
|
insertAction(new MoveSelectedItemsTo());
|
||||||
insertAction(new ToggleSeparatorsInPlaylist());
|
insertAction(new Add());
|
||||||
insertAction(new ToggleLyricsFetcher());
|
insertAction(new SeekForward());
|
||||||
insertAction(new ToggleFetchingLyricsInBackground());
|
insertAction(new SeekBackward());
|
||||||
insertAction(new ToggleAutoCenter());
|
insertAction(new ToggleDisplayMode());
|
||||||
insertAction(new UpdateDatabase());
|
insertAction(new ToggleSeparatorsInPlaylist());
|
||||||
insertAction(new JumpToPlayingSong());
|
insertAction(new ToggleLyricsFetcher());
|
||||||
insertAction(new ToggleRepeat());
|
insertAction(new ToggleFetchingLyricsInBackground());
|
||||||
insertAction(new Shuffle());
|
insertAction(new ToggleAutoCenter());
|
||||||
insertAction(new ToggleRandom());
|
insertAction(new UpdateDatabase());
|
||||||
insertAction(new StartSearching());
|
insertAction(new JumpToPlayingSong());
|
||||||
insertAction(new SaveTagChanges());
|
insertAction(new ToggleRepeat());
|
||||||
insertAction(new ToggleSingle());
|
insertAction(new Shuffle());
|
||||||
insertAction(new ToggleConsume());
|
insertAction(new ToggleRandom());
|
||||||
insertAction(new ToggleCrossfade());
|
insertAction(new StartSearching());
|
||||||
insertAction(new SetCrossfade());
|
insertAction(new SaveTagChanges());
|
||||||
insertAction(new EditSong());
|
insertAction(new ToggleSingle());
|
||||||
insertAction(new EditLibraryTag());
|
insertAction(new ToggleConsume());
|
||||||
insertAction(new EditLibraryAlbum());
|
insertAction(new ToggleCrossfade());
|
||||||
insertAction(new EditDirectoryName());
|
insertAction(new SetCrossfade());
|
||||||
insertAction(new EditPlaylistName());
|
insertAction(new EditSong());
|
||||||
insertAction(new EditLyrics());
|
insertAction(new EditLibraryTag());
|
||||||
insertAction(new JumpToBrowser());
|
insertAction(new EditLibraryAlbum());
|
||||||
insertAction(new JumpToMediaLibrary());
|
insertAction(new EditDirectoryName());
|
||||||
insertAction(new JumpToPlaylistEditor());
|
insertAction(new EditPlaylistName());
|
||||||
insertAction(new ToggleScreenLock());
|
insertAction(new EditLyrics());
|
||||||
insertAction(new JumpToTagEditor());
|
insertAction(new JumpToBrowser());
|
||||||
insertAction(new JumpToPositionInSong());
|
insertAction(new JumpToMediaLibrary());
|
||||||
insertAction(new ReverseSelection());
|
insertAction(new JumpToPlaylistEditor());
|
||||||
insertAction(new DeselectItems());
|
insertAction(new ToggleScreenLock());
|
||||||
insertAction(new SelectAlbum());
|
insertAction(new JumpToTagEditor());
|
||||||
insertAction(new AddSelectedItems());
|
insertAction(new JumpToPositionInSong());
|
||||||
insertAction(new CropMainPlaylist());
|
insertAction(new ReverseSelection());
|
||||||
insertAction(new CropPlaylist());
|
insertAction(new DeselectItems());
|
||||||
insertAction(new ClearMainPlaylist());
|
insertAction(new SelectAlbum());
|
||||||
insertAction(new ClearPlaylist());
|
insertAction(new AddSelectedItems());
|
||||||
insertAction(new SortPlaylist());
|
insertAction(new CropMainPlaylist());
|
||||||
insertAction(new ReversePlaylist());
|
insertAction(new CropPlaylist());
|
||||||
insertAction(new ApplyFilter());
|
insertAction(new ClearMainPlaylist());
|
||||||
insertAction(new DisableFilter());
|
insertAction(new ClearPlaylist());
|
||||||
insertAction(new Find());
|
insertAction(new SortPlaylist());
|
||||||
insertAction(new FindItemForward());
|
insertAction(new ReversePlaylist());
|
||||||
insertAction(new FindItemBackward());
|
insertAction(new ApplyFilter());
|
||||||
insertAction(new NextFoundItem());
|
insertAction(new DisableFilter());
|
||||||
insertAction(new PreviousFoundItem());
|
insertAction(new Find());
|
||||||
insertAction(new ToggleFindMode());
|
insertAction(new FindItemForward());
|
||||||
insertAction(new ToggleReplayGainMode());
|
insertAction(new FindItemBackward());
|
||||||
insertAction(new ToggleSpaceMode());
|
insertAction(new NextFoundItem());
|
||||||
insertAction(new ToggleAddMode());
|
insertAction(new PreviousFoundItem());
|
||||||
insertAction(new ToggleMouse());
|
insertAction(new ToggleFindMode());
|
||||||
insertAction(new ToggleBitrateVisibility());
|
insertAction(new ToggleReplayGainMode());
|
||||||
insertAction(new AddRandomItems());
|
insertAction(new ToggleSpaceMode());
|
||||||
insertAction(new ToggleBrowserSortMode());
|
insertAction(new ToggleAddMode());
|
||||||
insertAction(new ToggleLibraryTagType());
|
insertAction(new ToggleMouse());
|
||||||
insertAction(new RefetchLyrics());
|
insertAction(new ToggleBitrateVisibility());
|
||||||
insertAction(new RefetchArtistInfo());
|
insertAction(new AddRandomItems());
|
||||||
insertAction(new SetSelectedItemsPriority());
|
insertAction(new ToggleBrowserSortMode());
|
||||||
insertAction(new ShowSongInfo());
|
insertAction(new ToggleLibraryTagType());
|
||||||
insertAction(new ShowArtistInfo());
|
insertAction(new RefetchLyrics());
|
||||||
insertAction(new ShowLyrics());
|
insertAction(new RefetchArtistInfo());
|
||||||
insertAction(new Quit());
|
insertAction(new SetSelectedItemsPriority());
|
||||||
insertAction(new NextScreen());
|
insertAction(new ShowSongInfo());
|
||||||
insertAction(new PreviousScreen());
|
insertAction(new ShowArtistInfo());
|
||||||
insertAction(new ShowHelp());
|
insertAction(new ShowLyrics());
|
||||||
insertAction(new ShowPlaylist());
|
insertAction(new Quit());
|
||||||
insertAction(new ShowBrowser());
|
insertAction(new NextScreen());
|
||||||
insertAction(new ShowSearchEngine());
|
insertAction(new PreviousScreen());
|
||||||
insertAction(new ShowMediaLibrary());
|
insertAction(new ShowHelp());
|
||||||
insertAction(new ShowPlaylistEditor());
|
insertAction(new ShowPlaylist());
|
||||||
insertAction(new ShowTagEditor());
|
insertAction(new ShowBrowser());
|
||||||
insertAction(new ShowOutputs());
|
insertAction(new ShowSearchEngine());
|
||||||
insertAction(new ShowVisualizer());
|
insertAction(new ShowMediaLibrary());
|
||||||
insertAction(new ShowClock());
|
insertAction(new ShowPlaylistEditor());
|
||||||
insertAction(new ShowServerInfo());
|
insertAction(new ShowTagEditor());
|
||||||
}
|
insertAction(new ShowOutputs());
|
||||||
return Actions[at];
|
insertAction(new ShowVisualizer());
|
||||||
|
insertAction(new ShowClock());
|
||||||
|
insertAction(new ShowServerInfo());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
enum ActionType
|
enum ActionType
|
||||||
{
|
{
|
||||||
aMacroUtility,
|
aMacroUtility,
|
||||||
aMouseEvent, aScrollUp, aScrollDown, aScrollUpArtist, aScrollUpAlbum, aScrollDownArtist,
|
aDummy, aMouseEvent, aScrollUp, aScrollDown, aScrollUpArtist, aScrollUpAlbum, aScrollDownArtist,
|
||||||
aScrollDownAlbum, aPageUp, aPageDown, aMoveHome, aMoveEnd, aToggleInterface, aJumpToParentDir,
|
aScrollDownAlbum, aPageUp, aPageDown, aMoveHome, aMoveEnd, aToggleInterface, aJumpToParentDir,
|
||||||
aPressEnter, aPressSpace, aPreviousColumn, aNextColumn, aMasterScreen, aSlaveScreen, aVolumeUp,
|
aPressEnter, aPressSpace, aPreviousColumn, aNextColumn, aMasterScreen, aSlaveScreen, aVolumeUp,
|
||||||
aVolumeDown, aDelete, aReplaySong, aPreviousSong, aNextSong, aPause, aStop, aSavePlaylist,
|
aVolumeDown, aDelete, aReplaySong, aPreviousSong, aNextSong, aPause, aStop, aSavePlaylist,
|
||||||
@@ -79,6 +79,7 @@ struct Action
|
|||||||
static bool isMPDMusicDirSet();
|
static bool isMPDMusicDirSet();
|
||||||
|
|
||||||
static Action *Get(ActionType);
|
static Action *Get(ActionType);
|
||||||
|
static Action *Get(const std::string &name);
|
||||||
|
|
||||||
static bool OriginalStatusbarVisibility;
|
static bool OriginalStatusbarVisibility;
|
||||||
static bool DesignChanged;
|
static bool DesignChanged;
|
||||||
@@ -100,9 +101,12 @@ struct Action
|
|||||||
private:
|
private:
|
||||||
ActionType itsType;
|
ActionType itsType;
|
||||||
const char *itsName;
|
const char *itsName;
|
||||||
|
};
|
||||||
static void insertAction(Action *a) { Actions[a->Type()] = a; }
|
|
||||||
static std::map<ActionType, Action *> Actions;
|
struct Dummy : public Action
|
||||||
|
{
|
||||||
|
Dummy() : Action(aDummy, "dummy") { }
|
||||||
|
virtual void Run() { }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MouseEvent : public Action
|
struct MouseEvent : public Action
|
||||||
|
|||||||
538
src/keys.cpp
538
src/keys.cpp
@@ -18,146 +18,70 @@
|
|||||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
#include "keys.h"
|
#include "keys.h"
|
||||||
|
#include "utility/comparators.h"
|
||||||
|
#include "utility/string.h"
|
||||||
|
|
||||||
KeyConfiguration Keys;
|
KeyConfiguration Keys;
|
||||||
|
|
||||||
Key Key::noOp = Key(ERR, NCurses);
|
Key Key::noOp = Key(ERR, NCurses);
|
||||||
|
|
||||||
void KeyConfiguration::generateBindings()
|
namespace {//
|
||||||
|
|
||||||
|
Key stringToKey(const std::string &s)
|
||||||
{
|
{
|
||||||
bind_(KEY_MOUSE, Key::NCurses, aMouseEvent);
|
Key result = Key::noOp;
|
||||||
bind_(KEY_UP, Key::NCurses, aScrollUp);
|
if (!s.compare("mouse"))
|
||||||
bind_(KEY_DOWN, Key::NCurses, aScrollDown);
|
result = Key(KEY_MOUSE, Key::NCurses);
|
||||||
bind_('[', Key::Standard, aScrollUpAlbum);
|
else if (!s.compare("up"))
|
||||||
bind_(']', Key::Standard, aScrollDownAlbum);
|
result = Key(KEY_UP, Key::NCurses);
|
||||||
bind_('{', Key::Standard, aScrollUpArtist);
|
else if (!s.compare("down"))
|
||||||
bind_('}', Key::Standard, aScrollDownArtist);
|
result = Key(KEY_DOWN, Key::NCurses);
|
||||||
bind_(KEY_PPAGE, Key::NCurses, aPageUp);
|
else if (!s.compare("page_up"))
|
||||||
bind_(KEY_NPAGE, Key::NCurses, aPageDown);
|
result = Key(KEY_PPAGE, Key::NCurses);
|
||||||
bind_(KEY_HOME, Key::NCurses, aMoveHome);
|
else if (!s.compare("page_down"))
|
||||||
bind_(KEY_END, Key::NCurses, aMoveEnd);
|
result = Key(KEY_NPAGE, Key::NCurses);
|
||||||
bind_(KEY_SPACE, Key::Standard, aPressSpace);
|
else if (!s.compare("home"))
|
||||||
bind_(KEY_ENTER, Key::Standard, aPressEnter);
|
result = Key(KEY_HOME, Key::NCurses);
|
||||||
bind_(KEY_DC, Key::NCurses, aDelete);
|
else if (!s.compare("end"))
|
||||||
bind_(KEY_RIGHT, Key::NCurses, aNextColumn);
|
result = Key(KEY_END, Key::NCurses);
|
||||||
bind_(KEY_RIGHT, Key::NCurses, aSlaveScreen);
|
else if (!s.compare("space"))
|
||||||
bind_(KEY_RIGHT, Key::NCurses, aVolumeUp);
|
result = Key(KEY_SPACE, Key::Standard);
|
||||||
bind_(KEY_LEFT, Key::NCurses, aPreviousColumn);
|
else if (!s.compare("enter"))
|
||||||
bind_(KEY_LEFT, Key::NCurses, aMasterScreen);
|
result = Key(KEY_ENTER, Key::Standard);
|
||||||
bind_(KEY_LEFT, Key::NCurses, aVolumeDown);
|
else if (!s.compare("delete"))
|
||||||
bind_(KEY_TAB, Key::Standard, aNextScreen);
|
result = Key(KEY_DC, Key::NCurses);
|
||||||
bind_(KEY_SHIFT_TAB, Key::NCurses, aPreviousScreen);
|
else if (!s.compare("left"))
|
||||||
bind_('1', Key::Standard, aShowHelp);
|
result = Key(KEY_LEFT, Key::NCurses);
|
||||||
bind_('2', Key::Standard, aShowPlaylist);
|
else if (!s.compare("right"))
|
||||||
bind_('3', Key::Standard, aShowBrowser);
|
result = Key(KEY_RIGHT, Key::NCurses);
|
||||||
bind_('4', Key::Standard, aShowSearchEngine);
|
else if (!s.compare("tab"))
|
||||||
bind_('5', Key::Standard, aShowMediaLibrary);
|
result = Key(KEY_TAB, Key::Standard);
|
||||||
bind_('6', Key::Standard, aShowPlaylistEditor);
|
else if (!s.compare("shift_tab"))
|
||||||
bind_('7', Key::Standard, aShowTagEditor);
|
result = Key(KEY_SHIFT_TAB, Key::NCurses);
|
||||||
bind_('8', Key::Standard, aShowOutputs);
|
else if (!s.compare(0, 5, "ctrl_") && s.length() > 5 && s[5] >= 'a' && s[5] <= 'z')
|
||||||
bind_('9', Key::Standard, aShowVisualizer);
|
result = Key(KEY_CTRL_A + (s[5] - 'a'), Key::Standard);
|
||||||
bind_('0', Key::Standard, aShowClock);
|
else if (s.length() > 1 && s[0] == 'f')
|
||||||
bind_('@', Key::Standard, aShowServerInfo);
|
{
|
||||||
bind_('s', Key::Standard, aStop);
|
int n = atoi(s.c_str() + 1);
|
||||||
bind_('P', Key::Standard, aPause);
|
if (n >= 1 && n <= 12)
|
||||||
bind_('>', Key::Standard, aNextSong);
|
result = Key(KEY_F1 + n - 1, Key::NCurses);
|
||||||
bind_('<', Key::Standard, aPreviousSong);
|
}
|
||||||
bind_(KEY_CTRL_H, Key::Standard, aJumpToParentDir);
|
else if (!s.compare("backspace"))
|
||||||
bind_(KEY_CTRL_H, Key::Standard, aReplaySong);
|
result = Key(KEY_BACKSPACE, Key::NCurses);
|
||||||
bind_(KEY_BACKSPACE, Key::NCurses, aJumpToParentDir);
|
else if (!s.compare("backspace_2"))
|
||||||
bind_(KEY_BACKSPACE, Key::NCurses, aReplaySong);
|
result = Key(KEY_BACKSPACE_2, Key::Standard);
|
||||||
bind_(KEY_BACKSPACE_2, Key::Standard, aJumpToParentDir);
|
else
|
||||||
bind_(KEY_BACKSPACE_2, Key::Standard, aReplaySong);
|
{
|
||||||
bind_('f', Key::Standard, aSeekForward);
|
std::wstring ws = ToWString(s);
|
||||||
bind_('b', Key::Standard, aSeekBackward);
|
if (ws.length() == 1)
|
||||||
bind_('r', Key::Standard, aToggleRepeat);
|
result = Key(ws[0], Key::Standard);
|
||||||
bind_('z', Key::Standard, aToggleRandom);
|
}
|
||||||
bind_('y', Key::Standard, aSaveTagChanges);
|
return result;
|
||||||
bind_('y', Key::Standard, aStartSearching);
|
}
|
||||||
bind_('y', Key::Standard, aToggleSingle);
|
|
||||||
bind_('R', Key::Standard, aToggleConsume);
|
|
||||||
bind_('Y', Key::Standard, aToggleReplayGainMode);
|
|
||||||
bind_('t', Key::Standard, aToggleSpaceMode);
|
|
||||||
bind_('T', Key::Standard, aToggleAddMode);
|
|
||||||
bind_('|', Key::Standard, aToggleMouse);
|
|
||||||
bind_('#', Key::Standard, aToggleBitrateVisibility);
|
|
||||||
bind_('Z', Key::Standard, aShuffle);
|
|
||||||
bind_('x', Key::Standard, aToggleCrossfade);
|
|
||||||
bind_('X', Key::Standard, aSetCrossfade);
|
|
||||||
bind_('u', Key::Standard, aUpdateDatabase);
|
|
||||||
bind_(KEY_CTRL_V, Key::Standard, aSortPlaylist);
|
|
||||||
bind_(KEY_CTRL_R, Key::Standard, aReversePlaylist);
|
|
||||||
bind_(KEY_CTRL_F, Key::Standard, aApplyFilter);
|
|
||||||
bind_(KEY_CTRL_G, Key::Standard, aDisableFilter);
|
|
||||||
bind_('/', Key::Standard, aFind);
|
|
||||||
bind_('/', Key::Standard, aFindItemForward);
|
|
||||||
bind_('?', Key::Standard, aFind);
|
|
||||||
bind_('?', Key::Standard, aFindItemBackward);
|
|
||||||
bind_('.', Key::Standard, aNextFoundItem);
|
|
||||||
bind_(',', Key::Standard, aPreviousFoundItem);
|
|
||||||
bind_('w', Key::Standard, aToggleFindMode);
|
|
||||||
bind_('e', Key::Standard, aEditSong);
|
|
||||||
bind_('e', Key::Standard, aEditLibraryTag);
|
|
||||||
bind_('e', Key::Standard, aEditLibraryAlbum);
|
|
||||||
bind_('e', Key::Standard, aEditDirectoryName);
|
|
||||||
bind_('e', Key::Standard, aEditPlaylistName);
|
|
||||||
bind_('e', Key::Standard, aEditLyrics);
|
|
||||||
bind_('i', Key::Standard, aShowSongInfo);
|
|
||||||
bind_('I', Key::Standard, aShowArtistInfo);
|
|
||||||
bind_('g', Key::Standard, aJumpToPositionInSong);
|
|
||||||
bind_('l', Key::Standard, aShowLyrics);
|
|
||||||
bind_('v', Key::Standard, aReverseSelection);
|
|
||||||
bind_('V', Key::Standard, aDeselectItems);
|
|
||||||
bind_('B', Key::Standard, aSelectAlbum);
|
|
||||||
bind_('a', Key::Standard, aAddSelectedItems);
|
|
||||||
bind_('c', Key::Standard, aClearPlaylist);
|
|
||||||
bind_('c', Key::Standard, aClearMainPlaylist);
|
|
||||||
bind_('C', Key::Standard, aCropPlaylist);
|
|
||||||
bind_('C', Key::Standard, aCropMainPlaylist);
|
|
||||||
bind_('m', Key::Standard, aMoveSortOrderUp);
|
|
||||||
bind_('m', Key::Standard, aMoveSelectedItemsUp);
|
|
||||||
bind_('n', Key::Standard, aMoveSortOrderDown);
|
|
||||||
bind_('n', Key::Standard, aMoveSelectedItemsDown);
|
|
||||||
bind_('M', Key::Standard, aMoveSelectedItemsTo);
|
|
||||||
bind_('A', Key::Standard, aAdd);
|
|
||||||
bind_('S', Key::Standard, aSavePlaylist);
|
|
||||||
bind_('o', Key::Standard, aJumpToPlayingSong);
|
|
||||||
bind_('G', Key::Standard, aJumpToBrowser);
|
|
||||||
bind_('G', Key::Standard, aJumpToPlaylistEditor);
|
|
||||||
bind_('~', Key::Standard, aJumpToMediaLibrary);
|
|
||||||
bind_('E', Key::Standard, aJumpToTagEditor);
|
|
||||||
bind_('U', Key::Standard, aToggleAutoCenter);
|
|
||||||
bind_('p', Key::Standard, aToggleDisplayMode);
|
|
||||||
bind_('\\', Key::Standard, aToggleInterface);
|
|
||||||
bind_('!', Key::Standard, aToggleSeparatorsInPlaylist);
|
|
||||||
bind_('L', Key::Standard, aToggleLyricsFetcher);
|
|
||||||
bind_('F', Key::Standard, aToggleFetchingLyricsInBackground);
|
|
||||||
bind_(KEY_CTRL_L, Key::Standard, aToggleScreenLock);
|
|
||||||
bind_('`', Key::Standard, aToggleBrowserSortMode);
|
|
||||||
bind_('`', Key::Standard, aToggleLibraryTagType);
|
|
||||||
bind_('`', Key::Standard, aRefetchLyrics);
|
|
||||||
bind_('`', Key::Standard, aRefetchArtistInfo);
|
|
||||||
bind_('`', Key::Standard, aAddRandomItems);
|
|
||||||
bind_(KEY_CTRL_P, Key::Standard, aSetSelectedItemsPriority);
|
|
||||||
bind_('q', Key::Standard, aQuit);
|
|
||||||
|
|
||||||
bind_('k', Key::Standard, aScrollUp);
|
|
||||||
bind_('j', Key::Standard, aScrollDown);
|
|
||||||
bind_('d', Key::Standard, aDelete);
|
|
||||||
bind_('+', Key::Standard, aVolumeUp);
|
|
||||||
bind_('-', Key::Standard, aVolumeDown);
|
|
||||||
bind_(KEY_F1, Key::NCurses, aShowHelp);
|
|
||||||
bind_(KEY_F2, Key::NCurses, aShowPlaylist);
|
|
||||||
bind_(KEY_F3, Key::NCurses, aShowBrowser);
|
|
||||||
bind_(KEY_F4, Key::NCurses, aShowSearchEngine);
|
|
||||||
bind_(KEY_F5, Key::NCurses, aShowMediaLibrary);
|
|
||||||
bind_(KEY_F6, Key::NCurses, aShowPlaylistEditor);
|
|
||||||
bind_(KEY_F7, Key::NCurses, aShowTagEditor);
|
|
||||||
bind_(KEY_F8, Key::NCurses, aShowOutputs);
|
|
||||||
bind_(KEY_F9, Key::NCurses, aShowVisualizer);
|
|
||||||
bind_(KEY_F10, Key::NCurses, aShowClock);
|
|
||||||
bind_('Q', Key::Standard, aQuit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Key Key::read(NC::Window &w)
|
Key Key::read(NC::Window &w)
|
||||||
@@ -193,3 +117,351 @@ Key Key::read(NC::Window &w)
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool KeyConfiguration::read(const std::string &file)
|
||||||
|
{
|
||||||
|
bool result = true;
|
||||||
|
|
||||||
|
std::ifstream f(file);
|
||||||
|
if (!f.is_open())
|
||||||
|
return result;
|
||||||
|
|
||||||
|
size_t line_no = 0;
|
||||||
|
bool key_def_in_progress = false;
|
||||||
|
Key key = Key::noOp;
|
||||||
|
Binding::ActionChain actions;
|
||||||
|
std::string line, strkey;
|
||||||
|
|
||||||
|
auto error = [&]() -> std::ostream & {
|
||||||
|
std::cerr << file << ":" << line_no << ": ";
|
||||||
|
key_def_in_progress = false;
|
||||||
|
result = false;
|
||||||
|
return std::cerr;
|
||||||
|
};
|
||||||
|
auto bind_key_def = [&]() -> bool {
|
||||||
|
if (!actions.empty())
|
||||||
|
{
|
||||||
|
bind(key, actions);
|
||||||
|
actions.clear();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error() << "definition of key \"" << strkey << "\" cannot be empty.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
while (!f.eof() && ++line_no)
|
||||||
|
{
|
||||||
|
getline(f, line);
|
||||||
|
if (line.empty() || line[0] == '#')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!line.compare(0, 7, "def_key")) // beginning of key definition
|
||||||
|
{
|
||||||
|
if (key_def_in_progress)
|
||||||
|
{
|
||||||
|
if (!bind_key_def())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
key_def_in_progress = true;
|
||||||
|
strkey = getEnclosedString(line, '"', '"', 0);
|
||||||
|
key = stringToKey(strkey);
|
||||||
|
if (key == Key::noOp)
|
||||||
|
{
|
||||||
|
error() << "invalid key: \"" << strkey << "\"\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (isspace(line[0])) // name of action to be bound
|
||||||
|
{
|
||||||
|
trim(line);
|
||||||
|
Action *action = Action::Get(line);
|
||||||
|
if (action)
|
||||||
|
actions.push_back(action);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error() << "unknown action: \"" << line << "\"\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (key_def_in_progress)
|
||||||
|
bind_key_def();
|
||||||
|
f.close();
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyConfiguration::generateBindings()
|
||||||
|
{
|
||||||
|
Key k = Key::noOp;
|
||||||
|
if (notBound(k = stringToKey("mouse")))
|
||||||
|
bind(k, aMouseEvent);
|
||||||
|
if (notBound(k = stringToKey("up")))
|
||||||
|
bind(k, aScrollUp);
|
||||||
|
if (notBound(k = stringToKey("down")))
|
||||||
|
bind(k, aScrollDown);
|
||||||
|
if (notBound(k = stringToKey("[")))
|
||||||
|
bind(k, aScrollUpAlbum);
|
||||||
|
if (notBound(k = stringToKey("]")))
|
||||||
|
bind(k, aScrollDownAlbum);
|
||||||
|
if (notBound(k = stringToKey("{")))
|
||||||
|
bind(k, aScrollUpArtist);
|
||||||
|
if (notBound(k = stringToKey("}")))
|
||||||
|
bind(k, aScrollDownArtist);
|
||||||
|
if (notBound(k = stringToKey("page_up")))
|
||||||
|
bind(k, aPageUp);
|
||||||
|
if (notBound(k = stringToKey("page_down")))
|
||||||
|
bind(k, aPageDown);
|
||||||
|
if (notBound(k = stringToKey("home")))
|
||||||
|
bind(k, aMoveHome);
|
||||||
|
if (notBound(k = stringToKey("end")))
|
||||||
|
bind(k, aMoveEnd);
|
||||||
|
if (notBound(k = stringToKey("space")))
|
||||||
|
bind(k, aPressSpace);
|
||||||
|
if (notBound(k = stringToKey("enter")))
|
||||||
|
bind(k, aPressEnter);
|
||||||
|
if (notBound(k = stringToKey("delete")))
|
||||||
|
bind(k, aDelete);
|
||||||
|
if (notBound(k = stringToKey("right")))
|
||||||
|
{
|
||||||
|
bind(k, aNextColumn);
|
||||||
|
bind(k, aSlaveScreen);
|
||||||
|
bind(k, aVolumeUp);
|
||||||
|
}
|
||||||
|
if (notBound(k = stringToKey("left")))
|
||||||
|
{
|
||||||
|
bind(k, aPreviousColumn);
|
||||||
|
bind(k, aMasterScreen);
|
||||||
|
bind(k, aVolumeDown);
|
||||||
|
}
|
||||||
|
if (notBound(k = stringToKey("tab")))
|
||||||
|
bind(k, aNextScreen);
|
||||||
|
if (notBound(k = stringToKey("shift_tab")))
|
||||||
|
bind(k, aPreviousScreen);
|
||||||
|
if (notBound(k = stringToKey("1")))
|
||||||
|
bind(k, aShowHelp);
|
||||||
|
if (notBound(k = stringToKey("2")))
|
||||||
|
bind(k, aShowPlaylist);
|
||||||
|
if (notBound(k = stringToKey("3")))
|
||||||
|
bind(k, aShowBrowser);
|
||||||
|
if (notBound(k = stringToKey("4")))
|
||||||
|
bind(k, aShowSearchEngine);
|
||||||
|
if (notBound(k = stringToKey("5")))
|
||||||
|
bind(k, aShowMediaLibrary);
|
||||||
|
if (notBound(k = stringToKey("6")))
|
||||||
|
bind(k, aShowPlaylistEditor);
|
||||||
|
if (notBound(k = stringToKey("7")))
|
||||||
|
bind(k, aShowTagEditor);
|
||||||
|
if (notBound(k = stringToKey("8")))
|
||||||
|
bind(k, aShowOutputs);
|
||||||
|
if (notBound(k = stringToKey("9")))
|
||||||
|
bind(k, aShowVisualizer);
|
||||||
|
if (notBound(k = stringToKey("0")))
|
||||||
|
bind(k, aShowClock);
|
||||||
|
if (notBound(k = stringToKey("@")))
|
||||||
|
bind(k, aShowServerInfo);
|
||||||
|
if (notBound(k = stringToKey("s")))
|
||||||
|
bind(k, aStop);
|
||||||
|
if (notBound(k = stringToKey("P")))
|
||||||
|
bind(k, aPause);
|
||||||
|
if (notBound(k = stringToKey(">")))
|
||||||
|
bind(k, aNextSong);
|
||||||
|
if (notBound(k = stringToKey("<")))
|
||||||
|
bind(k, aPreviousSong);
|
||||||
|
if (notBound(k = stringToKey("ctrl_h")))
|
||||||
|
{
|
||||||
|
bind(k, aJumpToParentDir);
|
||||||
|
bind(k, aReplaySong);
|
||||||
|
}
|
||||||
|
if (notBound(k = stringToKey("backspace")))
|
||||||
|
{
|
||||||
|
bind(k, aJumpToParentDir);
|
||||||
|
bind(k, aReplaySong);
|
||||||
|
}
|
||||||
|
if (notBound(k = stringToKey("backspace_2")))
|
||||||
|
{
|
||||||
|
bind(k, aJumpToParentDir);
|
||||||
|
bind(k, aReplaySong);
|
||||||
|
}
|
||||||
|
if (notBound(k = stringToKey("f")))
|
||||||
|
bind(k, aSeekForward);
|
||||||
|
if (notBound(k = stringToKey("b")))
|
||||||
|
bind(k, aSeekBackward);
|
||||||
|
if (notBound(k = stringToKey("r")))
|
||||||
|
bind(k, aToggleRepeat);
|
||||||
|
if (notBound(k = stringToKey("z")))
|
||||||
|
bind(k, aToggleRandom);
|
||||||
|
if (notBound(k = stringToKey("y")))
|
||||||
|
{
|
||||||
|
bind(k, aSaveTagChanges);
|
||||||
|
bind(k, aStartSearching);
|
||||||
|
bind(k, aToggleSingle);
|
||||||
|
}
|
||||||
|
if (notBound(k = stringToKey("R")))
|
||||||
|
bind(k, aToggleConsume);
|
||||||
|
if (notBound(k = stringToKey("Y")))
|
||||||
|
bind(k, aToggleReplayGainMode);
|
||||||
|
if (notBound(k = stringToKey("t")))
|
||||||
|
bind(k, aToggleSpaceMode);
|
||||||
|
if (notBound(k = stringToKey("T")))
|
||||||
|
bind(k, aToggleAddMode);
|
||||||
|
if (notBound(k = stringToKey("|")))
|
||||||
|
bind(k, aToggleMouse);
|
||||||
|
if (notBound(k = stringToKey("#")))
|
||||||
|
bind(k, aToggleBitrateVisibility);
|
||||||
|
if (notBound(k = stringToKey("Z")))
|
||||||
|
bind(k, aShuffle);
|
||||||
|
if (notBound(k = stringToKey("x")))
|
||||||
|
bind(k, aToggleCrossfade);
|
||||||
|
if (notBound(k = stringToKey("X")))
|
||||||
|
bind(k, aSetCrossfade);
|
||||||
|
if (notBound(k = stringToKey("u")))
|
||||||
|
bind(k, aUpdateDatabase);
|
||||||
|
if (notBound(k = stringToKey("ctrl_v")))
|
||||||
|
bind(k, aSortPlaylist);
|
||||||
|
if (notBound(k = stringToKey("ctrl_r")))
|
||||||
|
bind(k, aReversePlaylist);
|
||||||
|
if (notBound(k = stringToKey("ctrl_f")))
|
||||||
|
bind(k, aApplyFilter);
|
||||||
|
if (notBound(k = stringToKey("ctrl_g")))
|
||||||
|
bind(k, aDisableFilter);
|
||||||
|
if (notBound(k = stringToKey("/")))
|
||||||
|
{
|
||||||
|
bind(k, aFind);
|
||||||
|
bind(k, aFindItemForward);
|
||||||
|
}
|
||||||
|
if (notBound(k = stringToKey("/")))
|
||||||
|
{
|
||||||
|
bind(k, aFind);
|
||||||
|
bind(k, aFindItemBackward);
|
||||||
|
}
|
||||||
|
if (notBound(k = stringToKey(".")))
|
||||||
|
bind(k, aNextFoundItem);
|
||||||
|
if (notBound(k = stringToKey(",")))
|
||||||
|
bind(k, aPreviousFoundItem);
|
||||||
|
if (notBound(k = stringToKey("w")))
|
||||||
|
bind(k, aToggleFindMode);
|
||||||
|
if (notBound(k = stringToKey("e")))
|
||||||
|
{
|
||||||
|
bind(k, aEditSong);
|
||||||
|
bind(k, aEditLibraryTag);
|
||||||
|
bind(k, aEditLibraryAlbum);
|
||||||
|
bind(k, aEditDirectoryName);
|
||||||
|
bind(k, aEditPlaylistName);
|
||||||
|
bind(k, aEditLyrics);
|
||||||
|
}
|
||||||
|
if (notBound(k = stringToKey("i")))
|
||||||
|
bind(k, aShowSongInfo);
|
||||||
|
if (notBound(k = stringToKey("I")))
|
||||||
|
bind(k, aShowArtistInfo);
|
||||||
|
if (notBound(k = stringToKey("g")))
|
||||||
|
bind(k, aJumpToPositionInSong);
|
||||||
|
if (notBound(k = stringToKey("l")))
|
||||||
|
bind(k, aShowLyrics);
|
||||||
|
if (notBound(k = stringToKey("v")))
|
||||||
|
bind(k, aReverseSelection);
|
||||||
|
if (notBound(k = stringToKey("B")))
|
||||||
|
bind(k, aSelectAlbum);
|
||||||
|
if (notBound(k = stringToKey("a")))
|
||||||
|
bind(k, aAddSelectedItems);
|
||||||
|
if (notBound(k = stringToKey("c")))
|
||||||
|
{
|
||||||
|
bind(k, aClearPlaylist);
|
||||||
|
bind(k, aClearMainPlaylist);
|
||||||
|
}
|
||||||
|
if (notBound(k = stringToKey("C")))
|
||||||
|
{
|
||||||
|
bind(k, aCropPlaylist);
|
||||||
|
bind(k, aCropMainPlaylist);
|
||||||
|
}
|
||||||
|
if (notBound(k = stringToKey("m")))
|
||||||
|
{
|
||||||
|
bind(k, aMoveSortOrderUp);
|
||||||
|
bind(k, aMoveSelectedItemsUp);
|
||||||
|
}
|
||||||
|
if (notBound(k = stringToKey("n")))
|
||||||
|
{
|
||||||
|
bind(k, aMoveSortOrderDown);
|
||||||
|
bind(k, aMoveSelectedItemsDown);
|
||||||
|
}
|
||||||
|
if (notBound(k = stringToKey("M")))
|
||||||
|
bind(k, aMoveSelectedItemsTo);
|
||||||
|
if (notBound(k = stringToKey("A")))
|
||||||
|
bind(k, aAdd);
|
||||||
|
if (notBound(k = stringToKey("S")))
|
||||||
|
bind(k, aSavePlaylist);
|
||||||
|
if (notBound(k = stringToKey("o")))
|
||||||
|
bind(k, aJumpToPlayingSong);
|
||||||
|
if (notBound(k = stringToKey("G")))
|
||||||
|
{
|
||||||
|
bind(k, aJumpToBrowser);
|
||||||
|
bind(k, aJumpToPlaylistEditor);
|
||||||
|
}
|
||||||
|
if (notBound(k = stringToKey("~")))
|
||||||
|
bind(k, aJumpToMediaLibrary);
|
||||||
|
if (notBound(k = stringToKey("E")))
|
||||||
|
bind(k, aJumpToTagEditor);
|
||||||
|
if (notBound(k = stringToKey("U")))
|
||||||
|
bind(k, aToggleAutoCenter);
|
||||||
|
if (notBound(k = stringToKey("p")))
|
||||||
|
bind(k, aToggleDisplayMode);
|
||||||
|
if (notBound(k = stringToKey("\\")))
|
||||||
|
bind(k, aToggleInterface);
|
||||||
|
if (notBound(k = stringToKey("!")))
|
||||||
|
bind(k, aToggleSeparatorsInPlaylist);
|
||||||
|
if (notBound(k = stringToKey("L")))
|
||||||
|
bind(k, aToggleLyricsFetcher);
|
||||||
|
if (notBound(k = stringToKey("F")))
|
||||||
|
bind(k, aToggleFetchingLyricsInBackground);
|
||||||
|
if (notBound(k = stringToKey("ctrl_l")))
|
||||||
|
bind(k, aToggleScreenLock);
|
||||||
|
if (notBound(k = stringToKey("`")))
|
||||||
|
{
|
||||||
|
bind(k, aToggleBrowserSortMode);
|
||||||
|
bind(k, aToggleLibraryTagType);
|
||||||
|
bind(k, aRefetchLyrics);
|
||||||
|
bind(k, aRefetchArtistInfo);
|
||||||
|
bind(k, aAddRandomItems);
|
||||||
|
}
|
||||||
|
if (notBound(k = stringToKey("ctrl_p")))
|
||||||
|
bind(k, aSetSelectedItemsPriority);
|
||||||
|
if (notBound(k = stringToKey("q")))
|
||||||
|
bind(k, aQuit);
|
||||||
|
|
||||||
|
if (notBound(k = stringToKey("k")))
|
||||||
|
bind(k, aScrollUp);
|
||||||
|
if (notBound(k = stringToKey("j")))
|
||||||
|
bind(k, aScrollDown);
|
||||||
|
if (notBound(k = stringToKey("d")))
|
||||||
|
bind(k, aDelete);
|
||||||
|
if (notBound(k = stringToKey("+")))
|
||||||
|
bind(k, aVolumeUp);
|
||||||
|
if (notBound(k = stringToKey("-")))
|
||||||
|
bind(k, aVolumeDown);
|
||||||
|
|
||||||
|
if (notBound(k = stringToKey("f1")))
|
||||||
|
bind(k, aShowHelp);
|
||||||
|
if (notBound(k = stringToKey("f2")))
|
||||||
|
bind(k, aShowPlaylist);
|
||||||
|
if (notBound(k = stringToKey("f3")))
|
||||||
|
bind(k, aShowBrowser);
|
||||||
|
if (notBound(k = stringToKey("f4")))
|
||||||
|
bind(k, aShowSearchEngine);
|
||||||
|
if (notBound(k = stringToKey("f5")))
|
||||||
|
bind(k, aShowMediaLibrary);
|
||||||
|
if (notBound(k = stringToKey("f6")))
|
||||||
|
bind(k, aShowPlaylistEditor);
|
||||||
|
if (notBound(k = stringToKey("f7")))
|
||||||
|
bind(k, aShowTagEditor);
|
||||||
|
if (notBound(k = stringToKey("f8")))
|
||||||
|
bind(k, aShowOutputs);
|
||||||
|
if (notBound(k = stringToKey("f9")))
|
||||||
|
bind(k, aShowVisualizer);
|
||||||
|
if (notBound(k = stringToKey("f10")))
|
||||||
|
bind(k, aShowClock);
|
||||||
|
if (notBound(k = stringToKey("Q")))
|
||||||
|
bind(k, aQuit);
|
||||||
|
}
|
||||||
|
|||||||
53
src/keys.h
53
src/keys.h
@@ -31,12 +31,15 @@ struct Key
|
|||||||
|
|
||||||
Key(wchar_t ch, Type ct) : m_char(ch), m_type(ct) { }
|
Key(wchar_t ch, Type ct) : m_char(ch), m_type(ct) { }
|
||||||
|
|
||||||
wchar_t getChar() const { return m_char; }
|
wchar_t getChar() const {
|
||||||
Type getType() const { return m_type; }
|
return m_char;
|
||||||
|
}
|
||||||
|
Type getType() const {
|
||||||
|
return m_type;
|
||||||
|
}
|
||||||
|
|
||||||
# define KEYS_DEFINE_OPERATOR(CMP) \
|
# define KEYS_DEFINE_OPERATOR(CMP) \
|
||||||
bool operator CMP (const Key &k) const \
|
bool operator CMP (const Key &k) const { \
|
||||||
{ \
|
|
||||||
if (m_char CMP k.m_char) \
|
if (m_char CMP k.m_char) \
|
||||||
return true; \
|
return true; \
|
||||||
if (m_char != k.m_char) \
|
if (m_char != k.m_char) \
|
||||||
@@ -49,8 +52,12 @@ struct Key
|
|||||||
KEYS_DEFINE_OPERATOR(>=);
|
KEYS_DEFINE_OPERATOR(>=);
|
||||||
# undef KEYS_DEFINE_OPERATOR
|
# undef KEYS_DEFINE_OPERATOR
|
||||||
|
|
||||||
bool operator==(const Key &k) const { return m_char == k.m_char && m_type == k.m_type; }
|
bool operator==(const Key &k) const {
|
||||||
bool operator!=(const Key &k) const { return !(*this == k); }
|
return m_char == k.m_char && m_type == k.m_type;
|
||||||
|
}
|
||||||
|
bool operator!=(const Key &k) const {
|
||||||
|
return !(*this == k);
|
||||||
|
}
|
||||||
|
|
||||||
static Key read(NC::Window &w);
|
static Key read(NC::Window &w);
|
||||||
static Key noOp;
|
static Key noOp;
|
||||||
@@ -66,11 +73,28 @@ struct Binding
|
|||||||
typedef std::vector<Action *> ActionChain;
|
typedef std::vector<Action *> ActionChain;
|
||||||
|
|
||||||
Binding(ActionType at) : m_is_single(true), m_action(Action::Get(at)) { }
|
Binding(ActionType at) : m_is_single(true), m_action(Action::Get(at)) { }
|
||||||
Binding(ActionChain *chain_) : m_is_single(false), m_chain(chain_) { }
|
Binding(const ActionChain &actions) {
|
||||||
|
assert(actions.size() > 0);
|
||||||
|
if (actions.size() == 1) {
|
||||||
|
m_is_single = true;
|
||||||
|
m_action = actions[0];
|
||||||
|
} else {
|
||||||
|
m_is_single = false;
|
||||||
|
m_chain = new ActionChain(actions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool isSingle() const { return m_is_single; }
|
bool isSingle() const {
|
||||||
ActionChain *chain() const { assert(!m_is_single); return m_chain; }
|
return m_is_single;
|
||||||
Action *action() const { assert(m_is_single); return m_action; }
|
}
|
||||||
|
ActionChain *chain() const {
|
||||||
|
assert(!m_is_single);
|
||||||
|
return m_chain;
|
||||||
|
}
|
||||||
|
Action *action() const {
|
||||||
|
assert(m_is_single);
|
||||||
|
return m_action;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_is_single;
|
bool m_is_single;
|
||||||
@@ -83,13 +107,18 @@ private:
|
|||||||
/// Key configuration
|
/// Key configuration
|
||||||
struct KeyConfiguration
|
struct KeyConfiguration
|
||||||
{
|
{
|
||||||
|
bool read(const std::string &file);
|
||||||
void generateBindings();
|
void generateBindings();
|
||||||
|
|
||||||
std::multimap<Key, Binding> Bindings;
|
std::multimap<Key, Binding> Bindings;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename T> void bind_(wchar_t c, Key::Type ct, T t) {
|
bool notBound(const Key &k) const {
|
||||||
Bindings.insert(std::make_pair(Key(c, ct), Binding(t)));
|
return k != Key::noOp && Bindings.find(k) == Bindings.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> void bind(Key k, T t) {
|
||||||
|
Bindings.insert(std::make_pair(k, Binding(t)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -922,7 +922,7 @@ bool SortAllTracks(const MPD::Song &a, const MPD::Song &b)
|
|||||||
&MPD::Song::getAlbum,
|
&MPD::Song::getAlbum,
|
||||||
&MPD::Song::getDisc
|
&MPD::Song::getDisc
|
||||||
}};
|
}};
|
||||||
CaseInsensitiveStringComparison cmp;
|
CaseInsensitiveStringComparison cmp(Config.ignore_leading_the);
|
||||||
for (auto get = gets.begin(); get != gets.end(); ++get)
|
for (auto get = gets.begin(); get != gets.end(); ++get)
|
||||||
{
|
{
|
||||||
int ret = cmp(a.getTags(*get), b.getTags(*get));
|
int ret = cmp(a.getTags(*get), b.getTags(*get));
|
||||||
@@ -935,7 +935,7 @@ bool SortAllTracks(const MPD::Song &a, const MPD::Song &b)
|
|||||||
bool SortSearchConstraints(const SearchConstraints &a, const SearchConstraints &b)
|
bool SortSearchConstraints(const SearchConstraints &a, const SearchConstraints &b)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
CaseInsensitiveStringComparison cmp;
|
CaseInsensitiveStringComparison cmp(Config.ignore_leading_the);
|
||||||
result = cmp(a.PrimaryTag, b.PrimaryTag);
|
result = cmp(a.PrimaryTag, b.PrimaryTag);
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
return result < 0;
|
return result < 0;
|
||||||
|
|||||||
@@ -96,8 +96,11 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
Config.SetDefaults();
|
Config.SetDefaults();
|
||||||
Config.Read();
|
Config.Read();
|
||||||
|
|
||||||
Config.GenerateColumns();
|
Config.GenerateColumns();
|
||||||
|
|
||||||
|
if (!Keys.read(Config.ncmpcpp_directory + "keys"))
|
||||||
|
return 1;
|
||||||
|
|
||||||
Keys.generateBindings();
|
Keys.generateBindings();
|
||||||
|
|
||||||
if (getenv("MPD_HOST"))
|
if (getenv("MPD_HOST"))
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ void Playlist::EnterPressed()
|
|||||||
|
|
||||||
std::function<void(MPD::SongList::iterator, MPD::SongList::iterator)> iter_swap, quick_sort;
|
std::function<void(MPD::SongList::iterator, MPD::SongList::iterator)> iter_swap, quick_sort;
|
||||||
auto song_cmp = [](const MPD::Song &a, const MPD::Song &b) -> bool {
|
auto song_cmp = [](const MPD::Song &a, const MPD::Song &b) -> bool {
|
||||||
CaseInsensitiveStringComparison cmp;
|
CaseInsensitiveStringComparison cmp(Config.ignore_leading_the);
|
||||||
for (size_t i = 0; i < SortOptions; ++i)
|
for (size_t i = 0; i < SortOptions; ++i)
|
||||||
if (int ret = cmp(a.getTags((*SortDialog)[i].value().second), b.getTags((*SortDialog)[i].value().second)))
|
if (int ret = cmp(a.getTags((*SortDialog)[i].value().second), b.getTags((*SortDialog)[i].value().second)))
|
||||||
return ret < 0;
|
return ret < 0;
|
||||||
|
|||||||
@@ -536,7 +536,7 @@ void SearchEngine::Search()
|
|||||||
}
|
}
|
||||||
else // match only if values are equal
|
else // match only if values are equal
|
||||||
{
|
{
|
||||||
CaseInsensitiveStringComparison cmp;
|
CaseInsensitiveStringComparison cmp(Config.ignore_leading_the);
|
||||||
|
|
||||||
if (!itsConstraints[0].empty())
|
if (!itsConstraints[0].empty())
|
||||||
any_found =
|
any_found =
|
||||||
|
|||||||
@@ -21,24 +21,32 @@
|
|||||||
#include "comparators.h"
|
#include "comparators.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
int CaseInsensitiveStringComparison::operator()(const std::string &a, const std::string &b)
|
bool CaseInsensitiveStringComparison::hasTheWord(const char *s) const
|
||||||
{
|
{
|
||||||
const char *i = a.c_str();
|
return (s[0] == 't' || s[0] == 'T')
|
||||||
const char *j = b.c_str();
|
&& (s[1] == 'h' || s[1] == 'H')
|
||||||
if (Config.ignore_leading_the)
|
&& (s[2] == 'e' || s[2] == 'E')
|
||||||
|
&& (s[3] == ' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
int CaseInsensitiveStringComparison::operator()(const char *a, const char *b) const
|
||||||
|
{
|
||||||
|
if (m_ignore_the)
|
||||||
{
|
{
|
||||||
if (hasTheWord(a))
|
if (hasTheWord(a))
|
||||||
i += 4;
|
a += 4;
|
||||||
if (hasTheWord(b))
|
if (hasTheWord(b))
|
||||||
j += 4;
|
b += 4;
|
||||||
}
|
}
|
||||||
int dist;
|
int dist;
|
||||||
while (!(dist = tolower(*i)-tolower(*j)) && *j)
|
while (!(dist = tolower(*a)-tolower(*b)) && *b)
|
||||||
++i, ++j;
|
++a, ++b;
|
||||||
return dist;
|
return dist;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CaseInsensitiveSorting::operator()(const MPD::Item &a, const MPD::Item &b)
|
CaseInsensitiveSorting::CaseInsensitiveSorting(): cmp(Config.ignore_leading_the) { }
|
||||||
|
|
||||||
|
bool CaseInsensitiveSorting::operator()(const MPD::Item &a, const MPD::Item &b) const
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
if (a.type == b.type)
|
if (a.type == b.type)
|
||||||
@@ -65,8 +73,6 @@ bool CaseInsensitiveSorting::operator()(const MPD::Item &a, const MPD::Item &b)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default: // there is no other option, silence compiler
|
|
||||||
assert(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -26,17 +26,24 @@
|
|||||||
|
|
||||||
class CaseInsensitiveStringComparison
|
class CaseInsensitiveStringComparison
|
||||||
{
|
{
|
||||||
bool hasTheWord(const std::string &s)
|
bool m_ignore_the;
|
||||||
{
|
|
||||||
return (s.length() > 3)
|
bool hasTheWord(const char *s) const;
|
||||||
&& (s[0] == 't' || s[0] == 'T')
|
|
||||||
&& (s[1] == 'h' || s[1] == 'H')
|
|
||||||
&& (s[2] == 'e' || s[2] == 'E')
|
|
||||||
&& (s[3] == ' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int operator()(const std::string &a, const std::string &b);
|
CaseInsensitiveStringComparison(bool ignore_the) : m_ignore_the(ignore_the) { }
|
||||||
|
|
||||||
|
int operator()(const char *a, const char *b) const;
|
||||||
|
|
||||||
|
int operator()(const char *a, const std::string &b) const {
|
||||||
|
return (*this)(a, b.c_str());
|
||||||
|
}
|
||||||
|
int operator()(const std::string &a, const char *b) const {
|
||||||
|
return (*this)(a.c_str(), b);
|
||||||
|
}
|
||||||
|
int operator()(const std::string &a, const std::string &b) const {
|
||||||
|
return (*this)(a.c_str(), b.c_str());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CaseInsensitiveSorting
|
class CaseInsensitiveSorting
|
||||||
@@ -44,22 +51,22 @@ class CaseInsensitiveSorting
|
|||||||
CaseInsensitiveStringComparison cmp;
|
CaseInsensitiveStringComparison cmp;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool operator()(const std::string &a, const std::string &b)
|
CaseInsensitiveSorting();
|
||||||
{
|
|
||||||
|
bool operator()(const std::string &a, const std::string &b) const {
|
||||||
return cmp(a, b) < 0;
|
return cmp(a, b) < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator()(const MPD::Song &a, const MPD::Song &b)
|
bool operator()(const MPD::Song &a, const MPD::Song &b) const {
|
||||||
{
|
|
||||||
return cmp(a.getName(), b.getName()) < 0;
|
return cmp(a.getName(), b.getName()) < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename A, typename B> bool operator()(const std::pair<A, B> &a, const std::pair<A, B> &b)
|
template <typename A, typename B>
|
||||||
{
|
bool operator()(const std::pair<A, B> &a, const std::pair<A, B> &b) const {
|
||||||
return cmp(a.first, b.first) < 0;
|
return cmp(a.first, b.first) < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator()(const MPD::Item &a, const MPD::Item &b);
|
bool operator()(const MPD::Item &a, const MPD::Item &b) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _UTILITY_COMPARATORS
|
#endif // _UTILITY_COMPARATORS
|
||||||
|
|||||||
Reference in New Issue
Block a user