keybinding system rewrite

This commit is contained in:
Andrzej Rybczak
2012-07-18 01:34:55 +02:00
parent 4cf9fe33db
commit 181224b837
34 changed files with 4401 additions and 3270 deletions

View File

@@ -1,10 +1,11 @@
bin_PROGRAMS = ncmpcpp
ncmpcpp_SOURCES = browser.cpp charset.cpp clock.cpp conv.cpp curl_handle.cpp \
display.cpp error.cpp help.cpp helpers.cpp lastfm.cpp lastfm_service.cpp lyrics.cpp \
lyrics_fetcher.cpp media_library.cpp menu.cpp mpdpp.cpp ncmpcpp.cpp outputs.cpp \
playlist.cpp playlist_editor.cpp screen.cpp scrollpad.cpp search_engine.cpp \
sel_items_adder.cpp server_info.cpp settings.cpp song.cpp song_info.cpp status.cpp \
tag_editor.cpp tiny_tag_editor.cpp tolower.cpp visualizer.cpp window.cpp
ncmpcpp_SOURCES = actions.cpp browser.cpp charset.cpp clock.cpp conv.cpp \
curl_handle.cpp display.cpp error.cpp help.cpp helpers.cpp lastfm.cpp \
lastfm_service.cpp lyrics.cpp lyrics_fetcher.cpp media_library.cpp menu.cpp mpdpp.cpp \
ncmpcpp.cpp outputs.cpp playlist.cpp playlist_editor.cpp screen.cpp scrollpad.cpp \
search_engine.cpp sel_items_adder.cpp server_info.cpp settings.cpp song.cpp song_info.cpp \
status.cpp tag_editor.cpp tiny_tag_editor.cpp tolower.cpp visualizer.cpp \
window.cpp
# set the include path found by configure
INCLUDES= $(all_includes)

2616
src/actions.cpp Normal file

File diff suppressed because it is too large Load Diff

840
src/actions.h Normal file
View File

@@ -0,0 +1,840 @@
/***************************************************************************
* Copyright (C) 2008-2012 by Andrzej Rybczak *
* electricityispower@gmail.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef _ACTIONS_H
#define _ACTIONS_H
#include <map>
#include <string>
#include "ncmpcpp.h"
enum ActionType
{
aMouseEvent, aScrollUp, aScrollDown, aScrollUpArtist, aScrollUpAlbum, aScrollDownArtist,
aScrollDownAlbum, aPageUp, aPageDown, aMoveHome, aMoveEnd, aToggleInterface, aJumpToParentDir,
aPressEnter, aPressSpace, aPreviousColumn, aNextColumn, aMasterScreen, aSlaveScreen, aVolumeUp,
aVolumeDown, aDelete, aReplaySong, aPreviousSong, aNextSong, aPause, aStop, aSavePlaylist,
aMoveSortOrderUp, aMoveSortOrderDown, aMoveSelectedItemsUp, aMoveSelectedItemsDown,
aMoveSelectedItemsTo, aAdd, aSeekForward, aSeekBackward, aToggleDisplayMode, aToggleSeparatorsInPlaylist,
aToggleLyricsFetcher, aToggleFetchingLyricsInBackground, aToggleAutoCenter, aUpdateDatabase,
aJumpToPlayingSong, aToggleRepeat, aShuffle, aToggleRandom, aStartSearching, aSaveTagChanges,
aToggleSingle, aToggleConsume, aToggleCrossfade, aSetCrossfade, aEditSong, aEditLibraryTag,
aEditLibraryAlbum, aEditDirectoryName, aEditPlaylistName, aEditLyrics, aJumpToBrowser,
aJumpToMediaLibrary, aJumpToPlaylistEditor, aToggleScreenLock, aJumpToTagEditor,
aJumpToPositionInSong, aReverseSelection, aDeselectItems, aSelectAlbum, aAddSelectedItems,
aCropMainPlaylist, aCropPlaylist, aClearMainPlaylist, aClearPlaylist, aSortPlaylist, aReversePlaylist,
aApplyFilter, aDisableFilter, aFind, aFindItemForward, aFindItemBackward, aNextFoundItem,
aPreviousFoundItem, aToggleFindMode, aToggleReplayGainMode, aToggleSpaceMode, aToggleAddMode,
aToggleMouse, aToggleBitrateVisibility, aAddRandomItems, aToggleBrowserSortMode, aToggleLibraryTagType,
aRefetchLyrics, aRefetchArtistInfo, aShowSongInfo, aShowArtistInfo, aShowLyrics, aQuit,
aNextScreen, aPreviousScreen, aShowHelp, aShowPlaylist, aShowBrowser, aShowSearchEngine,
aShowMediaLibrary, aShowPlaylistEditor, aShowTagEditor, aShowOutputs, aShowVisualizer,
aShowClock, aShowServerInfo
};
struct Action
{
enum FindDirection { fdForward, fdBackward };
Action(ActionType type, const char *name) : itsType(type), itsName(name) { }
const char *Name() const { return itsName; }
ActionType Type() const { return itsType; }
bool Execute()
{
if (canBeRun())
{
Run();
return true;
}
return false;
}
static void ValidateScreenSize();
static void SetResizeFlags();
static void ResizeScreen();
static void SetWindowsDimensions();
static bool AskYesNoQuestion(const std::string &question, void (*callback)());
static bool isMPDMusicDirSet();
static Action *Get(ActionType);
static bool OriginalStatusbarVisibility;
static bool DesignChanged;
static bool OrderResize;
static bool ExitMainLoop;
static size_t HeaderHeight;
static size_t FooterHeight;
static size_t FooterStartY;
protected:
virtual bool canBeRun() const { return true; }
virtual void Run() = 0;
static void Seek();
static void FindItem(const FindDirection);
static void ListsChangeFinisher();
private:
ActionType itsType;
const char *itsName;
static void insertAction(Action *a) { Actions[a->Type()] = a; }
static std::map<ActionType, Action *> Actions;
};
struct MouseEvent : public Action
{
MouseEvent() : Action(aMouseEvent, "mouse_event") { }
virtual bool canBeRun() const;
virtual void Run();
private:
MEVENT itsMouseEvent;
MEVENT itsOldMouseEvent;
};
struct ScrollUp : public Action
{
ScrollUp() : Action(aScrollUp, "scroll_up") { }
virtual void Run();
};
struct ScrollDown : public Action
{
ScrollDown() : Action(aScrollDown, "scroll_down") { }
virtual void Run();
};
struct ScrollUpArtist : public Action
{
ScrollUpArtist() : Action(aScrollUpArtist, "scroll_up_artist") { }
virtual void Run();
};
struct ScrollUpAlbum : public Action
{
ScrollUpAlbum() : Action(aScrollUpAlbum, "scroll_up_album") { }
virtual void Run();
};
struct ScrollDownArtist : public Action
{
ScrollDownArtist() : Action(aScrollDownArtist, "scroll_down_artist") { }
virtual void Run();
};
struct ScrollDownAlbum : public Action
{
ScrollDownAlbum() : Action(aScrollDownAlbum, "scroll_down_album") { }
virtual void Run();
};
struct PageUp : public Action
{
PageUp() : Action(aPageUp, "page_up") { }
virtual void Run();
};
struct PageDown : public Action
{
PageDown() : Action(aPageDown, "page_down") { }
virtual void Run();
};
struct MoveHome : public Action
{
MoveHome() : Action(aMoveHome, "move_home") { }
virtual void Run();
};
struct MoveEnd : public Action
{
MoveEnd() : Action(aMoveEnd, "move_end") { }
virtual void Run();
};
struct ToggleInterface : public Action
{
ToggleInterface() : Action(aToggleInterface, "toggle_inferface") { }
virtual void Run();
};
struct JumpToParentDir : public Action
{
JumpToParentDir() : Action(aJumpToParentDir, "jump_to_parent_dir") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct PressEnter : public Action
{
PressEnter() : Action(aPressEnter, "press_enter") { }
virtual void Run();
};
struct PressSpace : public Action
{
PressSpace() : Action(aPressSpace, "press_space") { }
virtual void Run();
};
struct PreviousColumn : public Action
{
PreviousColumn() : Action(aPreviousColumn, "previous_column") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct NextColumn : public Action
{
NextColumn() : Action(aNextColumn, "next_column") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct MasterScreen : public Action
{
MasterScreen() : Action(aMasterScreen, "master_screen") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct SlaveScreen : public Action
{
SlaveScreen() : Action(aSlaveScreen, "slave_screen") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct VolumeUp : public Action
{
VolumeUp() : Action(aVolumeUp, "volume_up") { }
virtual void Run();
};
struct VolumeDown : public Action
{
VolumeDown() : Action(aVolumeDown, "volume_down") { }
virtual void Run();
};
struct Delete : public Action
{
Delete() : Action(aDelete, "delete") { }
virtual void Run();
};
struct ReplaySong : public Action
{
ReplaySong() : Action(aReplaySong, "replay_song") { }
virtual void Run();
};
struct PreviousSong : public Action
{
PreviousSong() : Action(aPreviousSong, "previous") { }
virtual void Run();
};
struct NextSong : public Action
{
NextSong() : Action(aNextSong, "next") { }
virtual void Run();
};
struct Pause : public Action
{
Pause() : Action(aPause, "pause") { }
virtual void Run();
};
struct Stop : public Action
{
Stop() : Action(aStop, "stop") { }
virtual void Run();
};
struct SavePlaylist : public Action
{
SavePlaylist() : Action(aSavePlaylist, "save_playlist") { }
virtual void Run();
};
struct MoveSortOrderUp : public Action
{
MoveSortOrderUp() : Action(aMoveSortOrderUp, "move_sort_order_up") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct MoveSortOrderDown : public Action
{
MoveSortOrderDown() : Action(aMoveSortOrderDown, "move_sort_order_down") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct MoveSelectedItemsUp : public Action
{
MoveSelectedItemsUp() : Action(aMoveSelectedItemsUp, "move_selected_items_up") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct MoveSelectedItemsDown : public Action
{
MoveSelectedItemsDown() : Action(aMoveSelectedItemsDown, "move_selected_items_down") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct MoveSelectedItemsTo : public Action
{
MoveSelectedItemsTo() : Action(aMoveSelectedItemsTo, "move_selected_items_to") { }
virtual void Run();
};
struct Add : public Action
{
Add() : Action(aAdd, "add") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct SeekForward : public Action
{
SeekForward() : Action(aSeekForward, "seek_forward") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct SeekBackward : public Action
{
SeekBackward() : Action(aSeekBackward, "seek_backward") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct ToggleDisplayMode : public Action
{
ToggleDisplayMode() : Action(aToggleDisplayMode, "toggle_display_mode") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct ToggleSeparatorsInPlaylist : public Action
{
ToggleSeparatorsInPlaylist() : Action(aToggleSeparatorsInPlaylist, "toggle_separators_in_playlist") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct ToggleLyricsFetcher : public Action
{
ToggleLyricsFetcher() : Action(aToggleLyricsFetcher, "toggle_lyrics_fetcher") { }
# ifndef HAVE_CURL_CURL_H
virtual bool canBeRun() const;
# endif // NOT HAVE_CURL_CURL_H
virtual void Run();
};
struct ToggleFetchingLyricsInBackground : public Action
{
ToggleFetchingLyricsInBackground() : Action(aToggleFetchingLyricsInBackground, "toggle_fetching_lyrics_in_background") { }
# ifndef HAVE_CURL_CURL_H
virtual bool canBeRun() const;
# endif // NOT HAVE_CURL_CURL_H
virtual void Run();
};
struct ToggleAutoCenter : public Action
{
ToggleAutoCenter() : Action(aToggleAutoCenter, "toggle_autocentering") { }
virtual void Run();
};
struct UpdateDatabase : public Action
{
UpdateDatabase() : Action(aUpdateDatabase, "update_database") { }
virtual void Run();
};
struct JumpToPlayingSong : public Action
{
JumpToPlayingSong() : Action(aJumpToPlayingSong, "jump_to_playing_song") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct ToggleRepeat : public Action
{
ToggleRepeat() : Action(aToggleRepeat, "toggle_repeat") { }
virtual void Run();
};
struct Shuffle : public Action
{
Shuffle() : Action(aShuffle, "shuffle") { }
virtual void Run();
};
struct ToggleRandom : public Action
{
ToggleRandom() : Action(aToggleRandom, "toggle_random") { }
virtual void Run();
};
struct StartSearching : public Action
{
StartSearching() : Action(aStartSearching, "start_searching") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct SaveTagChanges : public Action
{
SaveTagChanges() : Action(aSaveTagChanges, "save_tag_changes") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct ToggleSingle : public Action
{
ToggleSingle() : Action(aToggleSingle, "toggle_single") { }
virtual void Run();
};
struct ToggleConsume : public Action
{
ToggleConsume() : Action(aToggleConsume, "toggle_consume") { }
virtual void Run();
};
struct ToggleCrossfade : public Action
{
ToggleCrossfade() : Action(aToggleCrossfade, "toggle_crossfade") { }
virtual void Run();
};
struct SetCrossfade : public Action
{
SetCrossfade() : Action(aSetCrossfade, "set_crossfade") { }
virtual void Run();
};
struct EditSong : public Action
{
EditSong() : Action(aEditSong, "edit_song") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct EditLibraryTag : public Action
{
EditLibraryTag() : Action(aEditLibraryTag, "edit_library_tag") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct EditLibraryAlbum : public Action
{
EditLibraryAlbum() : Action(aEditLibraryAlbum, "edit_library_album") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct EditDirectoryName : public Action
{
EditDirectoryName() : Action(aEditDirectoryName, "edit_directory_name") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct EditPlaylistName : public Action
{
EditPlaylistName() : Action(aEditPlaylistName, "edit_playlist_name") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct EditLyrics : public Action
{
EditLyrics() : Action(aEditLyrics, "edit_lyrics") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct JumpToBrowser : public Action
{
JumpToBrowser() : Action(aJumpToBrowser, "jump_to_browser") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct JumpToMediaLibrary : public Action
{
JumpToMediaLibrary() : Action(aJumpToMediaLibrary, "jump_to_media_library") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct JumpToPlaylistEditor : public Action
{
JumpToPlaylistEditor() : Action(aJumpToPlaylistEditor, "jump_to_playlist_editor") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct ToggleScreenLock : public Action
{
ToggleScreenLock() : Action(aToggleScreenLock, "toggle_screen_lock") { }
virtual void Run();
};
struct JumpToTagEditor : public Action
{
JumpToTagEditor() : Action(aJumpToTagEditor, "jump_to_tag_editor") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct JumpToPositionInSong : public Action
{
JumpToPositionInSong() : Action(aJumpToPositionInSong, "jump_to_position_in_song") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct ReverseSelection : public Action
{
ReverseSelection() : Action(aReverseSelection, "reverse_selection") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct DeselectItems : public Action
{
DeselectItems() : Action(aDeselectItems, "deselect_items") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct SelectAlbum : public Action
{
SelectAlbum() : Action(aSelectAlbum, "select_album") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct AddSelectedItems : public Action
{
AddSelectedItems() : Action(aAddSelectedItems, "add_selected_items") { }
virtual void Run();
};
struct CropMainPlaylist : public Action
{
CropMainPlaylist() : Action(aCropMainPlaylist, "crop_main_playlist") { }
virtual void Run();
};
struct CropPlaylist : public Action
{
CropPlaylist() : Action(aCropPlaylist, "crop_playlist") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct ClearMainPlaylist : public Action
{
ClearMainPlaylist() : Action(aClearMainPlaylist, "clear_main_playlist") { }
virtual void Run();
};
struct ClearPlaylist : public Action
{
ClearPlaylist() : Action(aClearPlaylist, "clear_playlist") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct SortPlaylist : public Action
{
SortPlaylist() : Action(aSortPlaylist, "sort_playlist") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct ReversePlaylist : public Action
{
ReversePlaylist() : Action(aReversePlaylist, "reverse_playlist") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct ApplyFilter : public Action
{
ApplyFilter() : Action(aApplyFilter, "apply_filter") { }
virtual void Run();
};
struct DisableFilter : public Action
{
DisableFilter() : Action(aDisableFilter, "disable_filter") { }
virtual void Run();
};
struct Find : public Action
{
Find() : Action(aFind, "find") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct FindItemForward : public Action
{
FindItemForward() : Action(aFindItemForward, "find_item_forward") { }
virtual void Run();
};
struct FindItemBackward : public Action
{
FindItemBackward() : Action(aFindItemBackward, "find_item_backward") { }
virtual void Run();
};
struct NextFoundItem : public Action
{
NextFoundItem() : Action(aNextFoundItem, "next_found_item") { }
virtual void Run();
};
struct PreviousFoundItem : public Action
{
PreviousFoundItem() : Action(aPreviousFoundItem, "previous_found_item") { }
virtual void Run();
};
struct ToggleFindMode : public Action
{
ToggleFindMode() : Action(aToggleFindMode, "toggle_find_mode") { }
virtual void Run();
};
struct ToggleReplayGainMode : public Action
{
ToggleReplayGainMode() : Action(aToggleReplayGainMode, "toggle_replay_gain_mode") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct ToggleSpaceMode : public Action
{
ToggleSpaceMode() : Action(aToggleSpaceMode, "toggle_space_mode") { }
virtual void Run();
};
struct ToggleAddMode : public Action
{
ToggleAddMode() : Action(aToggleAddMode, "toggle_add_mode") { }
virtual void Run();
};
struct ToggleMouse : public Action
{
ToggleMouse() : Action(aToggleMouse, "toggle_mouse") { }
virtual void Run();
};
struct ToggleBitrateVisibility : public Action
{
ToggleBitrateVisibility() : Action(aToggleBitrateVisibility, "toggle_bitrate_visibility") { }
virtual void Run();
};
struct AddRandomItems : public Action
{
AddRandomItems() : Action(aAddRandomItems, "add_random_items") { }
virtual void Run();
};
struct ToggleBrowserSortMode : public Action
{
ToggleBrowserSortMode() : Action(aToggleBrowserSortMode, "toggle_browser_sort_mode") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct ToggleLibraryTagType : public Action
{
ToggleLibraryTagType() : Action(aToggleLibraryTagType, "toggle_library_tag_type") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct RefetchLyrics : public Action
{
RefetchLyrics() : Action(aRefetchLyrics, "refetch_lyrics") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct RefetchArtistInfo : public Action
{
RefetchArtistInfo() : Action(aRefetchArtistInfo, "refetch_artist_info") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct ShowSongInfo : public Action
{
ShowSongInfo() : Action(aShowSongInfo, "show_song_info") { }
virtual void Run();
};
struct ShowArtistInfo : public Action
{
ShowArtistInfo() : Action(aShowArtistInfo, "show_artist_info") { }
# ifndef HAVE_CURL_CURL_H
virtual bool canBeRun() const;
# endif // NOT HAVE_CURL_CURL_H
virtual void Run();
};
struct ShowLyrics : public Action
{
ShowLyrics() : Action(aShowLyrics, "show_lyrics") { }
virtual void Run();
};
struct Quit : public Action
{
Quit() : Action(aQuit, "quit") { }
virtual void Run();
};
struct NextScreen : public Action
{
NextScreen() : Action(aNextScreen, "next_screen") { }
virtual void Run();
};
struct PreviousScreen : public Action
{
PreviousScreen() : Action(aPreviousScreen, "previous_screen") { }
virtual void Run();
};
struct ShowHelp : public Action
{
ShowHelp() : Action(aShowHelp, "show_help") { }
# ifdef HAVE_TAGLIB_H
virtual bool canBeRun() const;
# endif // HAVE_TAGLIB_H
virtual void Run();
};
struct ShowPlaylist : public Action
{
ShowPlaylist() : Action(aShowPlaylist, "show_playlist") { }
# ifdef HAVE_TAGLIB_H
virtual bool canBeRun() const;
# endif // HAVE_TAGLIB_H
virtual void Run();
};
struct ShowBrowser : public Action
{
ShowBrowser() : Action(aShowBrowser, "show_browser") { }
# ifdef HAVE_TAGLIB_H
virtual bool canBeRun() const;
# endif // HAVE_TAGLIB_H
virtual void Run();
};
struct ShowSearchEngine : public Action
{
ShowSearchEngine() : Action(aShowSearchEngine, "show_search_engine") { }
# ifdef HAVE_TAGLIB_H
virtual bool canBeRun() const;
# endif // HAVE_TAGLIB_H
virtual void Run();
};
struct ShowMediaLibrary : public Action
{
ShowMediaLibrary() : Action(aShowMediaLibrary, "show_media_library") { }
# ifdef HAVE_TAGLIB_H
virtual bool canBeRun() const;
# endif // HAVE_TAGLIB_H
virtual void Run();
};
struct ShowPlaylistEditor : public Action
{
ShowPlaylistEditor() : Action(aShowPlaylistEditor, "show_playlist_editor") { }
# ifdef HAVE_TAGLIB_H
virtual bool canBeRun() const;
# endif // HAVE_TAGLIB_H
virtual void Run();
};
struct ShowTagEditor : public Action
{
ShowTagEditor() : Action(aShowTagEditor, "show_tag_editor") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct ShowOutputs : public Action
{
ShowOutputs() : Action(aShowOutputs, "show_outputs") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct ShowVisualizer : public Action
{
ShowVisualizer() : Action(aShowVisualizer, "show_visualizer") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct ShowClock : public Action
{
ShowClock() : Action(aShowClock, "show_clock") { }
virtual bool canBeRun() const;
virtual void Run();
};
struct ShowServerInfo : public Action
{
ShowServerInfo() : Action(aShowServerInfo, "show_server_info") { }
# ifdef HAVE_TAGLIB_H
virtual bool canBeRun() const;
# endif // HAVE_TAGLIB_H
virtual void Run();
};
#endif // _ACTIONS_H

View File

@@ -508,12 +508,12 @@ void Browser::ClearDirectory(const std::string &path) const
ClearDirectory(full_path);
if (remove(full_path.c_str()) == 0)
{
static const char msg[] = "Deleting \"%s\"...";
const char msg[] = "Deleting \"%s\"...";
ShowMessage(msg, Shorten(TO_WSTRING(full_path), COLS-static_strlen(msg)).c_str());
}
else
{
static const char msg[] = "Couldn't remove \"%s\": %s";
const char msg[] = "Couldn't remove \"%s\": %s";
ShowMessage(msg, Shorten(TO_WSTRING(full_path), COLS-static_strlen(msg)-25).c_str(), strerror(errno));
}
}

27
src/gcc.h Normal file
View File

@@ -0,0 +1,27 @@
/***************************************************************************
* Copyright (C) 2008-2012 by Andrzej Rybczak *
* electricityispower@gmail.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#if defined(__GNUC__) && __GNUC__ >= 3
# define GNUC_UNUSED __attribute__((unused))
# define GNUC_PRINTF(a, b) __attribute__((format(printf, a, b)))
#else
# define GNUC_UNUSED
# define GNUC_PRINTF(a, b)
#endif

View File

@@ -41,9 +41,6 @@ namespace Global
extern size_t MainStartY;
extern size_t MainHeight;
extern bool BlockItemListUpdate;
extern bool UpdateStatusImmediately;
extern bool MessagesAllowed;
extern bool SeekingInProgress;
extern bool RedrawHeader;

View File

@@ -76,353 +76,361 @@ std::basic_string<my_char_t> Help::Title()
return U("Help");
}
std::string Help::DisplayKeys(int *key, int size)
std::string Help::DisplayKeys2(const ActionType at)
{
bool backspace = 1;
std::string result = "\t";
for (int i = 0; i < size; i++)
bool backspace = true;
std::string result;
for (std::multimap<int, Action *>::const_iterator it = Key.Bindings.begin(); it != Key.Bindings.end(); ++it)
{
if (key[i] == NcmpcppKeys::NullKey);
else if (key[i] == 259)
result += "Up";
else if (key[i] == 258)
result += "Down";
else if (key[i] == 339)
result += "Page Up";
else if (key[i] == 338)
result += "Page Down";
else if (key[i] == 262)
result += "Home";
else if (key[i] == 360)
result += "End";
else if (key[i] == 32)
result += "Space";
else if (key[i] == 10)
result += "Enter";
else if (key[i] == 330)
result += "Delete";
else if (key[i] == 261)
result += "Right";
else if (key[i] == 260)
result += "Left";
else if (key[i] == 9)
result += "Tab";
else if (key[i] == 353)
result += "Shift-Tab";
else if (key[i] >= 1 && key[i] <= 26)
if (it->second->Type() == at)
{
result += "Ctrl-";
result += key[i]+64;
int key = it->first;
if (key == 259)
result += "Up";
else if (key == 258)
result += "Down";
else if (key == 339)
result += "PageUp";
else if (key == 338)
result += "PageDown";
else if (key == 262)
result += "Home";
else if (key == 360)
result += "End";
else if (key == 32)
result += "Space";
else if (key == 10)
result += "Enter";
else if (key == 330)
result += "Delete";
else if (key == 261)
result += "Right";
else if (key == 260)
result += "Left";
else if (key == 9)
result += "Tab";
else if (key == 353)
result += "Shift-Tab";
else if (key >= 1 && key <= 26)
{
result += "Ctrl-";
result += key+64;
}
else if (key >= 265 && key <= 276)
{
result += "F";
result += IntoStr(key-264);
}
else if ((key == 263 || key == 127) && !backspace);
else if ((key == 263 || key == 127) && backspace)
{
result += "Backspace";
backspace = false;
}
else if (isprint(key))
result += key;
result += " ";
}
else if (key[i] >= 265 && key[i] <= 276)
{
result += "F";
result += IntoStr(key[i]-264);
}
else if ((key[i] == 263 || key[i] == 127) && !backspace);
else if ((key[i] == 263 || key[i] == 127) && backspace)
{
result += "Backspace";
backspace = 0;
}
else
result += key[i];
result += " ";
}
if (result.length() > 12)
result = result.substr(0, 12);
for (size_t i = result.length(); i <= 12; result += " ", ++i) { }
result += ": ";
result.resize(12, ' ');
return result;
}
void Help::Section(const char *type, const char *title)
{
*w << "\n " << fmtBold << type << " - " << title << fmtBoldEnd << "\n\n";
}
void Help::KeyDesc(const ActionType at, const char *desc)
{
*w << " " << DisplayKeys2(at) << " : " << desc << "\n";
}
void Help::MouseDesc(std::string action, const char *desc, bool indent)
{
action.resize(31 - (indent ? 2 : 0), ' ');
*w << " " << (indent ? " " : "") << action << ": " << desc << "\n";
}
void Help::MouseColumn(const char *column)
{
*w << fmtBold << " " << column << " column:\n" << fmtBoldEnd;
}
void Help::GetKeybindings()
{
*w << " " << fmtBold << "Keys - Movement\n -----------------------------------------\n" << fmtBoldEnd;
*w << DisplayKeys(Key.Up) << "Move Cursor up\n";
*w << DisplayKeys(Key.Down) << "Move Cursor down\n";
*w << DisplayKeys(Key.UpAlbum) << "Move Cursor up one album\n";
*w << DisplayKeys(Key.DownAlbum) << "Move Cursor down one album\n";
*w << DisplayKeys(Key.UpArtist) << "Move Cursor up one artist\n";
*w << DisplayKeys(Key.DownArtist) << "Move Cursor down one artist\n";
*w << DisplayKeys(Key.PageUp) << "Page up\n";
*w << DisplayKeys(Key.PageDown) << "Page down\n";
*w << DisplayKeys(Key.Home) << "Home\n";
*w << DisplayKeys(Key.End) << "End\n";
KeysSection("Movement");
KeyDesc(aScrollUp, "Move cursor up");
KeyDesc(aScrollDown, "Move cursor down");
KeyDesc(aScrollUpAlbum, "Move cursor up one album");
KeyDesc(aScrollDownAlbum, "Move cursor down one album");
KeyDesc(aScrollUpArtist, "Move cursor up one artist");
KeyDesc(aScrollDownArtist, "Move cursor down one artist");
KeyDesc(aPageUp, "Page up");
KeyDesc(aPageDown, "Page down");
KeyDesc(aMoveHome, "Home");
KeyDesc(aMoveEnd, "End");
*w << "\n";
if (Config.screen_switcher_previous)
*w << DisplayKeys(Key.ScreenSwitcher) << "Switch between current and last screen\n";
{
KeyDesc(aNextScreen, "Switch between current and last screen");
KeyDesc(aPreviousScreen, "Switch between current and last screen");
}
else
{
*w << DisplayKeys(Key.ScreenSwitcher) << "Switch to next screen in sequence\n";
*w << DisplayKeys(Key.BackwardScreenSwitcher) << "Switch to previous screen in sequence\n";
KeyDesc(aNextScreen, "Switch to next screen in sequence");
KeyDesc(aPreviousScreen, "Switch to previous screen in sequence");
}
*w << DisplayKeys(Key.Help) << "Help screen\n";
*w << DisplayKeys(Key.Playlist) << "Playlist screen\n";
*w << DisplayKeys(Key.Browser) << "Browse screen\n";
*w << DisplayKeys(Key.SearchEngine) << "Search engine\n";
*w << DisplayKeys(Key.MediaLibrary) << "Media library\n";
*w << DisplayKeys(Key.PlaylistEditor) << "Playlist editor\n";
KeyDesc(aShowHelp, "Show help");
KeyDesc(aShowPlaylist, "Show playlist");
KeyDesc(aShowBrowser, "Show browser");
KeyDesc(aShowSearchEngine, "Show search engine");
KeyDesc(aShowMediaLibrary, "Show media library");
KeyDesc(aShowPlaylistEditor, "Show playlist editor");
# ifdef HAVE_TAGLIB_H
*w << DisplayKeys(Key.TagEditor) << "Tag editor\n";
KeyDesc(aShowTagEditor, "Show tag editor");
# endif // HAVE_TAGLIB_H
# ifdef ENABLE_OUTPUTS
*w << DisplayKeys(Key.Outputs) << "Outputs\n";
KeyDesc(aShowOutputs, "Show outputs");
# endif // ENABLE_OUTPUTS
# ifdef ENABLE_VISUALIZER
*w << DisplayKeys(Key.Visualizer) << "Music visualizer\n";
KeyDesc(aShowVisualizer, "Show music visualizer");
# endif // ENABLE_VISUALIZER
# ifdef ENABLE_CLOCK
*w << DisplayKeys(Key.Clock) << "Clock screen\n";
KeyDesc(aShowClock, "Show clock");
# endif // ENABLE_CLOCK
*w << "\n";
*w << DisplayKeys(Key.ServerInfo) << "MPD server info\n";
KeyDesc(aShowServerInfo, "Show server info");
*w << "\n\n " << fmtBold << "Keys - Global\n -----------------------------------------\n" << fmtBoldEnd;
*w << DisplayKeys(Key.Stop) << "Stop\n";
*w << DisplayKeys(Key.Pause) << "Pause\n";
*w << DisplayKeys(Key.Next) << "Next track\n";
*w << DisplayKeys(Key.Prev) << "Previous track\n";
*w << DisplayKeys(Key.Replay) << "Play current track from the beginning\n";
*w << DisplayKeys(Key.SeekForward) << "Seek forward\n";
*w << DisplayKeys(Key.SeekBackward) << "Seek backward\n";
*w << DisplayKeys(Key.VolumeDown) << "Decrease volume\n";
*w << DisplayKeys(Key.VolumeUp) << "Increase volume\n";
KeysSection("Global");
KeyDesc(aStop, "Stop");
KeyDesc(aPause, "Pause");
KeyDesc(aNextSong, "Next track");
KeyDesc(aPreviousSong, "Previous track");
KeyDesc(aReplaySong, "Replay playing song");
KeyDesc(aSeekForward, "Seek forward in playing song");
KeyDesc(aSeekBackward, "Seek backward in playing song");
KeyDesc(aVolumeDown, "Decrease volume by 2%");
KeyDesc(aVolumeUp, "Increase volume by 2%");
*w << "\n";
*w << DisplayKeys(Key.ToggleSpaceMode) << "Toggle space mode (select/add)\n";
*w << DisplayKeys(Key.ToggleAddMode) << "Toggle add mode\n";
*w << DisplayKeys(Key.ToggleMouse) << "Toggle mouse support\n";
*w << DisplayKeys(Key.ReverseSelection) << "Reverse selection\n";
*w << DisplayKeys(Key.DeselectAll) << "Deselect all items\n";
*w << DisplayKeys(Key.SelectAlbum) << "Select songs of album around cursor\n";
*w << DisplayKeys(Key.AddSelected) << "Add selected items to playlist/m3u file\n";
KeyDesc(aToggleSpaceMode, "Toggle space mode (select/add)");
KeyDesc(aToggleAddMode, "Toggle add mode (add or remove/always add)");
KeyDesc(aToggleMouse, "Toggle mouse support");
KeyDesc(aReverseSelection, "Reverse selection");
KeyDesc(aDeselectItems, "Deselect items");
KeyDesc(aSelectAlbum, "Select songs of album around the cursor");
KeyDesc(aAddSelectedItems, "Add selected items to playlist");
*w << "\n";
*w << DisplayKeys(Key.ToggleRepeat) << "Toggle repeat mode\n";
*w << DisplayKeys(Key.ToggleRandom) << "Toggle random mode\n";
*w << DisplayKeys(Key.ToggleSingle) << "Toggle single mode\n";
*w << DisplayKeys(Key.ToggleConsume) << "Toggle consume mode\n";
KeyDesc(aToggleRepeat, "Toggle repeat mode");
KeyDesc(aToggleRandom, "Toggle random mode");
KeyDesc(aToggleSingle, "Toggle single mode");
KeyDesc(aToggleConsume, "Toggle consume mode");
if (Mpd.Version() >= 16)
*w << DisplayKeys(Key.ToggleReplayGainMode) << "Toggle replay gain mode\n";
*w << DisplayKeys(Key.ToggleBitrateVisibility) << "Toggle bitrate visibility\n";
*w << DisplayKeys(Key.Shuffle) << "Shuffle playlist\n";
*w << DisplayKeys(Key.ToggleCrossfade) << "Toggle crossfade mode\n";
*w << DisplayKeys(Key.SetCrossfade) << "Set crossfade\n";
*w << DisplayKeys(Key.UpdateDB) << "Start a music database update\n";
KeyDesc(aToggleReplayGainMode, "Toggle replay gain mode");
KeyDesc(aToggleBitrateVisibility, "Toggle bitrate visibility");
KeyDesc(aShuffle, "Shuffle playlist");
KeyDesc(aToggleCrossfade, "Toggle crossfade mode");
KeyDesc(aSetCrossfade, "Set crossfade");
KeyDesc(aUpdateDatabase, "Start music database update");
*w << "\n";
*w << DisplayKeys(Key.ApplyFilter) << "Apply filter\n";
*w << DisplayKeys(Key.DisableFilter) << "Disable filter\n";
*w << DisplayKeys(Key.FindForward) << "Forward find\n";
*w << DisplayKeys(Key.FindBackward) << "Backward find\n";
*w << DisplayKeys(Key.PrevFoundPosition) << "Go to previous found position\n";
*w << DisplayKeys(Key.NextFoundPosition) << "Go to next found position\n";
*w << DisplayKeys(Key.ToggleFindMode) << "Toggle find mode (normal/wrapped)\n";
*w << DisplayKeys(Key.GoToContainingDir) << "Locate song in browser\n";
*w << DisplayKeys(Key.GoToMediaLibrary) << "Locate current song in media library\n";
*w << DisplayKeys(Key.ToggleScreenLock) << "Lock/unlock current screen\n";
KeyDesc(aApplyFilter, "Apply filter");
KeyDesc(aDisableFilter, "Disable filter");
KeyDesc(aFindItemForward, "Find item forward");
KeyDesc(aFindItemBackward, "Find item backward");
KeyDesc(aPreviousFoundItem, "Go to previous found item");
KeyDesc(aNextFoundItem, "Go to next found item");
KeyDesc(aToggleFindMode, "Toggle find mode (normal/wrapped)");
KeyDesc(aJumpToBrowser, "Locate song in browser");
KeyDesc(aJumpToMediaLibrary, "Locate song in media library");
KeyDesc(aToggleScreenLock, "Lock/unlock current screen");
KeyDesc(aMasterScreen, "Switch to master screen (left one)");
KeyDesc(aSlaveScreen, "Switch to slave screen (right one)");
# ifdef HAVE_TAGLIB_H
*w << DisplayKeys(Key.GoToTagEditor) << "Locate current song in tag editor\n";
KeyDesc(aJumpToTagEditor, "Locate song in tag editor");
# endif // HAVE_TAGLIB_H
*w << DisplayKeys(Key.ToggleDisplayMode) << "Toggle display mode\n";
*w << DisplayKeys(Key.ToggleInterface) << "Toggle user interface\n";
*w << DisplayKeys(Key.ToggleSeparatorsInPlaylist) << "Toggle displaying separators between albums\n";
*w << DisplayKeys(Key.GoToPosition) << "Go to given position in current song (in % by default)\n";
*w << DisplayKeys(Key.SongInfo) << "Show song info\n";
KeyDesc(aToggleDisplayMode, "Toggle display mode");
KeyDesc(aToggleInterface, "Toggle user interface");
KeyDesc(aToggleSeparatorsInPlaylist, "Toggle displaying separators between albums");
KeyDesc(aJumpToPositionInSong, "Jump to given position in playing song (formats: mm:ss, x%)");
KeyDesc(aShowSongInfo, "Show song info");
# ifdef HAVE_CURL_CURL_H
*w << DisplayKeys(Key.ArtistInfo) << "Show artist info\n";
*w << DisplayKeys(Key.ToggleLyricsDB) << "Toggle lyrics database\n";
*w << DisplayKeys(Key.ToggleFetchingLyricsInBackground) << "Toggle fetching lyrics for current song in background\n";
KeyDesc(aShowArtistInfo, "Show artist info");
KeyDesc(aToggleLyricsFetcher, "Toggle lyrics fetcher");
KeyDesc(aToggleFetchingLyricsInBackground, "Toggle fetching lyrics for playing songs in background");
# endif // HAVE_CURL_CURL_H
*w << DisplayKeys(Key.Lyrics) << "Show/hide song's lyrics\n";
KeyDesc(aShowLyrics, "Show/hide song lyrics");
*w << "\n";
*w << DisplayKeys(Key.Quit) << "Quit\n";
KeyDesc(aQuit, "Quit");
*w << "\n\n " << fmtBold << "Keys - Playlist\n -----------------------------------------\n" << fmtBoldEnd;
*w << DisplayKeys(Key.Enter) << "Play\n";
*w << DisplayKeys(Key.SwitchTagTypeList) << "Add random songs/artists/albums to playlist\n";
*w << DisplayKeys(Key.Delete) << "Delete item/selected items from playlist\n";
*w << DisplayKeys(Key.Clear) << "Clear playlist\n";
*w << DisplayKeys(Key.Crop) << "Clear playlist but hold currently playing/selected items\n";
*w << DisplayKeys(Key.MvSongUp) << "Move item(s) up\n";
*w << DisplayKeys(Key.MvSongDown) << "Move item(s) down\n";
*w << DisplayKeys(Key.MoveTo) << "Move selected item(s) to cursor position\n";
*w << DisplayKeys(Key.MoveBefore) << "Move selected item(s) before cursor position\n";
*w << DisplayKeys(Key.MoveAfter) << "Move selected item(s) after cursor position\n";
*w << DisplayKeys(Key.Add) << "Add url/file/directory to playlist\n";
KeysSection("Playlist");
KeyDesc(aPressEnter, "Play selected item");
KeyDesc(aAddRandomItems, "Add random items to playlist");
KeyDesc(aDelete, "Delete selected item(s) from playlist");
KeyDesc(aClearMainPlaylist, "Clear playlist");
KeyDesc(aCropMainPlaylist, "Clear playlist except playing/selected items");
KeyDesc(aMoveSelectedItemsUp, "Move selected item(s) up");
KeyDesc(aMoveSelectedItemsDown, "Move selected item(s) down");
KeyDesc(aMoveSelectedItemsTo, "Move selected item(s) to cursor position");
KeyDesc(aAdd, "Add item to playlist");
# ifdef HAVE_TAGLIB_H
*w << DisplayKeys(Key.EditTags) << "Edit song's tags\n";
KeyDesc(aEditSong, "Edit song");
# endif // HAVE_TAGLIB_H
*w << DisplayKeys(Key.SavePlaylist) << "Save playlist\n";
*w << DisplayKeys(Key.SortPlaylist) << "Sort/reverse playlist\n";
*w << DisplayKeys(Key.GoToNowPlaying) << "Go to currently playing position\n";
*w << DisplayKeys(Key.ToggleAutoCenter) << "Toggle auto center mode\n";
KeyDesc(aSavePlaylist, "Save playlist");
KeyDesc(aSortPlaylist, "Sort playlist");
KeyDesc(aReversePlaylist, "Reverse playlist");
KeyDesc(aJumpToPlayingSong, "Jump to playing song");
KeyDesc(aToggleAutoCenter, "Toggle auto center mode");
*w << "\n\n " << fmtBold << "Keys - Browser\n -----------------------------------------\n" << fmtBoldEnd;
*w << DisplayKeys(Key.Enter) << "Enter directory/Add item to playlist and play\n";
*w << DisplayKeys(Key.Space) << "Add item to playlist\n";
KeysSection("Browser");
KeyDesc(aPressEnter, "Enter directory/Add item to playlist and play it");
KeyDesc(aPressSpace, "Add item to playlist/select it");
# ifdef HAVE_TAGLIB_H
*w << DisplayKeys(Key.EditTags) << "Edit song's tags/Rename playlist/directory\n";
# else
*w << DisplayKeys(Key.EditTags) << "Rename playlist/directory\n";
KeyDesc(aEditSong, "Edit song");
# endif // HAVE_TAGLIB_H
KeyDesc(aEditDirectoryName, "Edit directory name");
KeyDesc(aEditPlaylistName, "Edit playlist name");
if (Mpd.GetHostname()[0] == '/') // are we connected to unix socket?
*w << DisplayKeys(Key.Browser) << "Browse MPD database/local filesystem\n";
*w << DisplayKeys(Key.SwitchTagTypeList) << "Toggle sort order\n";
*w << DisplayKeys(Key.GoToNowPlaying) << "Locate currently playing song\n";
*w << DisplayKeys(Key.GoToParentDir) << "Go to parent directory\n";
*w << DisplayKeys(Key.Delete) << "Delete playlist/file/directory\n";
*w << DisplayKeys(Key.GoToContainingDir) << "Jump to playlist editor (playlists only)\n";
KeyDesc(aShowBrowser, "Browse MPD database/local filesystem");
KeyDesc(aToggleBrowserSortMode, "Toggle sort mode");
KeyDesc(aJumpToPlayingSong, "Locate playing song");
KeyDesc(aJumpToParentDir, "Go to parent directory");
KeyDesc(aDelete, "Delete item");
KeyDesc(aJumpToPlaylistEditor, "Jump to playlist editor (playlists only)");
*w << "\n\n " << fmtBold << "Keys - Search engine\n -----------------------------------------\n" << fmtBoldEnd;
*w << DisplayKeys(Key.Enter) << "Add item to playlist and play/change option\n";
*w << DisplayKeys(Key.Space) << "Add item to playlist\n";
KeysSection("Search engine");
KeyDesc(aPressEnter, "Add item to playlist and play it/change option");
KeyDesc(aPressSpace, "Add item to playlist");
# ifdef HAVE_TAGLIB_H
*w << DisplayKeys(Key.EditTags) << "Edit song's tags\n";
KeyDesc(aEditSong, "Edit song");
# endif // HAVE_TAGLIB_H
*w << DisplayKeys(Key.ToggleSingle) << "Start searching immediately\n";
*w << DisplayKeys(Key.SearchEngine) << "Reset search engine\n";
KeyDesc(aStartSearching, "Start searching");
KeyDesc(aShowSearchEngine, "Reset search constraints and clear results");
*w << "\n\n " << fmtBold << "Keys - Media library\n -----------------------------------------\n" << fmtBoldEnd;
KeysSection("Media library");
if (!Config.media_library_disable_two_column_mode)
*w << DisplayKeys(Key.MediaLibrary) << "Switch between two/three columns\n";
*w << DisplayKeys(Key.PrevColumn) << "Previous column\n";
*w << DisplayKeys(Key.NextColumn) << "Next column\n";
*w << DisplayKeys(Key.Enter) << "Add to playlist and play song/album/artist's songs\n";
*w << DisplayKeys(Key.Space) << "Add to playlist song/album/artist's songs\n";
KeyDesc(aShowMediaLibrary, "Switch between two/three columns mode");
KeyDesc(aPreviousColumn, "Previous column");
KeyDesc(aNextColumn, "Next column");
KeyDesc(aPressEnter, "Add item to playlist and play it");
KeyDesc(aPressSpace, "Add item to playlist");
# ifdef HAVE_TAGLIB_H
*w << DisplayKeys(Key.EditTags) << "Edit main tag/album/song's tags\n";
KeyDesc(aEditSong, "Edit song");
# endif // HAVE_TAGLIB_H
*w << DisplayKeys(Key.SwitchTagTypeList) << "Tag type list switcher (left column)\n";
KeyDesc(aEditLibraryTag, "Edit tag (left column)/album (middle/right column)");
KeyDesc(aToggleLibraryTagType, "Toggle type of tag used in left column");
*w << "\n\n " << fmtBold << "Keys - Playlist editor\n -----------------------------------------\n" << fmtBoldEnd;
*w << DisplayKeys(Key.PrevColumn) << "Previous column\n";
*w << DisplayKeys(Key.NextColumn) << "Next column\n";
*w << DisplayKeys(Key.Enter) << "Add item to playlist and play\n";
*w << DisplayKeys(Key.Space) << "Add to playlist/select item\n";
KeysSection("Playlist editor");
KeyDesc(aPreviousColumn, "Previous column");
KeyDesc(aNextColumn, "Next column");
KeyDesc(aPressEnter, "Add item to playlist and play it");
KeyDesc(aPressSpace, "Add item to playlist/select it");
# ifdef HAVE_TAGLIB_H
*w << DisplayKeys(Key.EditTags) << "Edit playlist's name/song's tags\n";
# else
*w << DisplayKeys(Key.EditTags) << "Edit playlist's name\n";
KeyDesc(aEditSong, "Edit song");
# endif // HAVE_TAGLIB_H
*w << DisplayKeys(Key.MvSongUp) << "Move item(s) up\n";
*w << DisplayKeys(Key.MvSongDown) << "Move item(s) down\n";
*w << DisplayKeys(Key.Clear) << "Clear current playlist\n";
KeyDesc(aEditPlaylistName, "Edit playlist name");
KeyDesc(aMoveSelectedItemsUp, "Move selected item(s) up");
KeyDesc(aMoveSelectedItemsDown, "Move selected item(s) down");
KeyDesc(aClearPlaylist, "Clear playlist");
KeyDesc(aCropPlaylist, "Clear playlist except selected items");
KeysSection("Lyrics");
KeyDesc(aPressSpace, "Toggle reloading lyrics upon song change");
KeyDesc(aEditLyrics, "Open lyrics in external editor");
KeyDesc(aRefetchLyrics, "Refetch lyrics");
*w << "\n\n " << fmtBold << "Keys - Lyrics\n -----------------------------------------\n" << fmtBoldEnd;
*w << DisplayKeys(Key.Space) << "Switch for following lyrics of now playing song\n";
*w << DisplayKeys(Key.EditTags) << "Open lyrics in external editor\n";
*w << DisplayKeys(Key.SwitchTagTypeList) << "Refetch lyrics\n";
*w << "\n\n " << fmtBold << "Keys - Artist info\n -----------------------------------------\n" << fmtBoldEnd;
*w << DisplayKeys(Key.SwitchTagTypeList) << "Refetch artist info\n";
KeysSection("Artist info");
KeyDesc(aRefetchArtistInfo, "Refetch artist info");
# ifdef HAVE_TAGLIB_H
*w << "\n\n " << fmtBold << "Keys - Tiny tag editor\n -----------------------------------------\n" << fmtBoldEnd;
*w << DisplayKeys(Key.Enter) << "Edit tag\n";
*w << DisplayKeys(Key.ToggleSingle) << "Save\n";
KeysSection("Tiny tag editor");
KeyDesc(aPressEnter, "Edit tag");
KeyDesc(aSaveTagChanges, "Save");
*w << "\n\n " << fmtBold << "Keys - Tag editor\n -----------------------------------------\n" << fmtBoldEnd;
*w << DisplayKeys(Key.Enter) << "Change tag/filename for one song (left column)\n";
*w << DisplayKeys(Key.Enter) << "Perform operation on all/selected songs (middle column)\n";
*w << DisplayKeys(Key.Space) << "Switch to albums/directories view (left column)\n";
*w << DisplayKeys(Key.Space) << "Select/deselect song (right column)\n";
*w << DisplayKeys(Key.PrevColumn) << "Previous column\n";
*w << DisplayKeys(Key.NextColumn) << "Next column\n";
*w << DisplayKeys(Key.GoToParentDir) << "Go to parent directory (left column, directories view)\n";
KeysSection("Tag editor");
KeyDesc(aPressEnter, "Edit tag/filename of selected item (left column)");
KeyDesc(aPressEnter, "Perform operation on all/selected items (middle column)");
KeyDesc(aPressSpace, "Switch to albums/directories view (left column)");
KeyDesc(aPressSpace, "Select item (right column)");
KeyDesc(aPreviousColumn, "Previous column");
KeyDesc(aNextColumn, "Next column");
KeyDesc(aJumpToParentDir, "Go to parent directory (left column, directories view)");
# endif // HAVE_TAGLIB_H
# ifdef ENABLE_OUTPUTS
*w << "\n\n " << fmtBold << "Keys - Outputs\n -----------------------------------------\n" << fmtBoldEnd;
*w << DisplayKeys(Key.Enter) << "Enable/disable output\n";
KeysSection("Outputs");
KeyDesc(aPressEnter, "Toggle output");
# endif // ENABLE_OUTPUTS
# if defined(ENABLE_VISUALIZER) && defined(HAVE_FFTW3_H)
*w << "\n\n " << fmtBold << "Keys - Music visualizer\n -----------------------------------------\n" << fmtBoldEnd;
*w << DisplayKeys(Key.Space) << "Toggle visualization type\n";
KeysSection("Music visualizer");
KeyDesc(aPressSpace, "Toggle visualization type");
# endif // ENABLE_VISUALIZER && HAVE_FFTW3_H
*w << "\n\n " << fmtBold << "Mouse - Global\n -----------------------------------------\n" << fmtBoldEnd;
*w << "\tLeft click on \"Playing/Paused\" " << ": Play/pause\n";
*w << "\tLeft click on progressbar " << ": Go to chosen position in played track\n";
MouseSection("Global");
MouseDesc("Left click on \"Playing/Paused\"", "Play/pause");
MouseDesc("Left click on progressbar", "Jump to pointed position in playing song");
*w << "\n";
*w << "\tMouse wheel on \"Volume: xx\" " << ": Change volume\n";
*w << "\tMouse wheel on main window " << ": Scroll\n";
MouseDesc("Mouse wheel on \"Volume: xx\"", "Play/pause");
MouseDesc("Mouse wheel on main window", "Scroll");
MouseSection("Playlist");
MouseDesc("Left click", "Select pointed item");
MouseDesc("Right click", "Play");
*w << "\n\n " << fmtBold << "Mouse - Playlist\n -----------------------------------------\n" << fmtBoldEnd;
*w << "\tLeft click " << ": Highlight\n";
*w << "\tRight click " << ": Play\n";
*w << "\n\n " << fmtBold << "Mouse - Browser\n -----------------------------------------\n" << fmtBoldEnd;
*w << "\tLeft click on directory " << ": Enter directory\n";
*w << "\tRight click on directory " << ": Add to playlist\n";
MouseSection("Browser");
MouseDesc("Left click on directory", "Enter pointed directory");
MouseDesc("Right click on directory", "Add pointed directory to playlist");
*w << "\n";
*w << "\tLeft click on song/playlist " << ": Add to playlist\n";
*w << "\tRight click on song/playlist " << ": Add to playlist and play\n";
MouseDesc("Left click on song/playlist", "Add pointed item to playlist");
MouseDesc("Right click on song/playlist", "Add pointed item to playlist and play it");
MouseSection("Search engine");
MouseDesc("Left click", "Highlight/switch value");
MouseDesc("Right click", "Change value");
*w << "\n\n " << fmtBold << "Mouse - Search engine\n -----------------------------------------\n" << fmtBoldEnd;
*w << "\tLeft click " << ": Highlight/switch value\n";
*w << "\tRight click " << ": Change value\n";
*w << "\n\n " << fmtBold << "Mouse - Media library\n -----------------------------------------\n" << fmtBoldEnd;
*w << fmtBold << "\tLeft/middle column:\n" << fmtBoldEnd;
*w << "\t\tLeft Click " << ": Highlight\n";
*w << "\t\tRight Click " << ": Add to playlist\n";
MouseSection("Media library");
MouseColumn("Left/middle");
MouseDesc("Left click", "Select pointed item", true);
MouseDesc("Right click", "Add item to playlist", true);
*w << "\n";
*w << fmtBold << "\tRight column:\n" << fmtBoldEnd;
*w << "\t\tLeft Click " << ": Add to playlist\n";
*w << "\t\tRight Click " << ": Add to playlist and play\n";
MouseColumn("Right");
MouseDesc("Left Click", "Add pointed item to playlist", true);
MouseDesc("Right Click", "Add pointed item to playlist and play it", true);
*w << "\n\n " << fmtBold << "Mouse - Playlist editor\n -----------------------------------------\n" << fmtBoldEnd;
*w << fmtBold << "\tLeft column:\n" << fmtBoldEnd;
*w << "\t\tLeft Click " << ": Highlight\n";
*w << "\t\tRight Click " << ": Add to playlist\n";
MouseSection("Playlist editor");
MouseColumn("Left");
MouseDesc("Left click", "Select pointed item", true);
MouseDesc("Right click", "Add item to playlist", true);
*w << "\n";
*w << fmtBold << "\tRight column:\n" << fmtBoldEnd;
*w << "\t\tLeft Click " << ": Add to playlist\n";
*w << "\t\tRight Click " << ": Add to playlist and play\n";
MouseColumn("Right");
MouseDesc("Left click", "Add pointed item to playlist", true);
MouseDesc("Right click", "Add pointed item to playlist and play it", true);
# ifdef HAVE_TAGLIB_H
*w << "\n\n " << fmtBold << "Mouse - Tiny tag editor\n -----------------------------------------\n" << fmtBoldEnd;
*w << "\tLeft click " << ": Highlight\n";
*w << "\tRight click " << ": Change value/execute command\n";
MouseSection("Tiny tag editor");
MouseDesc("Left click", "Select option");
MouseDesc("Right click", "Set value/execute");
*w << "\n\n " << fmtBold << "Mouse - Tag editor\n -----------------------------------------\n" << fmtBoldEnd;
*w << fmtBold << "\tLeft column:\n" << fmtBoldEnd;
*w << "\t\tLeft Click " << ": Enter directory/highlight album\n";
*w << "\t\tRight Click " << ": Switch to directories/albums view\n";
MouseSection("Tag editor");
MouseColumn("Left");
MouseDesc("Left click", "Enter pointed directory/select pointed album", true);
MouseDesc("Right click", "Toggle view (directories/albums)", true);
*w << "\n";
*w << fmtBold << "\tMiddle column:\n" << fmtBoldEnd;
*w << "\t\tLeft Click " << ": Highlight\n";
*w << "\t\tRight Click " << ": Change value/execute command\n";
MouseColumn("Middle");
MouseDesc("Left click", "Select option", true);
MouseDesc("Right click", "Set value/execute", true);
*w << "\n";
*w << fmtBold << "\tRight column:\n" << fmtBoldEnd;
*w << "\t\tLeft Click " << ": Highlight\n";
*w << "\t\tRight Click " << ": Change value\n";
MouseColumn("Right");
MouseDesc("Left click", "Select pointed item", true);
MouseDesc("Right click", "Set value", true);
# endif // HAVE_TAGLIB_H
# ifdef ENABLE_OUTPUTS
*w << "\n\n " << fmtBold << "Mouse - Outputs\n -----------------------------------------\n" << fmtBoldEnd;
*w << "\tLeft click " << ": Highlight\n";
*w << "\tRight click " << ": Enable/disable output\n";
MouseSection("Outputs");
MouseDesc("Left click", "Select pointed output");
MouseDesc("Right click", "Toggle output");
# endif // ENABLE_OUTPUTS
}

View File

@@ -47,7 +47,14 @@ class Help : public Screen<Scrollpad>
virtual bool isLockable() { return true; }
private:
std::string DisplayKeys(int *, int = 2);
void KeysSection(const char *title) { Section("Keys", title); }
void MouseSection(const char *title) { Section("Mouse", title); }
void Section(const char *type, const char *title);
void KeyDesc(const ActionType at, const char *desc);
void MouseDesc(std::string action, const char *desc, bool indent = false);
void MouseColumn(const char *column);
std::string DisplayKeys2(const ActionType at);
void GetKeybindings();
};

View File

@@ -478,29 +478,3 @@ std::basic_string<my_char_t> Scroller(const std::basic_string<my_char_t> &str, s
result = s;
return result;
}
bool SwitchToNextColumn(BasicScreen *screen)
{
if (screen == myLibrary)
return myLibrary->NextColumn();
else if (screen == myPlaylistEditor)
return myPlaylistEditor->NextColumn();
# ifdef HAVE_TAGLIB_H
else if (screen == myTagEditor)
return myTagEditor->NextColumn();
# endif // HAVE_TAGLIB_H
return false;
}
bool SwitchToPrevColumn(BasicScreen *screen)
{
if (screen == myLibrary)
return myLibrary->PrevColumn();
else if (screen == myPlaylistEditor)
return myPlaylistEditor->PrevColumn();
# ifdef HAVE_TAGLIB_H
else if (screen == myTagEditor)
return myTagEditor->PrevColumn();
# endif // HAVE_TAGLIB_H
return false;
}

View File

@@ -219,8 +219,7 @@ std::string GetLineValue(std::string &, char = '"', char = '"', bool = 0);
std::basic_string<my_char_t> Scroller(const std::basic_string<my_char_t> &str, size_t &pos, size_t width);
bool SwitchToNextColumn(BasicScreen *);
bool SwitchToPrevColumn(BasicScreen *);
bool askYesNoQuestion(const Buffer &question, void (*callback)());
#endif

View File

@@ -210,7 +210,7 @@ void Lastfm::Refetch()
{
if (remove(itsFilename.c_str()) && errno != ENOENT)
{
static const char msg[] = "Couldn't remove \"%s\": %s";
const char msg[] = "Couldn't remove \"%s\": %s";
ShowMessage(msg, Shorten(TO_WSTRING(itsFilename), COLS-static_strlen(msg)-25).c_str(), strerror(errno));
return;
}

View File

@@ -398,20 +398,18 @@ void Lyrics::Save(const std::string &filename, const std::string &lyrics)
output.close();
}
}
#endif // HAVE_CURL_CURL_H
void Lyrics::Refetch()
{
if (remove(itsFilename.c_str()) && errno != ENOENT)
{
static const char msg[] = "Couldn't remove \"%s\": %s";
const char msg[] = "Couldn't remove \"%s\": %s";
ShowMessage(msg, Shorten(TO_WSTRING(itsFilename), COLS-static_strlen(msg)-25).c_str(), strerror(errno));
return;
}
Load();
}
#ifdef HAVE_CURL_CURL_H
void Lyrics::ToggleFetcher()
{
if (itsFetcher && *itsFetcher)

View File

@@ -55,9 +55,10 @@ class Lyrics : public Screen<Scrollpad>
virtual bool isMergable() { return true; }
void Edit();
void Refetch();
# ifdef HAVE_CURL_CURL_H
void Refetch();
static void ToggleFetcher();
static void DownloadInBackground(const MPD::Song *s);
# endif // HAVE_CURL_CURL_H

View File

@@ -19,6 +19,7 @@
***************************************************************************/
#include <algorithm>
#include <cassert>
#include "charset.h"
#include "display.h"
@@ -553,31 +554,57 @@ void MediaLibrary::ApplyFilter(const std::string &s)
GetList()->ApplyFilter(s, 0, REG_ICASE | Config.regex_type);
}
bool MediaLibrary::NextColumn()
bool MediaLibrary::isNextColumnAvailable()
{
assert(!hasTwoColumns || w != Artists);
if (w == Artists)
{
if (!Albums->ReallyEmpty() && !Songs->ReallyEmpty())
return true;
}
else if (w == Albums)
{
if (!Songs->ReallyEmpty())
return true;
}
return false;
}
void MediaLibrary::NextColumn()
{
if (w == Artists)
{
if (!hasTwoColumns && Songs->ReallyEmpty())
return false;
Artists->HighlightColor(Config.main_highlight_color);
w->Refresh();
w = Albums;
Albums->HighlightColor(Config.active_column_color);
if (!Albums->ReallyEmpty())
return true;
}
if (w == Albums && !Songs->ReallyEmpty())
else if (w == Albums)
{
Albums->HighlightColor(Config.main_highlight_color);
w->Refresh();
w = Songs;
Songs->HighlightColor(Config.active_column_color);
return true;
}
}
bool MediaLibrary::isPrevColumnAvailable()
{
assert(!hasTwoColumns || w != Artists);
if (w == Songs)
{
if (!Albums->ReallyEmpty() && (hasTwoColumns || !Artists->ReallyEmpty()))
return true;
}
else if (w == Albums)
{
if (!hasTwoColumns && !Artists->ReallyEmpty())
return true;
}
return false;
}
bool MediaLibrary::PrevColumn()
void MediaLibrary::PrevColumn()
{
if (w == Songs)
{
@@ -585,18 +612,14 @@ bool MediaLibrary::PrevColumn()
w->Refresh();
w = Albums;
Albums->HighlightColor(Config.active_column_color);
if (!Albums->ReallyEmpty())
return true;
}
if (w == Albums && !hasTwoColumns)
else if (w == Albums && !hasTwoColumns)
{
Albums->HighlightColor(Config.main_highlight_color);
w->Refresh();
w = Artists;
Artists->HighlightColor(Config.active_column_color);
return true;
}
return false;
}
void MediaLibrary::LocateSong(const MPD::Song &s)

View File

@@ -69,8 +69,10 @@ class MediaLibrary : public Screen<Window>
virtual bool isMergable() { return true; }
int Columns() { return hasTwoColumns ? 2 : 3; }
bool NextColumn();
bool PrevColumn();
bool isNextColumnAvailable();
void NextColumn();
bool isPrevColumnAvailable();
void PrevColumn();
void LocateSong(const MPD::Song &);

View File

@@ -98,8 +98,8 @@ namespace NCurses
virtual bool isFiltered() = 0;
};
/// This template class is generic menu, that has holds
/// any values that are std::vector compatible.
/// This template class is generic menu capable of
/// holding any std::vector compatible values.
///
template <typename T> class Menu : public Window, public List
{

View File

@@ -30,7 +30,6 @@ MPD::Connection Mpd;
const char *MPD::Message::PartOfSongsAdded = "Only part of requested songs' list added to playlist!";
const char *MPD::Message::FullPlaylist = "Playlist is full!";
const char *MPD::Message::FunctionDisabledFilteringEnabled = "Function disabled due to enabled filtering in playlist";
MPD::Connection::Connection() : itsConnection(0),
isCommandsListEnabled(0),
@@ -480,19 +479,19 @@ void MPD::Connection::Prev()
}
}
void MPD::Connection::Move(unsigned from, unsigned to)
bool MPD::Connection::Move(unsigned from, unsigned to)
{
if (!itsConnection)
return;
return false;
if (!isCommandsListEnabled)
{
GoBusy();
mpd_run_move(itsConnection, from, to);
return mpd_run_move(itsConnection, from, to);
}
else
{
assert(!isIdle);
mpd_send_move(itsConnection, from, to);
return mpd_send_move(itsConnection, from, to);
}
}
@@ -598,17 +597,21 @@ void MPD::Connection::AddToPlaylist(const std::string &path, const std::string &
}
}
void MPD::Connection::Move(const std::string &path, int from, int to)
bool MPD::Connection::Move(const std::string &path, int from, int to)
{
if (!itsConnection)
return;
return false;
if (!isCommandsListEnabled)
{
GoBusy();
return mpd_send_playlist_move(itsConnection, path.c_str(), from, to)
&& mpd_response_finish(itsConnection);
}
else
{
assert(!isIdle);
mpd_send_playlist_move(itsConnection, path.c_str(), from, to);
if (!isCommandsListEnabled)
mpd_response_finish(itsConnection);
return mpd_send_playlist_move(itsConnection, path.c_str(), from, to);
}
}
bool MPD::Connection::Rename(const std::string &from, const std::string &to)
@@ -1025,10 +1028,10 @@ bool MPD::Connection::CommitCommandsList()
assert(isCommandsListEnabled);
assert(!isIdle);
mpd_command_list_end(itsConnection);
mpd_response_finish(itsConnection);
isCommandsListEnabled = 0;
return mpd_response_finish(itsConnection);
if (GetPlaylistLength() == itsMaxPlaylistLength && itsErrorHandler)
itsErrorHandler(this, MPD_SERVER_ERROR_PLAYLIST_MAX, Message::FullPlaylist, itsErrorHandlerUserdata);
isCommandsListEnabled = 0;
bool result = !CheckForErrors();
UpdateStatus();
return result;

View File

@@ -33,7 +33,6 @@ namespace MPD
{
extern const char *PartOfSongsAdded;
extern const char *FullPlaylist;
extern const char *FunctionDisabledFilteringEnabled;
}
enum ItemType { itDirectory, itSong, itPlaylist };
@@ -121,7 +120,7 @@ namespace MPD
void Stop();
void Next();
void Prev();
void Move(unsigned, unsigned);
bool Move(unsigned, unsigned);
void Swap(unsigned, unsigned);
void Seek(unsigned);
void Shuffle();
@@ -193,7 +192,7 @@ namespace MPD
void ClearPlaylist(const std::string &);
void AddToPlaylist(const std::string &, const Song &);
void AddToPlaylist(const std::string &, const std::string &);
void Move(const std::string &, int, int);
bool Move(const std::string &, int, int);
bool Rename(const std::string &, const std::string &);
void StartSearch(bool);

File diff suppressed because it is too large Load Diff

View File

@@ -36,9 +36,6 @@ Playlist *myPlaylist = new Playlist;
bool Playlist::ReloadTotalLength = 0;
bool Playlist::ReloadRemaining = 0;
bool Playlist::BlockNowPlayingUpdate = 0;
bool Playlist::BlockUpdate = 0;
const size_t Playlist::SortOptions = 10;
const size_t Playlist::SortDialogWidth = 30;
size_t Playlist::SortDialogHeight;
@@ -156,10 +153,7 @@ void Playlist::EnterPressed()
if (w == Items)
{
if (!Items->Empty())
{
Mpd.PlayID(Items->Current().GetID());
Global::UpdateStatusImmediately = 1;
}
}
else if (w == SortDialog)
{
@@ -177,21 +171,7 @@ void Playlist::EnterPressed()
if (pos > SortOptions)
{
if (pos == SortOptions+2) // reverse
{
BlockUpdate = 1;
ShowMessage("Reversing playlist order...");
Mpd.StartCommandsList();
for (size_t i = beginning, j = end-1; i < (beginning+end)/2; ++i, --j)
{
Mpd.Swap(i, j);
Items->Swap(i, j);
}
ShowMessage(Mpd.CommitCommandsList() ? "Playlist reversed!" : "Error while reversing playlist!");
w = Items;
return;
}
else if (pos == SortOptions+3) // cancel
if (pos == SortOptions+2) // cancel
{
w = Items;
return;
@@ -221,7 +201,6 @@ void Playlist::EnterPressed()
return;
}
BlockUpdate = 1;
Mpd.StartCommandsList();
do
{
@@ -237,7 +216,8 @@ void Playlist::EnterPressed()
}
}
while (playlist != cmp);
ShowMessage(Mpd.CommitCommandsList() ? "Playlist sorted!" : "Error while sorting playlist!");
if (Mpd.CommitCommandsList())
ShowMessage("Playlist sorted!");
w = Items;
}
}
@@ -290,7 +270,7 @@ MPD::Song *Playlist::CurrentSong()
void Playlist::GetSelectedSongs(MPD::SongList &v)
{
if (myPlaylist->Items->Empty())
if (Items->Empty())
return;
std::vector<size_t> selected;
Items->GetSelected(selected);
@@ -306,8 +286,97 @@ void Playlist::ApplyFilter(const std::string &s)
Items->ApplyFilter(s, 0, REG_ICASE | Config.regex_type);
}
bool Playlist::isFiltered()
{
if (Items->isFiltered())
{
ShowMessage("Function disabled due to enabled filtering in playlist");
return true;
}
return false;
}
void Playlist::MoveSelectedItems(Movement where)
{
if (Items->Empty() || isFiltered())
return;
// remove search results as we may move them to different positions, but
// search rememebers positions and may point to wrong ones after that.
Items->Search("");
switch (where)
{
case mUp:
{
if (myPlaylist->Items->hasSelected())
{
std::vector<size_t> list;
myPlaylist->Items->GetSelected(list);
if (list.front() > 0)
{
Mpd.StartCommandsList();
std::vector<size_t>::const_iterator it = list.begin();
for (; it != list.end(); ++it)
Mpd.Move(*it-1, *it);
if (Mpd.CommitCommandsList())
{
myPlaylist->Items->Select(list.back(), false);
myPlaylist->Items->Select(list.front()-1, true);
myPlaylist->Items->Highlight(list[(list.size()-1)/2]-1);
}
}
}
else
{
size_t pos = myPlaylist->Items->Choice();
if (pos > 0)
{
if (Mpd.Move(pos-1, pos))
myPlaylist->Items->Scroll(wUp);
}
}
break;
}
case mDown:
{
if (Items->hasSelected())
{
std::vector<size_t> list;
Items->GetSelected(list);
if (list.back() < Items->Size()-1)
{
Mpd.StartCommandsList();
std::vector<size_t>::const_reverse_iterator it = list.rbegin();
for (; it != list.rend(); ++it)
Mpd.Move(*it, *it+1);
if (Mpd.CommitCommandsList())
{
Items->Select(list.front(), false);
Items->Select(list.back()+1, true);
Items->Highlight(list[(list.size()-1)/2]+1);
}
}
}
else
{
size_t pos = Items->Choice();
if (pos < Items->Size()-1)
{
if (Mpd.Move(pos, pos+1))
Items->Scroll(wDown);
}
}
break;
}
}
}
void Playlist::Sort()
{
if (isFiltered())
return;
if (Items->GetWidth() < SortDialogWidth || MainHeight < 5)
ShowMessage("Screen is too small to display dialog window!");
else
@@ -317,24 +386,56 @@ void Playlist::Sort()
}
}
void Playlist::AdjustSortOrder(int key)
void Playlist::Reverse()
{
if (Keypressed(key, Key.MvSongUp))
if (isFiltered())
return;
ShowMessage("Reversing playlist order...");
size_t beginning = -1, end = -1;
for (size_t i = 0; i < Items->Size(); ++i)
{
size_t pos = SortDialog->Choice();
if (pos > 0 && pos < SortOptions)
if (Items->isSelected(i))
{
SortDialog->Swap(pos, pos-1);
SortDialog->Scroll(wUp);
if (beginning == size_t(-1))
beginning = i;
end = i;
}
}
else if (Keypressed(key, Key.MvSongDown))
if (beginning == size_t(-1)) // no selected items
{
size_t pos = SortDialog->Choice();
if (pos < SortOptions-1)
beginning = 0;
end = Items->Size();
}
Mpd.StartCommandsList();
for (size_t i = beginning, j = end-1; i < (beginning+end)/2; ++i, --j)
Mpd.Swap(i, j);
if (Mpd.CommitCommandsList())
ShowMessage("Playlist reversed!");
}
void Playlist::AdjustSortOrder(Movement where)
{
switch (where)
{
case mUp:
{
SortDialog->Swap(pos, pos+1);
SortDialog->Scroll(wDown);
size_t pos = SortDialog->Choice();
if (pos > 0 && pos < SortOptions)
{
SortDialog->Swap(pos, pos-1);
SortDialog->Scroll(wUp);
}
break;
}
case mDown:
{
size_t pos = SortDialog->Choice();
if (pos < SortOptions-1)
{
SortDialog->Swap(pos, pos+1);
SortDialog->Scroll(wDown);
}
break;
}
}
}
@@ -430,7 +531,6 @@ std::string Playlist::SongInColumnsToString(const MPD::Song &s, void *)
bool Playlist::Add(const MPD::Song &s, bool in_playlist, bool play, int position)
{
Global::BlockItemListUpdate = 1;
if (Config.ncmpc_like_songs_adding && in_playlist)
{
unsigned hash = s.GetHash();
@@ -448,7 +548,6 @@ bool Playlist::Add(const MPD::Song &s, bool in_playlist, bool play, int position
}
else
{
Playlist::BlockUpdate = 1;
Mpd.StartCommandsList();
for (size_t i = 0; i < Items->Size(); ++i)
{
@@ -460,7 +559,6 @@ bool Playlist::Add(const MPD::Song &s, bool in_playlist, bool play, int position
}
}
Mpd.CommitCommandsList();
Playlist::BlockUpdate = 0;
return false;
}
}

View File

@@ -30,6 +30,8 @@
class Playlist : public Screen<Window>
{
public:
enum Movement { mUp, mDown };
Playlist() : NowPlaying(-1), itsTotalLength(0), itsRemainingTime(0), itsScrollBegin(0) { }
~Playlist() { }
@@ -57,11 +59,15 @@ class Playlist : public Screen<Window>
virtual bool isMergable() { return true; }
bool isFiltered();
bool isPlaying() { return NowPlaying >= 0 && !Items->Empty(); }
const MPD::Song *NowPlayingSong();
void MoveSelectedItems(Movement where);
void Sort();
void AdjustSortOrder(int key);
void Reverse();
void AdjustSortOrder(Movement where);
bool SortingInProgress() { return w == SortDialog; }
void FixPositions(size_t = 0);
@@ -82,9 +88,6 @@ class Playlist : public Screen<Window>
static bool ReloadTotalLength;
static bool ReloadRemaining;
static bool BlockNowPlayingUpdate;
static bool BlockUpdate;
protected:
virtual void Init();
virtual bool isLockable() { return true; }

View File

@@ -188,6 +188,100 @@ void PlaylistEditor::Update()
}
}
void PlaylistEditor::MoveSelectedItems(Playlist::Movement where)
{
if (Content->Empty())
return;
// remove search results as we may move them to different positions, but
// search rememebers positions and may point to wrong ones after that.
Content->Search("");
switch (where)
{
case Playlist::mUp:
{
if (Content->hasSelected())
{
std::vector<size_t> list;
Content->GetSelected(list);
if (list.front() > 0)
{
Mpd.StartCommandsList();
std::vector<size_t>::const_iterator it = list.begin();
for (; it != list.end(); ++it)
Mpd.Move(Playlists->Current(), *it-1, *it);
if (Mpd.CommitCommandsList())
{
for (it = list.begin(); it != list.end(); ++it)
Content->Swap(*it-1, *it);
Content->Highlight(list[(list.size()-1)/2]-1);
}
}
}
else
{
size_t pos = Content->Choice();
if (pos > 0)
{
if (Mpd.Move(Playlists->Current(), pos-1, pos))
{
Content->Scroll(wUp);
Content->Swap(pos-1, pos);
}
}
}
break;
}
case Playlist::mDown:
{
if (Content->hasSelected())
{
std::vector<size_t> list;
Content->GetSelected(list);
if (list.back() < Content->Size()-1)
{
Mpd.StartCommandsList();
std::vector<size_t>::const_reverse_iterator it = list.rbegin();
for (; it != list.rend(); ++it)
Mpd.Move(Playlists->Current(), *it, *it+1);
if (Mpd.CommitCommandsList())
{
Content->Highlight(list[(list.size()-1)/2]+1);
for (it = list.rbegin(); it != list.rend(); ++it)
Content->Swap(*it, *it+1);
}
}
}
else
{
size_t pos = Content->Choice();
if (pos < Content->Size()-1)
{
if (Mpd.Move(Playlists->Current(), pos, pos+1))
{
Content->Scroll(wDown);
Content->Swap(pos, pos+1);
}
}
}
break;
}
}
}
bool PlaylistEditor::isNextColumnAvailable()
{
if (w == Playlists)
{
if (!Content->ReallyEmpty())
return true;
}
return false;
}
bool PlaylistEditor::NextColumn()
{
if (w == Playlists)
@@ -201,6 +295,16 @@ bool PlaylistEditor::NextColumn()
return false;
}
bool PlaylistEditor::isPrevColumnAvailable()
{
if (w == Content)
{
if (!Playlists->ReallyEmpty())
return true;
}
return false;
}
bool PlaylistEditor::PrevColumn()
{
if (w == Content)
@@ -308,18 +412,21 @@ void PlaylistEditor::ApplyFilter(const std::string &s)
GetList()->ApplyFilter(s, 0, REG_ICASE | Config.regex_type);
}
void PlaylistEditor::JumpTo(const std::string &s)
void PlaylistEditor::Locate(const std::string &name)
{
SwitchTo();
if (!isInitialized)
Init();
Update();
for (size_t i = 0; i < Playlists->Size(); ++i)
{
if (s == (*Playlists)[i])
if (name == (*Playlists)[i])
{
Playlists->Highlight(i);
Content->Clear();
break;
}
}
SwitchTo();
}
List *PlaylistEditor::GetList()

View File

@@ -21,6 +21,7 @@
#ifndef _PLAYLIST_EDITOR_H
#define _PLAYLIST_EDITOR_H
#include "playlist.h"
#include "ncmpcpp.h"
class PlaylistEditor : public Screen<Window>
@@ -48,13 +49,17 @@ class PlaylistEditor : public Screen<Window>
virtual void ApplyFilter(const std::string &);
virtual void JumpTo(const std::string &);
virtual void Locate(const std::string &);
virtual List *GetList();
virtual bool isMergable() { return true; }
void MoveSelectedItems(Playlist::Movement where);
bool isNextColumnAvailable();
bool NextColumn();
bool isPrevColumnAvailable();
bool PrevColumn();
Menu<std::string> *Playlists;

View File

@@ -81,7 +81,7 @@ class BasicScreen
/// @see Screen::Scroll()
///
virtual void Scroll(Where where, const int key[2] = 0) = 0;
virtual void Scroll(Where where) = 0;
/// Invoked after Enter was pressed
///
@@ -212,10 +212,8 @@ template <typename WindowType> class Screen : public BasicScreen
/// if fancy scrolling feature is disabled, enters the
/// loop that holds main loop until user releases the key
/// @param where indicates where one wants to scroll
/// @param key needed if fancy scrolling is disabled to
/// define the conditional for while loop
///
virtual void Scroll(Where where, const int key[2] = 0);
virtual void Scroll(Where where);
/// Invoked after there was one of mouse buttons pressed
/// @param me struct that contains coords of where the click
@@ -257,23 +255,9 @@ template <typename WindowType> void Screen<WindowType>::ReadKey(int &key)
w->ReadKey(key);
}
template <typename WindowType> void Screen<WindowType>::Scroll(Where where, const int key[2])
template <typename WindowType> void Screen<WindowType>::Scroll(Where where)
{
if (!Config.fancy_scrolling && key)
{
int in = key[0];
w->SetTimeout(50);
while (Keypressed(in, key))
{
TraceMpdStatus();
w->Scroll(where);
w->Refresh();
ReadKey(in);
}
w->SetTimeout(ncmpcpp_window_timeout);
}
else
w->Scroll(where);
w->Scroll(where);
}
template <typename WindowType> void Screen<WindowType>::MouseButtonPressed(MEVENT me)

View File

@@ -277,77 +277,6 @@ void SearchEngine::UpdateFoundList()
}
}
void SearchEngine::Scroll(int input)
{
size_t pos = w->Choice();
// above the reset button
if (pos < ResetButton)
{
if (Keypressed(input, Key.UpAlbum) || Keypressed(input, Key.UpArtist))
w->Highlight(0);
else if (Keypressed(input, Key.DownAlbum) || Keypressed(input, Key.DownArtist))
w->Highlight(ResetButton);
}
// reset button
else if (pos == ResetButton)
{
if (Keypressed(input, Key.UpAlbum) || Keypressed(input, Key.UpArtist))
w->Highlight(0);
else if (Keypressed(input, Key.DownAlbum) || Keypressed(input, Key.DownArtist))
w->Highlight(StaticOptions); // first search result
}
// we are in the search results at this point
else if (pos >= StaticOptions)
{
if (Keypressed(input, Key.UpAlbum))
{
if (pos == StaticOptions)
{
w->Highlight(ResetButton);
return;
}
else
{
std::string album = w->at(pos).second->GetAlbum();
while (pos > StaticOptions)
if (w->at(--pos).second->GetAlbum() != album)
break;
}
}
else if (Keypressed(input, Key.DownAlbum))
{
std::string album = w->at(pos).second->GetAlbum();
while (pos < w->Size() - 1)
if (w->at(++pos).second->GetAlbum() != album)
break;
}
else if (Keypressed(input, Key.UpArtist))
{
if (pos == StaticOptions)
{
w->Highlight(0);
return;
}
else
{
std::string artist = w->at(pos).second->GetArtist();
while (pos > StaticOptions)
if (w->at(--pos).second->GetArtist() != artist)
break;
}
}
else if (Keypressed(input, Key.DownArtist))
{
std::string artist = w->at(pos).second->GetArtist();
while (pos < w->Size() - 1)
if (w->at(++pos).second->GetArtist() != artist)
break;
}
w->Highlight(pos);
}
}
void SearchEngine::SelectAlbum()
{
size_t pos = w->Choice();
@@ -622,9 +551,13 @@ void SearchEngine::Search()
std::string SearchEngine::SearchEngineOptionToString(const std::pair<Buffer *, MPD::Song *> &pair, void *)
{
if (!Config.columns_in_search_engine)
return pair.second->toString(Config.song_list_format_dollar_free);
if (pair.second)
{
if (!Config.columns_in_search_engine)
return pair.second->toString(Config.song_list_format_dollar_free);
else
return Playlist::SongInColumnsToString(*pair.second, 0);
}
else
return Playlist::SongInColumnsToString(*pair.second, 0);
return "";
}

View File

@@ -51,7 +51,6 @@ class SearchEngine : public Screen< Menu< std::pair<Buffer *, MPD::Song *> > >
virtual bool isMergable() { return true; }
void UpdateFoundList();
void Scroll(int);
void SelectAlbum();
static size_t StaticOptions;

View File

@@ -31,6 +31,7 @@
#include <iostream>
#include <stdexcept>
#include "actions.h"
#include "browser.h"
#include "clock.h"
#include "global.h"
@@ -55,34 +56,6 @@ NcmpcppKeys Key;
namespace
{
void GetKeys(std::string &line, int *key)
{
size_t i = line.find("=")+1;
line = line.substr(i, line.length()-i);
i = 0;
if (line[i] == ' ')
while (line[++i] == ' ') { }
line = line.substr(i, line.length()-i);
i = line.find(" ");
std::string one;
std::string two;
if (i != std::string::npos)
{
one = line.substr(0, i);
i++;
two = line.substr(i, line.length()-i);
}
else
one = line;
key[0] = !one.empty() && one[0] == '\''
? one[1]
: (atoi(one.c_str()) == 0 ? NcmpcppKeys::NullKey : atoi(one.c_str()));
key[1] = !two.empty() && two[0] == '\''
? two[1]
: (atoi(two.c_str()) == 0 ? NcmpcppKeys::NullKey : atoi(two.c_str()));
}
Border IntoBorder(const std::string &color)
{
return Border(IntoColor(color));
@@ -158,207 +131,156 @@ void CreateDir(const std::string &dir)
);
}
void SetWindowsDimensions(size_t &header_height, size_t &footer_start_y, size_t &footer_height)
void NcmpcppKeys::GenerateKeybindings()
{
Global::MainStartY = Config.new_design ? 5 : 2;
Global::MainHeight = LINES-(Config.new_design ? 7 : 4);
# define BIND(key, action) Bindings.insert(std::make_pair(key, Action::Get(action)))
if (!Config.header_visibility)
{
Global::MainStartY -= 2;
Global::MainHeight += 2;
}
if (!Config.statusbar_visibility)
Global::MainHeight++;
BIND(KEY_MOUSE, aMouseEvent);
BIND(KEY_UP, aScrollUp);
BIND(KEY_DOWN, aScrollDown);
BIND('[', aScrollUpAlbum);
BIND(']', aScrollDownAlbum);
BIND('{', aScrollUpArtist);
BIND('}', aScrollDownArtist);
BIND(KEY_PPAGE, aPageUp);
BIND(KEY_NPAGE, aPageDown);
BIND(KEY_HOME, aMoveHome);
BIND(KEY_END, aMoveEnd);
BIND(' ', aPressSpace);
BIND(KEY_ENTER, aPressEnter);
BIND(KEY_DC, aDelete);
BIND(KEY_RIGHT, aNextColumn);
BIND(KEY_RIGHT, aSlaveScreen);
BIND(KEY_RIGHT, aVolumeUp);
BIND(KEY_LEFT, aPreviousColumn);
BIND(KEY_LEFT, aMasterScreen);
BIND(KEY_LEFT, aVolumeDown);
BIND(KEY_TAB, aNextScreen);
BIND(KEY_SHIFT_TAB, aPreviousScreen);
BIND('1', aShowHelp);
BIND('2', aShowPlaylist);
BIND('3', aShowBrowser);
BIND('4', aShowSearchEngine);
BIND('5', aShowMediaLibrary);
BIND('6', aShowPlaylistEditor);
BIND('7', aShowTagEditor);
BIND('8', aShowOutputs);
BIND('9', aShowVisualizer);
BIND('0', aShowClock);
BIND('@', aShowServerInfo);
BIND('s', aStop);
BIND('P', aPause);
BIND('>', aNextSong);
BIND('<', aPreviousSong);
BIND(KEY_BACKSPACE, aJumpToParentDir);
BIND(KEY_BACKSPACE, aReplaySong);
BIND(KEY_BACKSPACE_2, aJumpToParentDir);
BIND(KEY_BACKSPACE_2, aReplaySong);
BIND('f', aSeekForward);
BIND('b', aSeekBackward);
BIND('r', aToggleRepeat);
BIND('z', aToggleRandom);
BIND('y', aSaveTagChanges);
BIND('y', aStartSearching);
BIND('y', aToggleSingle);
BIND('R', aToggleConsume);
BIND('Y', aToggleReplayGainMode);
BIND('t', aToggleSpaceMode);
BIND('T', aToggleAddMode);
BIND('|', aToggleMouse);
BIND('#', aToggleBitrateVisibility);
BIND('Z', aShuffle);
BIND('x', aToggleCrossfade);
BIND('X', aSetCrossfade);
BIND('u', aUpdateDatabase);
BIND(KEY_CTRL_V, aSortPlaylist);
BIND(KEY_CTRL_R, aReversePlaylist);
BIND(KEY_CTRL_F, aApplyFilter);
BIND(KEY_CTRL_G, aDisableFilter);
BIND('/', aFind);
BIND('/', aFindItemForward);
BIND('?', aFind);
BIND('?', aFindItemBackward);
BIND('.', aNextFoundItem);
BIND(',', aPreviousFoundItem);
BIND('w', aToggleFindMode);
BIND('e', aEditSong);
BIND('e', aEditLibraryTag);
BIND('e', aEditLibraryAlbum);
BIND('e', aEditDirectoryName);
BIND('e', aEditPlaylistName);
BIND('e', aEditLyrics);
BIND('i', aShowSongInfo);
BIND('I', aShowArtistInfo);
BIND('g', aJumpToPositionInSong);
BIND('l', aShowLyrics);
BIND('v', aReverseSelection);
BIND('V', aDeselectItems);
BIND('B', aSelectAlbum);
BIND('a', aAddSelectedItems);
BIND('c', aClearPlaylist);
BIND('c', aClearMainPlaylist);
BIND('C', aCropPlaylist);
BIND('C', aCropMainPlaylist);
BIND('m', aMoveSortOrderUp);
BIND('m', aMoveSelectedItemsUp);
BIND('n', aMoveSortOrderDown);
BIND('n', aMoveSelectedItemsDown);
BIND('M', aMoveSelectedItemsTo);
BIND('A', aAdd);
BIND('S', aSavePlaylist);
BIND('o', aJumpToPlayingSong);
BIND('G', aJumpToBrowser);
BIND('G', aJumpToPlaylistEditor);
BIND('~', aJumpToMediaLibrary);
BIND('E', aJumpToTagEditor);
BIND('U', aToggleAutoCenter);
BIND('p', aToggleDisplayMode);
BIND('\\', aToggleInterface);
BIND('!', aToggleSeparatorsInPlaylist);
BIND('L', aToggleLyricsFetcher);
BIND('F', aToggleFetchingLyricsInBackground);
BIND(KEY_CTRL_L, aToggleScreenLock);
BIND('`', aToggleBrowserSortMode);
BIND('`', aToggleLibraryTagType);
BIND('`', aRefetchLyrics);
BIND('`', aRefetchArtistInfo);
BIND('`', aAddRandomItems);
BIND('q', aQuit);
header_height = Config.new_design ? (Config.header_visibility ? 5 : 3) : 1;
footer_start_y = LINES-(Config.statusbar_visibility ? 2 : 1);
footer_height = Config.statusbar_visibility ? 2 : 1;
BIND('k', aScrollUp);
BIND('j', aScrollDown);
BIND('d', aDelete);
BIND('+', aVolumeUp);
BIND('-', aVolumeDown);
BIND(KEY_F1, aShowHelp);
BIND(KEY_F2, aShowPlaylist);
BIND(KEY_F3, aShowBrowser);
BIND(KEY_F4, aShowSearchEngine);
BIND(KEY_F5, aShowMediaLibrary);
BIND(KEY_F6, aShowPlaylistEditor);
BIND(KEY_F7, aShowTagEditor);
BIND(KEY_F8, aShowOutputs);
BIND(KEY_F9, aShowVisualizer);
BIND(KEY_F10, aShowClock);
BIND('Q', aQuit);
# undef BIND
}
void NcmpcppKeys::SetDefaults()
int NcmpcppKeys::GetFirstBinding(const ActionType at)
{
Up[0] = KEY_UP;
Down[0] = KEY_DOWN;
UpAlbum[0] = '[';
DownAlbum[0] = ']';
UpArtist[0] = '{';
DownArtist[0] = '}';
PageUp[0] = KEY_PPAGE;
PageDown[0] = KEY_NPAGE;
Home[0] = KEY_HOME;
End[0] = KEY_END;
Space[0] = 32;
Enter[0] = 10;
Delete[0] = KEY_DC;
VolumeUp[0] = KEY_RIGHT;
VolumeDown[0] = KEY_LEFT;
PrevColumn[0] = KEY_LEFT;
NextColumn[0] = KEY_RIGHT;
ScreenSwitcher[0] = 9;
BackwardScreenSwitcher[0] = 353;
Help[0] = '1';
Playlist[0] = '2';
Browser[0] = '3';
SearchEngine[0] = '4';
MediaLibrary[0] = '5';
PlaylistEditor[0] = '6';
TagEditor[0] = '7';
Outputs[0] = '8';
Visualizer[0] = '9';
Clock[0] = '0';
ServerInfo[0] = '@';
Stop[0] = 's';
Pause[0] = 'P';
Next[0] = '>';
Prev[0] = '<';
Replay[0] = KEY_BACKSPACE;
SeekForward[0] = 'f';
SeekBackward[0] = 'b';
ToggleRepeat[0] = 'r';
ToggleRandom[0] = 'z';
ToggleSingle[0] = 'y';
ToggleConsume[0] = 'R';
ToggleReplayGainMode[0] = 'Y';
ToggleSpaceMode[0] = 't';
ToggleAddMode[0] = 'T';
ToggleMouse[0] = '|';
ToggleBitrateVisibility[0] = '#';
Shuffle[0] = 'Z';
ToggleCrossfade[0] = 'x';
SetCrossfade[0] = 'X';
UpdateDB[0] = 'u';
SortPlaylist[0] = 22;
ApplyFilter[0] = 6;
DisableFilter[0] = 7;
FindForward[0] = '/';
FindBackward[0] = '?';
NextFoundPosition[0] = '.';
PrevFoundPosition[0] = ',';
ToggleFindMode[0] = 'w';
EditTags[0] = 'e';
SongInfo[0] = 'i';
ArtistInfo[0] = 'I';
GoToPosition[0] = 'g';
Lyrics[0] = 'l';
ReverseSelection[0] = 'v';
DeselectAll[0] = 'V';
SelectAlbum[0] = 'B';
AddSelected[0] = 'A';
Clear[0] = 'c';
Crop[0] = 'C';
MvSongUp[0] = 'm';
MvSongDown[0] = 'n';
MoveTo[0] = 'M';
MoveBefore[0] = NullKey;
MoveAfter[0] = NullKey;
Add[0] = 'a';
SavePlaylist[0] = 'S';
GoToNowPlaying[0] = 'o';
GoToContainingDir[0] = 'G';
GoToMediaLibrary[0] = '~';
GoToTagEditor[0] = 'E';
ToggleAutoCenter[0] = 'U';
ToggleDisplayMode[0] = 'p';
ToggleInterface[0] = '\\';
ToggleSeparatorsInPlaylist[0] = '!';
ToggleLyricsDB[0] = 'L';
ToggleFetchingLyricsInBackground[0] = 'F';
ToggleScreenLock[0] = 12;
GoToParentDir[0] = KEY_BACKSPACE;
SwitchTagTypeList[0] = '`';
Quit[0] = 'q';
Up[1] = 'k';
Down[1] = 'j';
UpAlbum[1] = NullKey;
DownAlbum[1] = NullKey;
UpArtist[1] = NullKey;
DownArtist[1] = NullKey;
PageUp[1] = NullKey;
PageDown[1] = NullKey;
Home[1] = NullKey;
End[1] = NullKey;
Space[1] = NullKey;
Enter[1] = NullKey;
Delete[1] = 'd';
VolumeUp[1] = '+';
VolumeDown[1] = '-';
PrevColumn[1] = NullKey;
NextColumn[1] = NullKey;
ScreenSwitcher[1] = NullKey;
BackwardScreenSwitcher[1] = NullKey;
Help[1] = 265;
Playlist[1] = 266;
Browser[1] = 267;
SearchEngine[1] = 268;
MediaLibrary[1] = 269;
PlaylistEditor[1] = 270;
TagEditor[1] = 271;
Outputs[1] = 272;
Visualizer[1] = 273;
Clock[1] = 274;
ServerInfo[1] = NullKey;
Stop[1] = NullKey;
Pause[1] = NullKey;
Next[1] = NullKey;
Prev[1] = NullKey;
Replay[1] = 127;
SeekForward[1] = NullKey;
SeekBackward[1] = NullKey;
ToggleRepeat[1] = NullKey;
ToggleRandom[1] = NullKey;
ToggleSingle[1] = NullKey;
ToggleConsume[1] = NullKey;
ToggleReplayGainMode[1] = NullKey;
ToggleSpaceMode[1] = NullKey;
ToggleAddMode[1] = NullKey;
ToggleMouse[1] = NullKey;
ToggleBitrateVisibility[1] = NullKey;
Shuffle[1] = NullKey;
ToggleCrossfade[1] = NullKey;
SetCrossfade[1] = NullKey;
UpdateDB[1] = NullKey;
SortPlaylist[1] = NullKey;
ApplyFilter[1] = NullKey;
DisableFilter[1] = NullKey;
FindForward[1] = NullKey;
FindBackward[1] = NullKey;
NextFoundPosition[1] = NullKey;
PrevFoundPosition[1] = NullKey;
ToggleFindMode[1] = NullKey;
EditTags[1] = NullKey;
SongInfo[1] = NullKey;
ArtistInfo[1] = NullKey;
GoToPosition[1] = NullKey;
Lyrics[1] = NullKey;
ReverseSelection[1] = NullKey;
DeselectAll[1] = NullKey;
SelectAlbum[1] = NullKey;
AddSelected[1] = NullKey;
Clear[1] = NullKey;
Crop[1] = NullKey;
MvSongUp[1] = NullKey;
MvSongDown[1] = NullKey;
MoveTo[1] = NullKey;
MoveBefore[1] = NullKey;
MoveAfter[1] = NullKey;
Add[1] = NullKey;
SavePlaylist[1] = NullKey;
GoToNowPlaying[1] = NullKey;
GoToContainingDir[1] = NullKey;
GoToMediaLibrary[1] = NullKey;
GoToTagEditor[1] = NullKey;
ToggleAutoCenter[1] = NullKey;
ToggleDisplayMode[1] = NullKey;
ToggleInterface[1] = NullKey;
ToggleSeparatorsInPlaylist[1] = NullKey;
ToggleLyricsDB[1] = NullKey;
ToggleFetchingLyricsInBackground[1] = NullKey;
ToggleScreenLock[1] = NullKey;
GoToParentDir[1] = 127;
SwitchTagTypeList[1] = NullKey;
Quit[1] = 'Q';
int result = 0;
std::multimap<int, Action *>::const_iterator it = Bindings.begin();
for (; it != Bindings.end(); ++it)
{
if (it->second->Type() == at)
{
result = it->first;
break;
}
}
return result;
}
void NcmpcppConfig::SetDefaults()
@@ -404,7 +326,6 @@ void NcmpcppConfig::SetDefaults()
media_lib_primary_tag = MPD_TAG_ARTIST;
enable_idle_notifications = true;
colors_enabled = true;
fancy_scrolling = true;
playlist_show_remaining_time = false;
playlist_shorten_total_times = false;
playlist_separate_albums = false;
@@ -428,7 +349,6 @@ void NcmpcppConfig::SetDefaults()
fetch_lyrics_in_background = false;
local_browser_show_hidden_files = false;
search_in_db = true;
display_screens_numbers_on_start = true;
jump_to_now_playing_song_at_start = true;
clock_display_seconds = false;
display_volume_level = true;
@@ -481,200 +401,6 @@ void NcmpcppConfig::SetDefaults()
screens_seq.push_back(myBrowser);
}
void NcmpcppKeys::Read()
{
std::ifstream f((Config.ncmpcpp_directory + "keys").c_str());
std::string key, name;
if (!f.is_open())
return;
while (!f.eof())
{
getline(f, key);
if (!key.empty() && key[0] != '#')
{
name = GetOptionName(key);
if (name == "key_up")
GetKeys(key, Up);
else if (name == "key_down")
GetKeys(key, Down);
else if (name == "key_up_album")
GetKeys(key, UpAlbum);
else if (name == "key_down_album")
GetKeys(key, DownAlbum);
else if (name == "key_up_artist")
GetKeys(key, UpArtist);
else if (name == "key_down_artist")
GetKeys(key, DownArtist);
else if (name == "key_page_up")
GetKeys(key, PageUp);
else if (name == "key_page_down")
GetKeys(key, PageDown);
else if (name == "key_home")
GetKeys(key, Home);
else if (name == "key_end")
GetKeys(key, End);
else if (name == "key_space")
GetKeys(key, Space);
else if (name == "key_enter")
GetKeys(key, Enter);
else if (name == "key_delete")
GetKeys(key, Delete);
else if (name == "key_volume_up")
GetKeys(key, VolumeUp);
else if (name == "key_volume_down")
GetKeys(key, VolumeDown);
else if (name == "key_prev_column")
GetKeys(key, PrevColumn);
else if (name == "key_next_column")
GetKeys(key, NextColumn);
else if (name == "key_screen_switcher")
GetKeys(key, ScreenSwitcher);
else if (name == "key_backward_screen_switcher")
GetKeys(key, BackwardScreenSwitcher);
else if (name == "key_help")
GetKeys(key, Help);
else if (name == "key_playlist")
GetKeys(key, Playlist);
else if (name == "key_browser")
GetKeys(key, Browser);
else if (name == "key_search_engine")
GetKeys(key, SearchEngine);
else if (name == "key_media_library")
GetKeys(key, MediaLibrary);
else if (name == "key_playlist_editor")
GetKeys(key, PlaylistEditor);
else if (name == "key_tag_editor")
GetKeys(key, TagEditor);
else if (name == "key_outputs")
GetKeys(key, Outputs);
else if (name == "key_music_visualizer")
GetKeys(key, Visualizer);
else if (name == "key_clock")
GetKeys(key, Clock);
else if (name == "key_server_info")
GetKeys(key, ServerInfo);
else if (name == "key_stop")
GetKeys(key, Stop);
else if (name == "key_pause")
GetKeys(key, Pause);
else if (name == "key_next")
GetKeys(key, Next);
else if (name == "key_prev")
GetKeys(key, Prev);
else if (name == "key_replay")
GetKeys(key, Replay);
else if (name == "key_seek_forward")
GetKeys(key, SeekForward);
else if (name == "key_seek_backward")
GetKeys(key, SeekBackward);
else if (name == "key_toggle_repeat")
GetKeys(key, ToggleRepeat);
else if (name == "key_toggle_random")
GetKeys(key, ToggleRandom);
else if (name == "key_toggle_single")
GetKeys(key, ToggleSingle);
else if (name == "key_toggle_consume")
GetKeys(key, ToggleConsume);
else if (name == "key_toggle_replay_gain_mode")
GetKeys(key, ToggleReplayGainMode);
else if (name == "key_toggle_space_mode")
GetKeys(key, ToggleSpaceMode);
else if (name == "key_toggle_add_mode")
GetKeys(key, ToggleAddMode);
else if (name == "key_toggle_mouse")
GetKeys(key, ToggleMouse);
else if (name == "key_toggle_bitrate_visibility")
GetKeys(key, ToggleBitrateVisibility);
else if (name == "key_shuffle")
GetKeys(key, Shuffle);
else if (name == "key_toggle_crossfade")
GetKeys(key, ToggleCrossfade);
else if (name == "key_set_crossfade")
GetKeys(key, SetCrossfade);
else if (name == "key_update_db")
GetKeys(key, UpdateDB);
else if (name == "key_sort_playlist")
GetKeys(key, SortPlaylist);
else if (name == "key_apply_filter")
GetKeys(key, ApplyFilter);
else if (name == "key_clear_filter")
GetKeys(key, DisableFilter);
else if (name == "key_find_forward")
GetKeys(key, FindForward);
else if (name == "key_find_backward")
GetKeys(key, FindBackward);
else if (name == "key_next_found_position")
GetKeys(key, NextFoundPosition);
else if (name == "key_prev_found_position")
GetKeys(key, PrevFoundPosition);
else if (name == "key_toggle_find_mode")
GetKeys(key, ToggleFindMode);
else if (name == "key_edit_tags")
GetKeys(key, EditTags);
else if (name == "key_go_to_position")
GetKeys(key, GoToPosition);
else if (name == "key_song_info")
GetKeys(key, SongInfo);
else if (name == "key_artist_info")
GetKeys(key, ArtistInfo);
else if (name == "key_lyrics")
GetKeys(key, Lyrics);
else if (name == "key_reverse_selection")
GetKeys(key, ReverseSelection);
else if (name == "key_deselect_all")
GetKeys(key, DeselectAll);
else if (name == "key_select_album")
GetKeys(key, SelectAlbum);
else if (name == "key_add_selected_items")
GetKeys(key, AddSelected);
else if (name == "key_clear")
GetKeys(key, Clear);
else if (name == "key_crop")
GetKeys(key, Crop);
else if (name == "key_move_song_up")
GetKeys(key, MvSongUp);
else if (name == "key_move_song_down")
GetKeys(key, MvSongDown);
else if (name == "key_move_to")
GetKeys(key, MoveTo);
else if (name == "key_move_before")
GetKeys(key, MoveBefore);
else if (name == "key_move_after")
GetKeys(key, MoveAfter);
else if (name == "key_add")
GetKeys(key, Add);
else if (name == "key_save_playlist")
GetKeys(key, SavePlaylist);
else if (name == "key_go_to_now_playing")
GetKeys(key, GoToNowPlaying);
else if (name == "key_toggle_auto_center")
GetKeys(key, ToggleAutoCenter);
else if (name == "key_toggle_display_mode")
GetKeys(key, ToggleDisplayMode);
else if (name == "key_toggle_separators_in_playlist")
GetKeys(key, ToggleSeparatorsInPlaylist);
else if (name == "key_toggle_lyrics_db")
GetKeys(key, ToggleLyricsDB);
else if (name == "key_toggle_fetching_lyrics_for_current_song_in_background")
GetKeys(key, ToggleFetchingLyricsInBackground);
else if (name == "key_go_to_containing_directory")
GetKeys(key, GoToContainingDir);
else if (name == "key_go_to_media_library")
GetKeys(key, GoToMediaLibrary);
else if (name == "key_go_to_parent_dir")
GetKeys(key, GoToParentDir);
else if (name == "key_switch_tag_type_list")
GetKeys(key, SwitchTagTypeList);
else if (name == "key_quit")
GetKeys(key, Quit);
}
}
f.close();
}
NcmpcppConfig::NcmpcppConfig()
{
# ifdef WIN32
@@ -991,10 +717,6 @@ void NcmpcppConfig::Read()
{
colors_enabled = v == "yes";
}
else if (name == "fancy_scrolling")
{
fancy_scrolling = v == "yes";
}
else if (name == "cyclic_scrolling")
{
use_cyclic_scrolling = v == "yes";
@@ -1118,10 +840,6 @@ void NcmpcppConfig::Read()
{
search_in_db = v == "database";
}
else if (name == "display_screens_numbers_on_start")
{
display_screens_numbers_on_start = v == "yes";
}
else if (name == "jump_to_now_playing_song_at_start")
{
jump_to_now_playing_song_at_start = v == "yes";

View File

@@ -25,6 +25,7 @@
#include <mpd/client.h>
#include "actions.h"
#include "ncmpcpp.h"
class BasicScreen; // forward declaration for screens sequence
@@ -46,101 +47,15 @@ struct Column
struct NcmpcppKeys
{
static const int NullKey = 0;
typedef std::pair<
std::multimap<int, Action *>::iterator
, std::multimap<int, Action *>::iterator
> Binding;
void SetDefaults();
void Read();
void GenerateKeybindings();
int GetFirstBinding(const ActionType at);
int Up[2];
int Down[2];
int UpAlbum[2];
int DownAlbum[2];
int UpArtist[2];
int DownArtist[2];
int PageUp[2];
int PageDown[2];
int Home[2];
int End[2];
int Space[2];
int Enter[2];
int Delete[2];
int VolumeUp[2];
int VolumeDown[2];
int PrevColumn[2];
int NextColumn[2];
int ScreenSwitcher[2];
int BackwardScreenSwitcher[2];
int Help[2];
int Playlist[2];
int Browser[2];
int SearchEngine[2];
int MediaLibrary[2];
int PlaylistEditor[2];
int TagEditor[2];
int Outputs[2];
int Visualizer[2];
int Clock[2];
int ServerInfo[2];
int Stop[2];
int Pause[2];
int Next[2];
int Prev[2];
int Replay[2];
int SeekForward[2];
int SeekBackward[2];
int ToggleRepeat[2];
int ToggleRandom[2];
int ToggleSingle[2];
int ToggleConsume[2];
int ToggleReplayGainMode[2];
int ToggleSpaceMode[2];
int ToggleAddMode[2];
int ToggleMouse[2];
int ToggleBitrateVisibility[2];
int Shuffle[2];
int ToggleCrossfade[2];
int SetCrossfade[2];
int UpdateDB[2];
int SortPlaylist[2];
int ApplyFilter[2];
int DisableFilter[2];
int FindForward[2];
int FindBackward[2];
int NextFoundPosition[2];
int PrevFoundPosition[2];
int ToggleFindMode[2];
int EditTags[2];
int SongInfo[2];
int ArtistInfo[2];
int GoToPosition[2];
int Lyrics[2];
int ReverseSelection[2];
int DeselectAll[2];
int SelectAlbum[2];
int AddSelected[2];
int Clear[2];
int Crop[2];
int MvSongUp[2];
int MvSongDown[2];
int MoveTo[2];
int MoveBefore[2];
int MoveAfter[2];
int Add[2];
int SavePlaylist[2];
int GoToNowPlaying[2];
int GoToContainingDir[2];
int GoToMediaLibrary[2];
int GoToTagEditor[2];
int ToggleAutoCenter[2];
int ToggleDisplayMode[2];
int ToggleInterface[2];
int ToggleSeparatorsInPlaylist[2];
int ToggleLyricsDB[2];
int ToggleFetchingLyricsInBackground[2];
int ToggleScreenLock[2];
int GoToParentDir[2];
int SwitchTagTypeList[2];
int Quit[2];
std::multimap<int, Action *> Bindings;
};
struct NcmpcppConfig
@@ -214,7 +129,6 @@ struct NcmpcppConfig
bool enable_idle_notifications;
bool colors_enabled;
bool fancy_scrolling;
bool playlist_show_remaining_time;
bool playlist_shorten_total_times;
bool playlist_separate_albums;
@@ -239,7 +153,6 @@ struct NcmpcppConfig
bool fetch_lyrics_in_background;
bool local_browser_show_hidden_files;
bool search_in_db;
bool display_screens_numbers_on_start;
bool jump_to_now_playing_song_at_start;
bool clock_display_seconds;
bool display_volume_level;
@@ -300,7 +213,6 @@ extern NcmpcppKeys Key;
extern NcmpcppConfig Config;
void CreateDir(const std::string &dir);
void SetWindowsDimensions(size_t &header_height, size_t &footer_start_y, size_t &footer_height);
#endif

View File

@@ -48,11 +48,8 @@ using Global::Timer;
using Global::wHeader;
using Global::VolumeState;
bool Global::UpdateStatusImmediately = 0;
bool Global::RedrawStatusbar = 0;
std::string Global::VolumeState;
timeval Global::Timer;
namespace
@@ -137,8 +134,8 @@ void TraceMpdStatus()
{
static timeval past = { 0, 0 };
gettimeofday(&Global::Timer, 0);
if (Mpd.Connected() && (Mpd.SupportsIdle() || Timer.tv_sec > past.tv_sec || Global::UpdateStatusImmediately))
gettimeofday(&Timer, 0);
if (Mpd.Connected() && (Mpd.SupportsIdle() || Timer.tv_sec > past.tv_sec))
{
if (!Mpd.SupportsIdle())
{
@@ -153,9 +150,6 @@ void TraceMpdStatus()
gettimeofday(&past, 0);
}
Mpd.UpdateStatus();
Global::BlockItemListUpdate = 0;
Playlist::BlockUpdate = 0;
Global::UpdateStatusImmediately = 0;
}
ApplyToVisibleWindows(&BasicScreen::Update);
@@ -227,50 +221,46 @@ void NcmpcppStatusChanged(MPD::Connection *, MPD::StatusChanges changed, void *)
int sx, sy;
wFooter->GetXY(sx, sy);
if (!Playlist::BlockNowPlayingUpdate)
myPlaylist->NowPlaying = Mpd.GetCurrentlyPlayingSongPos();
myPlaylist->NowPlaying = Mpd.GetCurrentlyPlayingSongPos();
if (changed.Playlist)
{
if (!Playlist::BlockUpdate)
if (!(np = Mpd.GetCurrentlyPlayingSong()).Empty())
WindowTitle(utf_to_locale_cpy(np.toString(Config.song_window_title_format)));
bool was_filtered = myPlaylist->Items->isFiltered();
myPlaylist->Items->ShowAll();
MPD::SongList list;
size_t playlist_length = Mpd.GetPlaylistLength();
if (playlist_length < myPlaylist->Items->Size())
myPlaylist->Items->ResizeList(playlist_length);
Mpd.GetPlaylistChanges(Mpd.GetOldPlaylistID(), list);
myPlaylist->Items->Reserve(playlist_length);
for (MPD::SongList::const_iterator it = list.begin(); it != list.end(); ++it)
{
if (!(np = Mpd.GetCurrentlyPlayingSong()).Empty())
WindowTitle(utf_to_locale_cpy(np.toString(Config.song_window_title_format)));
bool was_filtered = myPlaylist->Items->isFiltered();
myPlaylist->Items->ShowAll();
MPD::SongList list;
size_t playlist_length = Mpd.GetPlaylistLength();
if (playlist_length < myPlaylist->Items->Size())
myPlaylist->Items->ResizeList(playlist_length);
Mpd.GetPlaylistChanges(Mpd.GetOldPlaylistID(), list);
myPlaylist->Items->Reserve(playlist_length);
for (MPD::SongList::const_iterator it = list.begin(); it != list.end(); ++it)
int pos = (*it)->GetPosition();
if (pos < int(myPlaylist->Items->Size()))
{
int pos = (*it)->GetPosition();
if (pos < int(myPlaylist->Items->Size()))
{
// if song's already in playlist, replace it with a new one
myPlaylist->Items->at(pos) = **it;
}
else
{
// otherwise just add it to playlist
myPlaylist->Items->AddOption(**it);
}
myPlaylist->Items->at(pos).CopyPtr(0);
(*it)->NullMe();
// if song's already in playlist, replace it with a new one
myPlaylist->Items->at(pos) = **it;
}
if (was_filtered)
else
{
myPlaylist->ApplyFilter(myPlaylist->Items->GetFilter());
if (myPlaylist->Items->Empty())
myPlaylist->Items->ShowAll();
// otherwise just add it to playlist
myPlaylist->Items->AddOption(**it);
}
FreeSongList(list);
myPlaylist->Items->at(pos).CopyPtr(0);
(*it)->NullMe();
}
if (was_filtered)
{
myPlaylist->ApplyFilter(myPlaylist->Items->GetFilter());
if (myPlaylist->Items->Empty())
myPlaylist->Items->ShowAll();
}
FreeSongList(list);
Playlist::ReloadTotalLength = 1;
Playlist::ReloadRemaining = 1;
@@ -282,24 +272,21 @@ void NcmpcppStatusChanged(MPD::Connection *, MPD::StatusChanges changed, void *)
ShowMessage("Cleared playlist!");
}
if (!Global::BlockItemListUpdate)
if (isVisible(myBrowser))
{
if (isVisible(myBrowser))
{
myBrowser->UpdateItemList();
}
else if (isVisible(mySearcher))
{
mySearcher->UpdateFoundList();
}
else if (isVisible(myLibrary))
{
UpdateSongList(myLibrary->Songs);
}
else if (isVisible(myPlaylistEditor))
{
UpdateSongList(myPlaylistEditor->Content);
}
myBrowser->UpdateItemList();
}
else if (isVisible(mySearcher))
{
mySearcher->UpdateFoundList();
}
else if (isVisible(myLibrary))
{
UpdateSongList(myLibrary->Songs);
}
else if (isVisible(myPlaylistEditor))
{
UpdateSongList(myPlaylistEditor->Content);
}
}
if (changed.Database)

View File

@@ -530,18 +530,8 @@ void TagEditor::EnterPressed()
if (w == TagTypes && id == 5)
{
LockStatusbar();
Statusbar() << "Number tracks? [" << fmtBold << 'y' << fmtBoldEnd << '/' << fmtBold << 'n' << fmtBoldEnd << "] ";
wFooter->Refresh();
int in = 0;
do
{
TraceMpdStatus();
wFooter->ReadKey(in);
}
while (in != 'y' && in != 'n');
UnlockStatusbar();
if (in == 'y')
bool yes = Action::AskYesNoQuestion("Number tracks?", TraceMpdStatus);
if (yes)
{
MPD::SongList::iterator it = EditedSongs.begin();
for (unsigned i = 1; i <= EditedSongs.size(); ++i, ++it)
@@ -640,7 +630,7 @@ void TagEditor::EnterPressed()
ShowMessage("Writing tags in \"%s\"...", (*it)->GetName().c_str());
if (!WriteTags(**it))
{
static const char msg[] = "Error while writing tags in \"%s\"!";
const char msg[] = "Error while writing tags in \"%s\"!";
ShowMessage(msg, Shorten(TO_WSTRING((*it)->GetFile()), COLS-static_strlen(msg)).c_str());
success = 0;
break;
@@ -809,6 +799,25 @@ List *TagEditor::GetList()
return 0;
}
bool TagEditor::isNextColumnAvailable()
{
if (w == LeftColumn)
{
if (!TagTypes->ReallyEmpty() && !Tags->ReallyEmpty())
return true;
}
else if (w == TagTypes)
{
if (!Tags->ReallyEmpty())
return true;
}
else if (w == FParser)
{
return true;
}
return false;
}
bool TagEditor::NextColumn()
{
if (w == LeftColumn)
@@ -839,6 +848,25 @@ bool TagEditor::NextColumn()
return false;
}
bool TagEditor::isPrevColumnAvailable()
{
if (w == Tags)
{
if (!TagTypes->ReallyEmpty() && !LeftColumn->ReallyEmpty())
return true;
}
else if (w == TagTypes)
{
if (!LeftColumn->ReallyEmpty())
return true;
}
else if (w == FParserHelper)
{
return true;
}
return false;
}
bool TagEditor::PrevColumn()
{
if (w == Tags)

View File

@@ -68,7 +68,9 @@ class TagEditor : public Screen<Window>
virtual bool isMergable() { return true; }
bool isNextColumnAvailable();
bool NextColumn();
bool isPrevColumnAvailable();
bool PrevColumn();
void LocateSong(const MPD::Song &s);

View File

@@ -175,12 +175,9 @@ void TinyTagEditor::MouseButtonPressed(MEVENT me)
Screen< Menu<Buffer> >::MouseButtonPressed(me);
}
bool TinyTagEditor::SetEdited(MPD::Song *s)
void TinyTagEditor::SetEdited(const MPD::Song &s)
{
if (!s)
return false;
itsEdited = *s;
return true;
itsEdited = s;
}
bool TinyTagEditor::GetTags()

View File

@@ -50,7 +50,7 @@ class TinyTagEditor : public Screen< Menu<Buffer> >
virtual bool isMergable() { return true; }
bool SetEdited(MPD::Song *);
void SetEdited(const MPD::Song &);
protected:
virtual void Init();

View File

@@ -30,20 +30,13 @@
#endif
#include "curses.h"
#include "gcc.h"
#include <list>
#include <stack>
#include <vector>
#include <string>
#if defined(__GNUC__) && __GNUC__ >= 3
# define GNUC_UNUSED __attribute__((unused))
# define GNUC_PRINTF(a, b) __attribute__((format(printf, a, b)))
#else
# define GNUC_UNUSED
# define GNUC_PRINTF(a, b)
#endif
// define some Ctrl-? keys
#define KEY_CTRL_A 1
#define KEY_CTRL_B 2
@@ -72,6 +65,24 @@
#define KEY_CTRL_Y 25
#define KEY_CTRL_Z 26
// define F? keys
#define KEY_F1 265
#define KEY_F2 266
#define KEY_F3 267
#define KEY_F4 268
#define KEY_F5 269
#define KEY_F6 270
#define KEY_F7 271
#define KEY_F8 272
#define KEY_F9 273
#define KEY_F10 274
#define KEY_F11 275
#define KEY_F12 276
// other handy keys
#define KEY_TAB 9
#define KEY_SHIFT_TAB 353
// define alternative KEY_BACKSPACE (used in some terminal emulators)
#define KEY_BACKSPACE_2 127