remove enterPressed from remaining screens
This commit is contained in:
1
NEWS
1
NEWS
@@ -24,6 +24,7 @@ ncmpcpp-0.7 (????-??-??)
|
|||||||
* Support for Alt, Ctrl and Shift modifiers as well as Escape key was added.
|
* Support for Alt, Ctrl and Shift modifiers as well as Escape key was added.
|
||||||
* Action that updates the environment can now be used in bindings configuration file.
|
* Action that updates the environment can now be used in bindings configuration file.
|
||||||
* Monolithic 'press_space' action was split into 'add_item_to_playlist', 'toggle_lyrics_update_on_song_change' and 'toggle_visualization_type'.
|
* Monolithic 'press_space' action was split into 'add_item_to_playlist', 'toggle_lyrics_update_on_song_change' and 'toggle_visualization_type'.
|
||||||
|
* Monolithic 'press_enter' action was split into 'enter_directory', 'play_item', run_action' and 'toggle_output'.
|
||||||
* Sorting actions were rebound to Ctrl-S.
|
* Sorting actions were rebound to Ctrl-S.
|
||||||
* Support for range selection was added (bound to Ctrl-V by default). In addition, sorting, reversing and shuffling items in playlist now works on ranges.
|
* Support for range selection was added (bound to Ctrl-V by default). In addition, sorting, reversing and shuffling items in playlist now works on ranges.
|
||||||
* Support for selecting found items was added (bound to Ctrl-_ by default).
|
* Support for selecting found items was added (bound to Ctrl-_ by default).
|
||||||
|
|||||||
@@ -193,13 +193,16 @@
|
|||||||
# select_item
|
# select_item
|
||||||
#
|
#
|
||||||
#def_key "enter"
|
#def_key "enter"
|
||||||
# play
|
# enter_directory
|
||||||
#
|
#
|
||||||
#def_key "enter"
|
#def_key "enter"
|
||||||
# toggle_output
|
# toggle_output
|
||||||
#
|
#
|
||||||
#def_key "enter"
|
#def_key "enter"
|
||||||
# press_enter
|
# play_item
|
||||||
|
#
|
||||||
|
#def_key "enter"
|
||||||
|
# run_action
|
||||||
#
|
#
|
||||||
#def_key "space"
|
#def_key "space"
|
||||||
# add_item_to_playlist
|
# add_item_to_playlist
|
||||||
|
|||||||
@@ -502,7 +502,7 @@ void JumpToParentDirectory::run()
|
|||||||
if (!myBrowser->inRootDirectory())
|
if (!myBrowser->inRootDirectory())
|
||||||
{
|
{
|
||||||
myBrowser->main().reset();
|
myBrowser->main().reset();
|
||||||
myBrowser->enterPressed();
|
myBrowser->enterDirectory();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# ifdef HAVE_TAGLIB_H
|
# ifdef HAVE_TAGLIB_H
|
||||||
@@ -511,37 +511,46 @@ void JumpToParentDirectory::run()
|
|||||||
if (myTagEditor->CurrentDir() != "/")
|
if (myTagEditor->CurrentDir() != "/")
|
||||||
{
|
{
|
||||||
myTagEditor->Dirs->reset();
|
myTagEditor->Dirs->reset();
|
||||||
myTagEditor->enterPressed();
|
myTagEditor->enterDirectory();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# endif // HAVE_TAGLIB_H
|
# endif // HAVE_TAGLIB_H
|
||||||
}
|
}
|
||||||
|
|
||||||
void PressEnter::run()
|
bool RunAction::canBeRun()
|
||||||
{
|
{
|
||||||
myScreen->enterPressed();
|
m_ha = dynamic_cast<HasActions *>(myScreen);
|
||||||
|
return m_ha != nullptr
|
||||||
|
&& m_ha->actionRunnable();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RunAction::run()
|
||||||
|
{
|
||||||
|
m_ha->runAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PreviousColumn::canBeRun()
|
bool PreviousColumn::canBeRun()
|
||||||
{
|
{
|
||||||
auto hc = hasColumns(myScreen);
|
m_hc = dynamic_cast<HasColumns *>(myScreen);
|
||||||
return hc && hc->previousColumnAvailable();
|
return m_hc != nullptr
|
||||||
|
&& m_hc->previousColumnAvailable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreviousColumn::run()
|
void PreviousColumn::run()
|
||||||
{
|
{
|
||||||
hasColumns(myScreen)->previousColumn();
|
m_hc->previousColumn();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NextColumn::canBeRun()
|
bool NextColumn::canBeRun()
|
||||||
{
|
{
|
||||||
auto hc = hasColumns(myScreen);
|
m_hc = dynamic_cast<HasColumns *>(myScreen);
|
||||||
return hc && hc->nextColumnAvailable();
|
return m_hc != nullptr
|
||||||
|
&& m_hc->nextColumnAvailable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NextColumn::run()
|
void NextColumn::run()
|
||||||
{
|
{
|
||||||
hasColumns(myScreen)->nextColumn();
|
m_hc->nextColumn();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MasterScreen::canBeRun()
|
bool MasterScreen::canBeRun()
|
||||||
@@ -600,14 +609,13 @@ void VolumeDown::run()
|
|||||||
|
|
||||||
bool AddItemToPlaylist::canBeRun()
|
bool AddItemToPlaylist::canBeRun()
|
||||||
{
|
{
|
||||||
if (m_hs != static_cast<void *>(myScreen))
|
m_hs = dynamic_cast<HasSongs *>(myScreen);
|
||||||
m_hs = dynamic_cast<HasSongs *>(myScreen);
|
return m_hs != nullptr && m_hs->itemAvailable();
|
||||||
return m_hs != nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddItemToPlaylist::run()
|
void AddItemToPlaylist::run()
|
||||||
{
|
{
|
||||||
bool success = m_hs->addItemToPlaylist();
|
bool success = m_hs->addItemToPlaylist(false);
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
myScreen->scroll(NC::Scroll::Down);
|
myScreen->scroll(NC::Scroll::Down);
|
||||||
@@ -615,6 +623,19 @@ void AddItemToPlaylist::run()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PlayItem::canBeRun()
|
||||||
|
{
|
||||||
|
m_hs = dynamic_cast<HasSongs *>(myScreen);
|
||||||
|
return m_hs != nullptr && m_hs->itemAvailable();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayItem::run()
|
||||||
|
{
|
||||||
|
bool success = m_hs->addItemToPlaylist(true);
|
||||||
|
if (success)
|
||||||
|
listsChangeFinisher();
|
||||||
|
}
|
||||||
|
|
||||||
bool DeletePlaylistItems::canBeRun()
|
bool DeletePlaylistItems::canBeRun()
|
||||||
{
|
{
|
||||||
return (myScreen == myPlaylist && !myPlaylist->main().empty())
|
return (myScreen == myPlaylist && !myPlaylist->main().empty())
|
||||||
@@ -957,17 +978,6 @@ void Add::run()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Play::canBeRun()
|
|
||||||
{
|
|
||||||
return myScreen == myPlaylist
|
|
||||||
&& !myPlaylist->main().empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Play::run()
|
|
||||||
{
|
|
||||||
Mpd.PlayID(myPlaylist->main().current()->value().getID());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SeekForward::canBeRun()
|
bool SeekForward::canBeRun()
|
||||||
{
|
{
|
||||||
return Status::State::player() != MPD::psStop && Status::State::totalTime() > 0;
|
return Status::State::player() != MPD::psStop && Status::State::totalTime() > 0;
|
||||||
@@ -1226,7 +1236,7 @@ void StartSearching::run()
|
|||||||
mySearcher->main().setHighlighting(0);
|
mySearcher->main().setHighlighting(0);
|
||||||
mySearcher->main().refresh();
|
mySearcher->main().refresh();
|
||||||
mySearcher->main().setHighlighting(1);
|
mySearcher->main().setHighlighting(1);
|
||||||
mySearcher->enterPressed();
|
mySearcher->runAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SaveTagChanges::canBeRun()
|
bool SaveTagChanges::canBeRun()
|
||||||
@@ -1245,12 +1255,12 @@ void SaveTagChanges::run()
|
|||||||
if (myScreen == myTinyTagEditor)
|
if (myScreen == myTinyTagEditor)
|
||||||
{
|
{
|
||||||
myTinyTagEditor->main().highlight(myTinyTagEditor->main().size()-2); // Save
|
myTinyTagEditor->main().highlight(myTinyTagEditor->main().size()-2); // Save
|
||||||
myTinyTagEditor->enterPressed();
|
myTinyTagEditor->runAction();
|
||||||
}
|
}
|
||||||
else if (myScreen->activeWindow() == myTagEditor->TagTypes)
|
else if (myScreen->activeWindow() == myTagEditor->TagTypes)
|
||||||
{
|
{
|
||||||
myTagEditor->TagTypes->highlight(myTagEditor->TagTypes->size()-1); // Save
|
myTagEditor->TagTypes->highlight(myTagEditor->TagTypes->size()-1); // Save
|
||||||
myTagEditor->enterPressed();
|
myTagEditor->runAction();
|
||||||
}
|
}
|
||||||
# endif // HAVE_TAGLIB_H
|
# endif // HAVE_TAGLIB_H
|
||||||
}
|
}
|
||||||
@@ -1297,6 +1307,34 @@ void SetVolume::run()
|
|||||||
Statusbar::printf("Volume set to %1%%%", volume);
|
Statusbar::printf("Volume set to %1%%%", volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EnterDirectory::canBeRun()
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
if (myScreen == myBrowser && !myBrowser->main().empty())
|
||||||
|
{
|
||||||
|
result = myBrowser->main().current()->value().type()
|
||||||
|
== MPD::Item::Type::Directory;
|
||||||
|
}
|
||||||
|
#ifdef HAVE_TAGLIB_H
|
||||||
|
else if (myScreen->activeWindow() == myTagEditor->Dirs)
|
||||||
|
result = true;
|
||||||
|
#endif // HAVE_TAGLIB_H
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnterDirectory::run()
|
||||||
|
{
|
||||||
|
if (myScreen == myBrowser)
|
||||||
|
myBrowser->enterDirectory();
|
||||||
|
#ifdef HAVE_TAGLIB_H
|
||||||
|
else if (myScreen->activeWindow() == myTagEditor->Dirs)
|
||||||
|
{
|
||||||
|
if (!myTagEditor->enterDirectory())
|
||||||
|
Statusbar::print("No subdirectories found");
|
||||||
|
}
|
||||||
|
#endif // HAVE_TAGLIB_H
|
||||||
|
}
|
||||||
|
|
||||||
bool EditSong::canBeRun()
|
bool EditSong::canBeRun()
|
||||||
{
|
{
|
||||||
# ifdef HAVE_TAGLIB_H
|
# ifdef HAVE_TAGLIB_H
|
||||||
@@ -2603,7 +2641,7 @@ void populateActions()
|
|||||||
insert_action(new Actions::MoveEnd());
|
insert_action(new Actions::MoveEnd());
|
||||||
insert_action(new Actions::ToggleInterface());
|
insert_action(new Actions::ToggleInterface());
|
||||||
insert_action(new Actions::JumpToParentDirectory());
|
insert_action(new Actions::JumpToParentDirectory());
|
||||||
insert_action(new Actions::PressEnter());
|
insert_action(new Actions::RunAction());
|
||||||
insert_action(new Actions::SelectItem());
|
insert_action(new Actions::SelectItem());
|
||||||
insert_action(new Actions::SelectRange());
|
insert_action(new Actions::SelectRange());
|
||||||
insert_action(new Actions::PreviousColumn());
|
insert_action(new Actions::PreviousColumn());
|
||||||
@@ -2629,7 +2667,7 @@ void populateActions()
|
|||||||
insert_action(new Actions::MoveSelectedItemsDown());
|
insert_action(new Actions::MoveSelectedItemsDown());
|
||||||
insert_action(new Actions::MoveSelectedItemsTo());
|
insert_action(new Actions::MoveSelectedItemsTo());
|
||||||
insert_action(new Actions::Add());
|
insert_action(new Actions::Add());
|
||||||
insert_action(new Actions::Play());
|
insert_action(new Actions::PlayItem());
|
||||||
insert_action(new Actions::SeekForward());
|
insert_action(new Actions::SeekForward());
|
||||||
insert_action(new Actions::SeekBackward());
|
insert_action(new Actions::SeekBackward());
|
||||||
insert_action(new Actions::ToggleDisplayMode());
|
insert_action(new Actions::ToggleDisplayMode());
|
||||||
@@ -2650,6 +2688,7 @@ void populateActions()
|
|||||||
insert_action(new Actions::ToggleCrossfade());
|
insert_action(new Actions::ToggleCrossfade());
|
||||||
insert_action(new Actions::SetCrossfade());
|
insert_action(new Actions::SetCrossfade());
|
||||||
insert_action(new Actions::SetVolume());
|
insert_action(new Actions::SetVolume());
|
||||||
|
insert_action(new Actions::EnterDirectory());
|
||||||
insert_action(new Actions::EditSong());
|
insert_action(new Actions::EditSong());
|
||||||
insert_action(new Actions::EditLibraryTag());
|
insert_action(new Actions::EditLibraryTag());
|
||||||
insert_action(new Actions::EditLibraryAlbum());
|
insert_action(new Actions::EditLibraryAlbum());
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
#include "interfaces.h"
|
#include "interfaces.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
|
||||||
|
// forward declarations
|
||||||
struct SongList;
|
struct SongList;
|
||||||
|
|
||||||
namespace Actions {
|
namespace Actions {
|
||||||
@@ -37,16 +38,16 @@ enum class Type
|
|||||||
MacroUtility = 0,
|
MacroUtility = 0,
|
||||||
Dummy, UpdateEnvironment, MouseEvent, ScrollUp, ScrollDown, ScrollUpArtist, ScrollUpAlbum,
|
Dummy, UpdateEnvironment, MouseEvent, ScrollUp, ScrollDown, ScrollUpArtist, ScrollUpAlbum,
|
||||||
ScrollDownArtist, ScrollDownAlbum, PageUp, PageDown, MoveHome, MoveEnd,
|
ScrollDownArtist, ScrollDownAlbum, PageUp, PageDown, MoveHome, MoveEnd,
|
||||||
ToggleInterface, JumpToParentDirectory, PressEnter, PreviousColumn,
|
ToggleInterface, JumpToParentDirectory, RunAction, PreviousColumn,
|
||||||
NextColumn, MasterScreen, SlaveScreen, VolumeUp, VolumeDown, AddItemToPlaylist,
|
NextColumn, MasterScreen, SlaveScreen, VolumeUp, VolumeDown, AddItemToPlaylist, PlayItem,
|
||||||
DeletePlaylistItems, DeleteStoredPlaylist, DeleteBrowserItems, ReplaySong, Previous,
|
DeletePlaylistItems, DeleteStoredPlaylist, DeleteBrowserItems, ReplaySong, Previous,
|
||||||
Next, Pause, Stop, ExecuteCommand, SavePlaylist, MoveSortOrderUp, MoveSortOrderDown,
|
Next, Pause, Stop, ExecuteCommand, SavePlaylist, MoveSortOrderUp, MoveSortOrderDown,
|
||||||
MoveSelectedItemsUp, MoveSelectedItemsDown, MoveSelectedItemsTo, Add, Play,
|
MoveSelectedItemsUp, MoveSelectedItemsDown, MoveSelectedItemsTo, Add,
|
||||||
SeekForward, SeekBackward, ToggleDisplayMode, ToggleSeparatorsBetweenAlbums,
|
SeekForward, SeekBackward, ToggleDisplayMode, ToggleSeparatorsBetweenAlbums,
|
||||||
ToggleLyricsUpdateOnSongChange, ToggleLyricsFetcher, ToggleFetchingLyricsInBackground,
|
ToggleLyricsUpdateOnSongChange, ToggleLyricsFetcher, ToggleFetchingLyricsInBackground,
|
||||||
TogglePlayingSongCentering, UpdateDatabase, JumpToPlayingSong, ToggleRepeat, Shuffle,
|
TogglePlayingSongCentering, UpdateDatabase, JumpToPlayingSong, ToggleRepeat, Shuffle,
|
||||||
ToggleRandom, StartSearching, SaveTagChanges, ToggleSingle, ToggleConsume, ToggleCrossfade,
|
ToggleRandom, StartSearching, SaveTagChanges, ToggleSingle, ToggleConsume, ToggleCrossfade,
|
||||||
SetCrossfade, SetVolume, EditSong, EditLibraryTag, EditLibraryAlbum, EditDirectoryName,
|
SetCrossfade, SetVolume, EnterDirectory, EditSong, EditLibraryTag, EditLibraryAlbum, EditDirectoryName,
|
||||||
EditPlaylistName, EditLyrics, JumpToBrowser, JumpToMediaLibrary,
|
EditPlaylistName, EditLyrics, JumpToBrowser, JumpToMediaLibrary,
|
||||||
JumpToPlaylistEditor, ToggleScreenLock, JumpToTagEditor, JumpToPositionInSong,
|
JumpToPlaylistEditor, ToggleScreenLock, JumpToTagEditor, JumpToPositionInSong,
|
||||||
SelectItem, SelectRange, ReverseSelection, RemoveSelection, SelectAlbum, SelectFoundItems,
|
SelectItem, SelectRange, ReverseSelection, RemoveSelection, SelectAlbum, SelectFoundItems,
|
||||||
@@ -266,12 +267,15 @@ private:
|
|||||||
virtual void run() OVERRIDE;
|
virtual void run() OVERRIDE;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PressEnter: BaseAction
|
struct RunAction: BaseAction
|
||||||
{
|
{
|
||||||
PressEnter(): BaseAction(Type::PressEnter, "press_enter") { }
|
RunAction(): BaseAction(Type::RunAction, "run_action") { }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
virtual bool canBeRun() OVERRIDE;
|
||||||
virtual void run() OVERRIDE;
|
virtual void run() OVERRIDE;
|
||||||
|
|
||||||
|
HasActions *m_ha;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PreviousColumn: BaseAction
|
struct PreviousColumn: BaseAction
|
||||||
@@ -281,6 +285,8 @@ struct PreviousColumn: BaseAction
|
|||||||
private:
|
private:
|
||||||
virtual bool canBeRun() OVERRIDE;
|
virtual bool canBeRun() OVERRIDE;
|
||||||
virtual void run() OVERRIDE;
|
virtual void run() OVERRIDE;
|
||||||
|
|
||||||
|
HasColumns *m_hc;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NextColumn: BaseAction
|
struct NextColumn: BaseAction
|
||||||
@@ -290,6 +296,8 @@ struct NextColumn: BaseAction
|
|||||||
private:
|
private:
|
||||||
virtual bool canBeRun() OVERRIDE;
|
virtual bool canBeRun() OVERRIDE;
|
||||||
virtual void run() OVERRIDE;
|
virtual void run() OVERRIDE;
|
||||||
|
|
||||||
|
HasColumns *m_hc;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MasterScreen: BaseAction
|
struct MasterScreen: BaseAction
|
||||||
@@ -337,6 +345,17 @@ private:
|
|||||||
HasSongs *m_hs;
|
HasSongs *m_hs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PlayItem: BaseAction
|
||||||
|
{
|
||||||
|
PlayItem(): BaseAction(Type::PlayItem, "play_item") { }
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual bool canBeRun() OVERRIDE;
|
||||||
|
virtual void run() OVERRIDE;
|
||||||
|
|
||||||
|
HasSongs *m_hs;
|
||||||
|
};
|
||||||
|
|
||||||
struct DeletePlaylistItems: BaseAction
|
struct DeletePlaylistItems: BaseAction
|
||||||
{
|
{
|
||||||
DeletePlaylistItems(): BaseAction(Type::DeletePlaylistItems, "delete_playlist_items") { }
|
DeletePlaylistItems(): BaseAction(Type::DeletePlaylistItems, "delete_playlist_items") { }
|
||||||
@@ -474,15 +493,6 @@ private:
|
|||||||
virtual void run() OVERRIDE;
|
virtual void run() OVERRIDE;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Play: BaseAction
|
|
||||||
{
|
|
||||||
Play(): BaseAction(Type::Play, "play") { }
|
|
||||||
|
|
||||||
private:
|
|
||||||
virtual bool canBeRun() OVERRIDE;
|
|
||||||
virtual void run() OVERRIDE;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SeekForward: BaseAction
|
struct SeekForward: BaseAction
|
||||||
{
|
{
|
||||||
SeekForward(): BaseAction(Type::SeekForward, "seek_forward") { }
|
SeekForward(): BaseAction(Type::SeekForward, "seek_forward") { }
|
||||||
@@ -665,6 +675,16 @@ private:
|
|||||||
virtual void run() OVERRIDE;
|
virtual void run() OVERRIDE;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct EnterDirectory: BaseAction
|
||||||
|
{
|
||||||
|
EnterDirectory(): BaseAction(Type::EnterDirectory, "enter_directory") { }
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual bool canBeRun() OVERRIDE;
|
||||||
|
virtual void run() OVERRIDE;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct EditSong: BaseAction
|
struct EditSong: BaseAction
|
||||||
{
|
{
|
||||||
EditSong(): BaseAction(Type::EditSong, "edit_song") { }
|
EditSong(): BaseAction(Type::EditSong, "edit_song") { }
|
||||||
|
|||||||
@@ -497,9 +497,10 @@ void BindingsConfiguration::generateDefaults()
|
|||||||
bind(k, Actions::Type::SelectItem);
|
bind(k, Actions::Type::SelectItem);
|
||||||
if (notBound(k = stringToKey("enter")))
|
if (notBound(k = stringToKey("enter")))
|
||||||
{
|
{
|
||||||
bind(k, Actions::Type::Play);
|
bind(k, Actions::Type::EnterDirectory);
|
||||||
bind(k, Actions::Type::ToggleOutput);
|
bind(k, Actions::Type::ToggleOutput);
|
||||||
bind(k, Actions::Type::PressEnter);
|
bind(k, Actions::Type::PlayItem);
|
||||||
|
bind(k, Actions::Type::RunAction);
|
||||||
}
|
}
|
||||||
if (notBound(k = stringToKey("space")))
|
if (notBound(k = stringToKey("space")))
|
||||||
{
|
{
|
||||||
|
|||||||
109
src/browser.cpp
109
src/browser.cpp
@@ -209,40 +209,6 @@ void Browser::update()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Browser::enterPressed()
|
|
||||||
{
|
|
||||||
if (w.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
const MPD::Item &item = w.current()->value();
|
|
||||||
switch (item.type())
|
|
||||||
{
|
|
||||||
case MPD::Item::Type::Directory:
|
|
||||||
{
|
|
||||||
getDirectory(item.directory().path());
|
|
||||||
drawHeader();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MPD::Item::Type::Song:
|
|
||||||
{
|
|
||||||
addSongToPlaylist(item.song(), true, -1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MPD::Item::Type::Playlist:
|
|
||||||
{
|
|
||||||
std::vector<MPD::Song> list(
|
|
||||||
std::make_move_iterator(Mpd.GetPlaylistContentNoInfo(item.playlist().path())),
|
|
||||||
std::make_move_iterator(MPD::SongIterator())
|
|
||||||
);
|
|
||||||
// TODO: ask on failure if we want to continue
|
|
||||||
bool success = addSongsToPlaylist(list.begin(), list.end(), true, -1);
|
|
||||||
Statusbar::printf("Playlist \"%1%\" loaded%2%",
|
|
||||||
item.playlist().path(), withErrors(success)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Browser::mouseButtonPressed(MEVENT me)
|
void Browser::mouseButtonPressed(MEVENT me)
|
||||||
{
|
{
|
||||||
if (w.empty() || !w.hasCoords(me.x, me.y) || size_t(me.y) >= w.size())
|
if (w.empty() || !w.hasCoords(me.x, me.y) || size_t(me.y) >= w.size())
|
||||||
@@ -254,20 +220,17 @@ void Browser::mouseButtonPressed(MEVENT me)
|
|||||||
{
|
{
|
||||||
case MPD::Item::Type::Directory:
|
case MPD::Item::Type::Directory:
|
||||||
if (me.bstate & BUTTON1_PRESSED)
|
if (me.bstate & BUTTON1_PRESSED)
|
||||||
{
|
enterDirectory();
|
||||||
getDirectory(w.current()->value().directory().path());
|
|
||||||
drawHeader();
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
addItemToPlaylist();
|
addItemToPlaylist(false);
|
||||||
break;
|
break;
|
||||||
case MPD::Item::Type::Playlist:
|
case MPD::Item::Type::Playlist:
|
||||||
case MPD::Item::Type::Song:
|
case MPD::Item::Type::Song:
|
||||||
if (me.bstate & BUTTON1_PRESSED)
|
{
|
||||||
addItemToPlaylist();
|
bool play = me.bstate & BUTTON3_PRESSED;
|
||||||
else
|
addItemToPlaylist(play);
|
||||||
enterPressed();
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -301,17 +264,36 @@ bool Browser::find(SearchDirection direction, bool wrap, bool skip_current)
|
|||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
|
||||||
bool Browser::addItemToPlaylist()
|
bool Browser::itemAvailable()
|
||||||
|
{
|
||||||
|
return !w.empty()
|
||||||
|
// ignore parent directory
|
||||||
|
&& !isParentDirectory(w.current()->value());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Browser::addItemToPlaylist(bool play)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
if (w.empty())
|
|
||||||
return result;
|
auto tryToPlay = [] {
|
||||||
|
// Cheap trick that might fail in presence of multiple
|
||||||
|
// clients modifying the playlist at the same time, but
|
||||||
|
// oh well, this approach correctly loads cue playlists
|
||||||
|
// and is much faster in general as it doesn't require
|
||||||
|
// fetching song data.
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Mpd.Play(Status::State::playlistLength());
|
||||||
|
}
|
||||||
|
catch (MPD::ServerError &e)
|
||||||
|
{
|
||||||
|
// If not bad index, rethrow.
|
||||||
|
if (e.code() != MPD_SERVER_ERROR_ARG)
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const MPD::Item &item = w.current()->value();
|
const MPD::Item &item = w.current()->value();
|
||||||
// ignore parent directory
|
|
||||||
if (isParentDirectory(item))
|
|
||||||
return result;
|
|
||||||
|
|
||||||
switch (item.type())
|
switch (item.type())
|
||||||
{
|
{
|
||||||
case MPD::Item::Type::Directory:
|
case MPD::Item::Type::Directory:
|
||||||
@@ -320,23 +302,26 @@ bool Browser::addItemToPlaylist()
|
|||||||
{
|
{
|
||||||
std::vector<MPD::Song> songs;
|
std::vector<MPD::Song> songs;
|
||||||
getLocalDirectoryRecursively(songs, item.directory().path());
|
getLocalDirectoryRecursively(songs, item.directory().path());
|
||||||
result = addSongsToPlaylist(songs.begin(), songs.end(), false, -1);
|
result = addSongsToPlaylist(songs.begin(), songs.end(), play, -1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Mpd.Add(item.directory().path());
|
Mpd.Add(item.directory().path());
|
||||||
|
if (play)
|
||||||
|
tryToPlay();
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
Statusbar::printf("Directory \"%1%\" added%2%",
|
Statusbar::printf("Directory \"%1%\" added%2%",
|
||||||
item.directory().path(), withErrors(result)
|
item.directory().path(), withErrors(result));
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MPD::Item::Type::Song:
|
case MPD::Item::Type::Song:
|
||||||
result = addSongToPlaylist(item.song(), false);
|
result = addSongToPlaylist(item.song(), play);
|
||||||
break;
|
break;
|
||||||
case MPD::Item::Type::Playlist:
|
case MPD::Item::Type::Playlist:
|
||||||
Mpd.LoadPlaylist(item.playlist().path());
|
Mpd.LoadPlaylist(item.playlist().path());
|
||||||
|
if (play)
|
||||||
|
tryToPlay();
|
||||||
Statusbar::printf("Playlist \"%1%\" loaded", item.playlist().path());
|
Statusbar::printf("Playlist \"%1%\" loaded", item.playlist().path());
|
||||||
result = true;
|
result = true;
|
||||||
break;
|
break;
|
||||||
@@ -424,6 +409,22 @@ void Browser::locateSong(const MPD::Song &s)
|
|||||||
w.highlight(it-begin);
|
w.highlight(it-begin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Browser::enterDirectory()
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
if (!w.empty())
|
||||||
|
{
|
||||||
|
const auto &item = w.current()->value();
|
||||||
|
if (item.type() == MPD::Item::Type::Directory)
|
||||||
|
{
|
||||||
|
getDirectory(item.directory().path());
|
||||||
|
drawHeader();
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void Browser::getDirectory(std::string directory)
|
void Browser::getDirectory(std::string directory)
|
||||||
{
|
{
|
||||||
m_scroll_beginning = 0;
|
m_scroll_beginning = 0;
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ struct Browser: Screen<BrowserWindow>, HasSongs, Searchable, Tabbable
|
|||||||
|
|
||||||
virtual void update() OVERRIDE;
|
virtual void update() OVERRIDE;
|
||||||
|
|
||||||
virtual void enterPressed() OVERRIDE;
|
|
||||||
virtual void mouseButtonPressed(MEVENT me) OVERRIDE;
|
virtual void mouseButtonPressed(MEVENT me) OVERRIDE;
|
||||||
|
|
||||||
virtual bool isLockable() OVERRIDE { return true; }
|
virtual bool isLockable() OVERRIDE { return true; }
|
||||||
@@ -69,7 +68,8 @@ struct Browser: Screen<BrowserWindow>, HasSongs, Searchable, Tabbable
|
|||||||
virtual bool find(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
|
virtual bool find(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
|
||||||
|
|
||||||
// HasSongs implementation
|
// HasSongs implementation
|
||||||
virtual bool addItemToPlaylist() OVERRIDE;
|
virtual bool itemAvailable() OVERRIDE;
|
||||||
|
virtual bool addItemToPlaylist(bool play) OVERRIDE;
|
||||||
virtual std::vector<MPD::Song> getSelectedSongs() OVERRIDE;
|
virtual std::vector<MPD::Song> getSelectedSongs() OVERRIDE;
|
||||||
|
|
||||||
// private members
|
// private members
|
||||||
@@ -81,6 +81,7 @@ struct Browser: Screen<BrowserWindow>, HasSongs, Searchable, Tabbable
|
|||||||
|
|
||||||
bool isLocal() { return m_local_browser; }
|
bool isLocal() { return m_local_browser; }
|
||||||
void locateSong(const MPD::Song &s);
|
void locateSong(const MPD::Song &s);
|
||||||
|
bool enterDirectory();
|
||||||
void getDirectory(std::string directory);
|
void getDirectory(std::string directory);
|
||||||
void changeBrowseMode();
|
void changeBrowseMode();
|
||||||
void remove(const MPD::Item &item);
|
void remove(const MPD::Item &item);
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ struct Clock: Screen<NC::Window>, Tabbable
|
|||||||
virtual void update() OVERRIDE;
|
virtual void update() OVERRIDE;
|
||||||
virtual void scroll(NC::Scroll) OVERRIDE { }
|
virtual void scroll(NC::Scroll) OVERRIDE { }
|
||||||
|
|
||||||
virtual void enterPressed() OVERRIDE { }
|
|
||||||
virtual void mouseButtonPressed(MEVENT) OVERRIDE { }
|
virtual void mouseButtonPressed(MEVENT) OVERRIDE { }
|
||||||
|
|
||||||
virtual bool isLockable() OVERRIDE { return false; }
|
virtual bool isLockable() OVERRIDE { return false; }
|
||||||
|
|||||||
19
src/help.cpp
19
src/help.cpp
@@ -238,7 +238,7 @@ void write_bindings(NC::Scrollpad &w)
|
|||||||
key(w, Type::Quit, "Quit");
|
key(w, Type::Quit, "Quit");
|
||||||
|
|
||||||
key_section(w, "Playlist");
|
key_section(w, "Playlist");
|
||||||
key(w, Type::Play, "Play selected item");
|
key(w, Type::PlayItem, "Play selected item");
|
||||||
key(w, Type::DeletePlaylistItems, "Delete selected item(s) from playlist");
|
key(w, Type::DeletePlaylistItems, "Delete selected item(s) from playlist");
|
||||||
key(w, Type::ClearMainPlaylist, "Clear playlist");
|
key(w, Type::ClearMainPlaylist, "Clear playlist");
|
||||||
key(w, Type::CropMainPlaylist, "Clear playlist except selected item(s)");
|
key(w, Type::CropMainPlaylist, "Clear playlist except selected item(s)");
|
||||||
@@ -258,7 +258,8 @@ void write_bindings(NC::Scrollpad &w)
|
|||||||
key(w, Type::TogglePlayingSongCentering, "Toggle playing song centering");
|
key(w, Type::TogglePlayingSongCentering, "Toggle playing song centering");
|
||||||
|
|
||||||
key_section(w, "Browser");
|
key_section(w, "Browser");
|
||||||
key(w, Type::PressEnter, "Enter directory/Add item to playlist and play it");
|
key(w, Type::EnterDirectory, "Enter directory");
|
||||||
|
key(w, Type::PlayItem, "Add item to playlist and play it");
|
||||||
key(w, Type::AddItemToPlaylist, "Add item to playlist");
|
key(w, Type::AddItemToPlaylist, "Add item to playlist");
|
||||||
# ifdef HAVE_TAGLIB_H
|
# ifdef HAVE_TAGLIB_H
|
||||||
key(w, Type::EditSong, "Edit song");
|
key(w, Type::EditSong, "Edit song");
|
||||||
@@ -273,8 +274,9 @@ void write_bindings(NC::Scrollpad &w)
|
|||||||
key(w, Type::JumpToPlaylistEditor, "Jump to playlist editor (playlists only)");
|
key(w, Type::JumpToPlaylistEditor, "Jump to playlist editor (playlists only)");
|
||||||
|
|
||||||
key_section(w, "Search engine");
|
key_section(w, "Search engine");
|
||||||
key(w, Type::PressEnter, "Add item to playlist and play it/change option");
|
key(w, Type::RunAction, "Modify option / Run action");
|
||||||
key(w, Type::AddItemToPlaylist, "Add item to playlist");
|
key(w, Type::AddItemToPlaylist, "Add item to playlist");
|
||||||
|
key(w, Type::PlayItem, "Add item to playlist and play it");
|
||||||
# ifdef HAVE_TAGLIB_H
|
# ifdef HAVE_TAGLIB_H
|
||||||
key(w, Type::EditSong, "Edit song");
|
key(w, Type::EditSong, "Edit song");
|
||||||
# endif // HAVE_TAGLIB_H
|
# endif // HAVE_TAGLIB_H
|
||||||
@@ -285,7 +287,7 @@ void write_bindings(NC::Scrollpad &w)
|
|||||||
key(w, Type::ToggleMediaLibraryColumnsMode, "Switch between two/three columns mode");
|
key(w, Type::ToggleMediaLibraryColumnsMode, "Switch between two/three columns mode");
|
||||||
key(w, Type::PreviousColumn, "Previous column");
|
key(w, Type::PreviousColumn, "Previous column");
|
||||||
key(w, Type::NextColumn, "Next column");
|
key(w, Type::NextColumn, "Next column");
|
||||||
key(w, Type::PressEnter, "Add item to playlist and play it");
|
key(w, Type::PlayItem, "Add item to playlist and play it");
|
||||||
key(w, Type::AddItemToPlaylist, "Add item to playlist");
|
key(w, Type::AddItemToPlaylist, "Add item to playlist");
|
||||||
# ifdef HAVE_TAGLIB_H
|
# ifdef HAVE_TAGLIB_H
|
||||||
key(w, Type::EditSong, "Edit song");
|
key(w, Type::EditSong, "Edit song");
|
||||||
@@ -297,7 +299,7 @@ void write_bindings(NC::Scrollpad &w)
|
|||||||
key_section(w, "Playlist editor");
|
key_section(w, "Playlist editor");
|
||||||
key(w, Type::PreviousColumn, "Previous column");
|
key(w, Type::PreviousColumn, "Previous column");
|
||||||
key(w, Type::NextColumn, "Next column");
|
key(w, Type::NextColumn, "Next column");
|
||||||
key(w, Type::PressEnter, "Add item to playlist and play it");
|
key(w, Type::PlayItem, "Add item to playlist and play it");
|
||||||
key(w, Type::AddItemToPlaylist, "Add item to playlist");
|
key(w, Type::AddItemToPlaylist, "Add item to playlist");
|
||||||
# ifdef HAVE_TAGLIB_H
|
# ifdef HAVE_TAGLIB_H
|
||||||
key(w, Type::EditSong, "Edit song");
|
key(w, Type::EditSong, "Edit song");
|
||||||
@@ -317,12 +319,13 @@ void write_bindings(NC::Scrollpad &w)
|
|||||||
|
|
||||||
# ifdef HAVE_TAGLIB_H
|
# ifdef HAVE_TAGLIB_H
|
||||||
key_section(w, "Tiny tag editor");
|
key_section(w, "Tiny tag editor");
|
||||||
key(w, Type::PressEnter, "Edit tag");
|
key(w, Type::RunAction, "Edit tag / Run action");
|
||||||
key(w, Type::SaveTagChanges, "Save");
|
key(w, Type::SaveTagChanges, "Save");
|
||||||
|
|
||||||
key_section(w, "Tag editor");
|
key_section(w, "Tag editor");
|
||||||
key(w, Type::PressEnter, "Edit tag/filename of selected item (left column)");
|
key(w, Type::EnterDirectory, "Enter directory (right column)");
|
||||||
key(w, Type::PressEnter, "Perform operation on all/selected items (middle column)");
|
key(w, Type::RunAction, "Perform operation on selected items (middle column)");
|
||||||
|
key(w, Type::RunAction, "Edit item (left column)");
|
||||||
key(w, Type::PreviousColumn, "Previous column");
|
key(w, Type::PreviousColumn, "Previous column");
|
||||||
key(w, Type::NextColumn, "Next column");
|
key(w, Type::NextColumn, "Next column");
|
||||||
key(w, Type::JumpToParentDirectory, "Jump to parent directory (left column, directories view)");
|
key(w, Type::JumpToParentDirectory, "Jump to parent directory (left column, directories view)");
|
||||||
|
|||||||
@@ -37,8 +37,6 @@ struct Help: Screen<NC::Scrollpad>, Tabbable
|
|||||||
|
|
||||||
virtual void update() OVERRIDE { }
|
virtual void update() OVERRIDE { }
|
||||||
|
|
||||||
virtual void enterPressed() OVERRIDE { }
|
|
||||||
|
|
||||||
virtual bool isLockable() OVERRIDE { return true; }
|
virtual bool isLockable() OVERRIDE { return true; }
|
||||||
virtual bool isMergable() OVERRIDE { return true; }
|
virtual bool isMergable() OVERRIDE { return true; }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -84,16 +84,6 @@ bool search(NC::Menu<ItemT> &m, const PredicateT &pred,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline HasColumns *hasColumns(BaseScreen *screen)
|
|
||||||
{
|
|
||||||
return dynamic_cast<HasColumns *>(screen);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline HasSongs *hasSongs(BaseScreen *screen)
|
|
||||||
{
|
|
||||||
return dynamic_cast<HasSongs *>(screen);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Iterator>
|
template <typename Iterator>
|
||||||
bool hasSelected(Iterator first, Iterator last)
|
bool hasSelected(Iterator first, Iterator last)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -37,9 +37,16 @@ struct Searchable
|
|||||||
virtual bool find(SearchDirection direction, bool wrap, bool skip_current) = 0;
|
virtual bool find(SearchDirection direction, bool wrap, bool skip_current) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct HasActions
|
||||||
|
{
|
||||||
|
virtual bool actionRunnable() = 0;
|
||||||
|
virtual void runAction() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
struct HasSongs
|
struct HasSongs
|
||||||
{
|
{
|
||||||
virtual bool addItemToPlaylist() = 0;
|
virtual bool itemAvailable() = 0;
|
||||||
|
virtual bool addItemToPlaylist(bool play) = 0;
|
||||||
virtual std::vector<MPD::Song> getSelectedSongs() = 0;
|
virtual std::vector<MPD::Song> getSelectedSongs() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -45,8 +45,6 @@ struct Lastfm: Screen<NC::Scrollpad>, Tabbable
|
|||||||
|
|
||||||
virtual void update() OVERRIDE;
|
virtual void update() OVERRIDE;
|
||||||
|
|
||||||
virtual void enterPressed() OVERRIDE { }
|
|
||||||
|
|
||||||
virtual bool isLockable() OVERRIDE { return false; }
|
virtual bool isLockable() OVERRIDE { return false; }
|
||||||
virtual bool isMergable() OVERRIDE { return true; }
|
virtual bool isMergable() OVERRIDE { return true; }
|
||||||
|
|
||||||
|
|||||||
@@ -42,8 +42,6 @@ struct Lyrics: Screen<NC::Scrollpad>, Tabbable
|
|||||||
|
|
||||||
virtual void update() OVERRIDE;
|
virtual void update() OVERRIDE;
|
||||||
|
|
||||||
virtual void enterPressed() OVERRIDE { }
|
|
||||||
|
|
||||||
virtual bool isLockable() OVERRIDE { return false; }
|
virtual bool isLockable() OVERRIDE { return false; }
|
||||||
virtual bool isMergable() OVERRIDE { return true; }
|
virtual bool isMergable() OVERRIDE { return true; }
|
||||||
|
|
||||||
|
|||||||
@@ -455,11 +455,6 @@ int MediaLibrary::windowTimeout()
|
|||||||
return Screen<WindowType>::windowTimeout();
|
return Screen<WindowType>::windowTimeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaLibrary::enterPressed()
|
|
||||||
{
|
|
||||||
addItemToPlaylist(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MediaLibrary::mouseButtonPressed(MEVENT me)
|
void MediaLibrary::mouseButtonPressed(MEVENT me)
|
||||||
{
|
{
|
||||||
auto tryNextColumn = [this]() -> bool {
|
auto tryNextColumn = [this]() -> bool {
|
||||||
@@ -492,7 +487,7 @@ void MediaLibrary::mouseButtonPressed(MEVENT me)
|
|||||||
{
|
{
|
||||||
Tags.Goto(me.y);
|
Tags.Goto(me.y);
|
||||||
if (me.bstate & BUTTON3_PRESSED)
|
if (me.bstate & BUTTON3_PRESSED)
|
||||||
addItemToPlaylist();
|
addItemToPlaylist(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Screen<WindowType>::mouseButtonPressed(me);
|
Screen<WindowType>::mouseButtonPressed(me);
|
||||||
@@ -515,7 +510,7 @@ void MediaLibrary::mouseButtonPressed(MEVENT me)
|
|||||||
{
|
{
|
||||||
Albums.Goto(me.y);
|
Albums.Goto(me.y);
|
||||||
if (me.bstate & BUTTON3_PRESSED)
|
if (me.bstate & BUTTON3_PRESSED)
|
||||||
addItemToPlaylist();
|
addItemToPlaylist(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Screen<WindowType>::mouseButtonPressed(me);
|
Screen<WindowType>::mouseButtonPressed(me);
|
||||||
@@ -528,10 +523,8 @@ void MediaLibrary::mouseButtonPressed(MEVENT me)
|
|||||||
if (size_t(me.y) < Songs.size() && (me.bstate & (BUTTON1_PRESSED | BUTTON3_PRESSED)))
|
if (size_t(me.y) < Songs.size() && (me.bstate & (BUTTON1_PRESSED | BUTTON3_PRESSED)))
|
||||||
{
|
{
|
||||||
Songs.Goto(me.y);
|
Songs.Goto(me.y);
|
||||||
if (me.bstate & BUTTON1_PRESSED)
|
bool play = me.bstate & BUTTON3_PRESSED;
|
||||||
addItemToPlaylist();
|
addItemToPlaylist(play);
|
||||||
else
|
|
||||||
enterPressed();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Screen<WindowType>::mouseButtonPressed(me);
|
Screen<WindowType>::mouseButtonPressed(me);
|
||||||
@@ -594,9 +587,53 @@ bool MediaLibrary::find(SearchDirection direction, bool wrap, bool skip_current)
|
|||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
|
||||||
bool MediaLibrary::addItemToPlaylist()
|
bool MediaLibrary::itemAvailable()
|
||||||
{
|
{
|
||||||
return addItemToPlaylist(false);
|
if (isActiveWindow(Tags))
|
||||||
|
return !Tags.empty();
|
||||||
|
if (isActiveWindow(Albums))
|
||||||
|
return !Albums.empty();
|
||||||
|
if (isActiveWindow(Songs))
|
||||||
|
return !Songs.empty();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MediaLibrary::addItemToPlaylist(bool play)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
if (isActiveWindow(Songs))
|
||||||
|
result = addSongToPlaylist(Songs.current()->value(), play);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (isActiveWindow(Tags)
|
||||||
|
|| (isActiveWindow(Albums) && Albums.current()->value().isAllTracksEntry()))
|
||||||
|
{
|
||||||
|
Mpd.StartSearch(true);
|
||||||
|
Mpd.AddSearch(Config.media_lib_primary_tag, Tags.current()->value().tag());
|
||||||
|
std::vector<MPD::Song> list(
|
||||||
|
std::make_move_iterator(Mpd.CommitSearchSongs()),
|
||||||
|
std::make_move_iterator(MPD::SongIterator())
|
||||||
|
);
|
||||||
|
result = addSongsToPlaylist(list.begin(), list.end(), play, -1);
|
||||||
|
std::string tag_type = boost::locale::to_lower(
|
||||||
|
tagTypeToString(Config.media_lib_primary_tag));
|
||||||
|
Statusbar::printf("Songs with %1% \"%2%\" added%3%",
|
||||||
|
tag_type, Tags.current()->value().tag(), withErrors(result)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (isActiveWindow(Albums))
|
||||||
|
{
|
||||||
|
std::vector<MPD::Song> list(
|
||||||
|
std::make_move_iterator(getSongsFromAlbum(Albums.current()->value())),
|
||||||
|
std::make_move_iterator(MPD::SongIterator())
|
||||||
|
);
|
||||||
|
result = addSongsToPlaylist(list.begin(), list.end(), play, -1);
|
||||||
|
Statusbar::printf("Songs from album \"%1%\" added%2%",
|
||||||
|
Albums.current()->value().entry().album(), withErrors(result)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<MPD::Song> MediaLibrary::getSelectedSongs()
|
std::vector<MPD::Song> MediaLibrary::getSelectedSongs()
|
||||||
@@ -914,44 +951,6 @@ void MediaLibrary::LocateSong(const MPD::Song &s)
|
|||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MediaLibrary::addItemToPlaylist(bool play)
|
|
||||||
{
|
|
||||||
bool result = false;
|
|
||||||
if (isActiveWindow(Songs) && !Songs.empty())
|
|
||||||
result = addSongToPlaylist(Songs.current()->value(), play);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((!Tags.empty() && isActiveWindow(Tags))
|
|
||||||
|| (isActiveWindow(Albums) && Albums.current()->value().isAllTracksEntry()))
|
|
||||||
{
|
|
||||||
Mpd.StartSearch(true);
|
|
||||||
Mpd.AddSearch(Config.media_lib_primary_tag, Tags.current()->value().tag());
|
|
||||||
std::vector<MPD::Song> list(
|
|
||||||
std::make_move_iterator(Mpd.CommitSearchSongs()),
|
|
||||||
std::make_move_iterator(MPD::SongIterator())
|
|
||||||
);
|
|
||||||
result = addSongsToPlaylist(list.begin(), list.end(), play, -1);
|
|
||||||
std::string tag_type = boost::locale::to_lower(
|
|
||||||
tagTypeToString(Config.media_lib_primary_tag));
|
|
||||||
Statusbar::printf("Songs with %1% \"%2%\" added%3%",
|
|
||||||
tag_type, Tags.current()->value().tag(), withErrors(result)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if (isActiveWindow(Albums))
|
|
||||||
{
|
|
||||||
std::vector<MPD::Song> list(
|
|
||||||
std::make_move_iterator(getSongsFromAlbum(Albums.current()->value())),
|
|
||||||
std::make_move_iterator(MPD::SongIterator())
|
|
||||||
);
|
|
||||||
result = addSongsToPlaylist(list.begin(), list.end(), play, -1);
|
|
||||||
Statusbar::printf("Songs from album \"%1%\" added%2%",
|
|
||||||
Albums.current()->value().entry().album(), withErrors(result)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
std::string AlbumToString(const AlbumEntry &ae)
|
std::string AlbumToString(const AlbumEntry &ae)
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ struct MediaLibrary: Screen<NC::Window *>, HasColumns, HasSongs, Searchable, Tab
|
|||||||
|
|
||||||
virtual int windowTimeout() OVERRIDE;
|
virtual int windowTimeout() OVERRIDE;
|
||||||
|
|
||||||
virtual void enterPressed() OVERRIDE;
|
|
||||||
virtual void mouseButtonPressed(MEVENT me) OVERRIDE;
|
virtual void mouseButtonPressed(MEVENT me) OVERRIDE;
|
||||||
|
|
||||||
virtual bool isLockable() OVERRIDE { return true; }
|
virtual bool isLockable() OVERRIDE { return true; }
|
||||||
@@ -56,7 +55,8 @@ struct MediaLibrary: Screen<NC::Window *>, HasColumns, HasSongs, Searchable, Tab
|
|||||||
virtual bool find(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
|
virtual bool find(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
|
||||||
|
|
||||||
// HasSongs implementation
|
// HasSongs implementation
|
||||||
virtual bool addItemToPlaylist() OVERRIDE;
|
virtual bool itemAvailable() OVERRIDE;
|
||||||
|
virtual bool addItemToPlaylist(bool play) OVERRIDE;
|
||||||
virtual std::vector<MPD::Song> getSelectedSongs() OVERRIDE;
|
virtual std::vector<MPD::Song> getSelectedSongs() OVERRIDE;
|
||||||
|
|
||||||
// HasColumns implementation
|
// HasColumns implementation
|
||||||
@@ -133,8 +133,6 @@ struct MediaLibrary: Screen<NC::Window *>, HasColumns, HasSongs, Searchable, Tab
|
|||||||
SongMenu Songs;
|
SongMenu Songs;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool addItemToPlaylist(bool play);
|
|
||||||
|
|
||||||
bool m_tags_update_request;
|
bool m_tags_update_request;
|
||||||
bool m_albums_update_request;
|
bool m_albums_update_request;
|
||||||
bool m_songs_update_request;
|
bool m_songs_update_request;
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ void Outputs::mouseButtonPressed(MEVENT me)
|
|||||||
{
|
{
|
||||||
w.Goto(me.y);
|
w.Goto(me.y);
|
||||||
if (me.bstate & BUTTON3_PRESSED)
|
if (me.bstate & BUTTON3_PRESSED)
|
||||||
enterPressed();
|
toggleOutput();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Screen<WindowType>::mouseButtonPressed(me);
|
Screen<WindowType>::mouseButtonPressed(me);
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ struct Outputs: Screen<NC::Menu<MPD::Output>>, Tabbable
|
|||||||
|
|
||||||
virtual void update() OVERRIDE { }
|
virtual void update() OVERRIDE { }
|
||||||
|
|
||||||
virtual void enterPressed() OVERRIDE { }
|
|
||||||
virtual void mouseButtonPressed(MEVENT me) OVERRIDE;
|
virtual void mouseButtonPressed(MEVENT me) OVERRIDE;
|
||||||
|
|
||||||
virtual bool isLockable() OVERRIDE { return true; }
|
virtual bool isLockable() OVERRIDE { return true; }
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ void Playlist::mouseButtonPressed(MEVENT me)
|
|||||||
{
|
{
|
||||||
w.Goto(me.y);
|
w.Goto(me.y);
|
||||||
if (me.bstate & BUTTON3_PRESSED)
|
if (me.bstate & BUTTON3_PRESSED)
|
||||||
enterPressed();
|
addItemToPlaylist(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Screen<WindowType>::mouseButtonPressed(me);
|
Screen<WindowType>::mouseButtonPressed(me);
|
||||||
@@ -172,6 +172,18 @@ bool Playlist::find(SearchDirection direction, bool wrap, bool skip_current)
|
|||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
|
||||||
|
bool Playlist::itemAvailable()
|
||||||
|
{
|
||||||
|
return !w.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Playlist::addItemToPlaylist(bool play)
|
||||||
|
{
|
||||||
|
if (play)
|
||||||
|
Mpd.PlayID(w.currentV()->getID());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<MPD::Song> Playlist::getSelectedSongs()
|
std::vector<MPD::Song> Playlist::getSelectedSongs()
|
||||||
{
|
{
|
||||||
return w.getSelectedSongs();
|
return w.getSelectedSongs();
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ struct Playlist: Screen<SongMenu>, HasSongs, Searchable, Tabbable
|
|||||||
|
|
||||||
virtual void update() OVERRIDE;
|
virtual void update() OVERRIDE;
|
||||||
|
|
||||||
virtual void enterPressed() OVERRIDE { }
|
|
||||||
virtual void mouseButtonPressed(MEVENT me) OVERRIDE;
|
virtual void mouseButtonPressed(MEVENT me) OVERRIDE;
|
||||||
|
|
||||||
virtual bool isLockable() OVERRIDE { return true; }
|
virtual bool isLockable() OVERRIDE { return true; }
|
||||||
@@ -56,7 +55,8 @@ struct Playlist: Screen<SongMenu>, HasSongs, Searchable, Tabbable
|
|||||||
virtual bool find(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
|
virtual bool find(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
|
||||||
|
|
||||||
// HasSongs implementation
|
// HasSongs implementation
|
||||||
virtual bool addItemToPlaylist() OVERRIDE { return false; };
|
virtual bool itemAvailable() OVERRIDE;
|
||||||
|
virtual bool addItemToPlaylist(bool play) OVERRIDE;
|
||||||
virtual std::vector<MPD::Song> getSelectedSongs() OVERRIDE;
|
virtual std::vector<MPD::Song> getSelectedSongs() OVERRIDE;
|
||||||
|
|
||||||
// private members
|
// private members
|
||||||
|
|||||||
@@ -225,11 +225,6 @@ int PlaylistEditor::windowTimeout()
|
|||||||
return Screen<WindowType>::windowTimeout();
|
return Screen<WindowType>::windowTimeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlaylistEditor::enterPressed()
|
|
||||||
{
|
|
||||||
addItemToPlaylist(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlaylistEditor::mouseButtonPressed(MEVENT me)
|
void PlaylistEditor::mouseButtonPressed(MEVENT me)
|
||||||
{
|
{
|
||||||
if (!Playlists.empty() && Playlists.hasCoords(me.x, me.y))
|
if (!Playlists.empty() && Playlists.hasCoords(me.x, me.y))
|
||||||
@@ -245,7 +240,7 @@ void PlaylistEditor::mouseButtonPressed(MEVENT me)
|
|||||||
{
|
{
|
||||||
Playlists.Goto(me.y);
|
Playlists.Goto(me.y);
|
||||||
if (me.bstate & BUTTON3_PRESSED)
|
if (me.bstate & BUTTON3_PRESSED)
|
||||||
addItemToPlaylist();
|
addItemToPlaylist(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Screen<WindowType>::mouseButtonPressed(me);
|
Screen<WindowType>::mouseButtonPressed(me);
|
||||||
@@ -263,10 +258,8 @@ void PlaylistEditor::mouseButtonPressed(MEVENT me)
|
|||||||
if (size_t(me.y) < Content.size() && (me.bstate & (BUTTON1_PRESSED | BUTTON3_PRESSED)))
|
if (size_t(me.y) < Content.size() && (me.bstate & (BUTTON1_PRESSED | BUTTON3_PRESSED)))
|
||||||
{
|
{
|
||||||
Content.Goto(me.y);
|
Content.Goto(me.y);
|
||||||
if (me.bstate & BUTTON1_PRESSED)
|
bool play = me.bstate & BUTTON3_PRESSED;
|
||||||
addItemToPlaylist();
|
addItemToPlaylist(play);
|
||||||
else
|
|
||||||
enterPressed();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Screen<WindowType>::mouseButtonPressed(me);
|
Screen<WindowType>::mouseButtonPressed(me);
|
||||||
@@ -318,9 +311,32 @@ bool PlaylistEditor::find(SearchDirection direction, bool wrap, bool skip_curren
|
|||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
|
||||||
bool PlaylistEditor::addItemToPlaylist()
|
bool PlaylistEditor::itemAvailable()
|
||||||
{
|
{
|
||||||
return addItemToPlaylist(false);
|
if (isActiveWindow(Playlists))
|
||||||
|
return !Playlists.empty();
|
||||||
|
if (isActiveWindow(Content))
|
||||||
|
return !Content.empty();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PlaylistEditor::addItemToPlaylist(bool play)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
if (isActiveWindow(Playlists))
|
||||||
|
{
|
||||||
|
std::vector<MPD::Song> list(
|
||||||
|
std::make_move_iterator(Mpd.GetPlaylistContent(Playlists.current()->value().path())),
|
||||||
|
std::make_move_iterator(MPD::SongIterator())
|
||||||
|
);
|
||||||
|
result = addSongsToPlaylist(list.begin(), list.end(), play, -1);
|
||||||
|
Statusbar::printf("Playlist \"%1%\" loaded%2%",
|
||||||
|
Playlists.current()->value().path(), withErrors(result)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (isActiveWindow(Content))
|
||||||
|
result = addSongToPlaylist(Content.current()->value(), play);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<MPD::Song> PlaylistEditor::getSelectedSongs()
|
std::vector<MPD::Song> PlaylistEditor::getSelectedSongs()
|
||||||
@@ -420,25 +436,6 @@ void PlaylistEditor::Locate(const MPD::Playlist &playlist)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PlaylistEditor::addItemToPlaylist(bool play)
|
|
||||||
{
|
|
||||||
bool result = false;
|
|
||||||
if (isActiveWindow(Playlists) && !Playlists.empty())
|
|
||||||
{
|
|
||||||
std::vector<MPD::Song> list(
|
|
||||||
std::make_move_iterator(Mpd.GetPlaylistContent(Playlists.current()->value().path())),
|
|
||||||
std::make_move_iterator(MPD::SongIterator())
|
|
||||||
);
|
|
||||||
result = addSongsToPlaylist(list.begin(), list.end(), play, -1);
|
|
||||||
Statusbar::printf("Playlist \"%1%\" loaded%2%",
|
|
||||||
Playlists.current()->value().path(), withErrors(result)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if (isActiveWindow(Content) && !Content.empty())
|
|
||||||
result = addSongToPlaylist(Content.current()->value(), play);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
std::string SongToString(const MPD::Song &s)
|
std::string SongToString(const MPD::Song &s)
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ struct PlaylistEditor: Screen<NC::Window *>, HasColumns, HasSongs, Searchable, T
|
|||||||
|
|
||||||
virtual int windowTimeout() OVERRIDE;
|
virtual int windowTimeout() OVERRIDE;
|
||||||
|
|
||||||
virtual void enterPressed() OVERRIDE;
|
|
||||||
virtual void mouseButtonPressed(MEVENT me) OVERRIDE;
|
virtual void mouseButtonPressed(MEVENT me) OVERRIDE;
|
||||||
|
|
||||||
virtual bool isLockable() OVERRIDE { return true; }
|
virtual bool isLockable() OVERRIDE { return true; }
|
||||||
@@ -56,7 +55,8 @@ struct PlaylistEditor: Screen<NC::Window *>, HasColumns, HasSongs, Searchable, T
|
|||||||
virtual bool find(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
|
virtual bool find(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
|
||||||
|
|
||||||
// HasSongs implementation
|
// HasSongs implementation
|
||||||
virtual bool addItemToPlaylist() OVERRIDE;
|
virtual bool itemAvailable() OVERRIDE;
|
||||||
|
virtual bool addItemToPlaylist(bool play) OVERRIDE;
|
||||||
virtual std::vector<MPD::Song> getSelectedSongs() OVERRIDE;
|
virtual std::vector<MPD::Song> getSelectedSongs() OVERRIDE;
|
||||||
|
|
||||||
// HasColumns implementation
|
// HasColumns implementation
|
||||||
@@ -78,8 +78,6 @@ struct PlaylistEditor: Screen<NC::Window *>, HasColumns, HasSongs, Searchable, T
|
|||||||
SongMenu Content;
|
SongMenu Content;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool addItemToPlaylist(bool play);
|
|
||||||
|
|
||||||
bool m_playlists_update_requested;
|
bool m_playlists_update_requested;
|
||||||
bool m_content_update_requested;
|
bool m_content_update_requested;
|
||||||
|
|
||||||
|
|||||||
@@ -73,9 +73,6 @@ struct BaseScreen
|
|||||||
/// somehow, it should be called by this function.
|
/// somehow, it should be called by this function.
|
||||||
virtual void update() = 0;
|
virtual void update() = 0;
|
||||||
|
|
||||||
/// Invoked after Enter was pressed
|
|
||||||
virtual void enterPressed() = 0;
|
|
||||||
|
|
||||||
/// @see Screen::mouseButtonPressed()
|
/// @see Screen::mouseButtonPressed()
|
||||||
virtual void mouseButtonPressed(MEVENT me) = 0;
|
virtual void mouseButtonPressed(MEVENT me) = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -205,12 +205,66 @@ std::wstring SearchEngine::title()
|
|||||||
return L"Search engine";
|
return L"Search engine";
|
||||||
}
|
}
|
||||||
|
|
||||||
void SearchEngine::enterPressed()
|
void SearchEngine::mouseButtonPressed(MEVENT me)
|
||||||
|
{
|
||||||
|
if (w.empty() || !w.hasCoords(me.x, me.y) || size_t(me.y) >= w.size())
|
||||||
|
return;
|
||||||
|
if (me.bstate & (BUTTON1_PRESSED | BUTTON3_PRESSED))
|
||||||
|
{
|
||||||
|
if (!w.Goto(me.y))
|
||||||
|
return;
|
||||||
|
w.refresh();
|
||||||
|
if ((me.bstate & BUTTON3_PRESSED)
|
||||||
|
&& w.choice() < StaticOptions)
|
||||||
|
runAction();
|
||||||
|
else if (w.choice() >= StaticOptions)
|
||||||
|
{
|
||||||
|
bool play = me.bstate & BUTTON3_PRESSED;
|
||||||
|
addItemToPlaylist(play);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Screen<WindowType>::mouseButtonPressed(me);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
|
||||||
|
bool SearchEngine::allowsSearching()
|
||||||
|
{
|
||||||
|
return w.rbegin()->value().isSong();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SearchEngine::setSearchConstraint(const std::string &constraint)
|
||||||
|
{
|
||||||
|
m_search_predicate = Regex::ItemFilter<SEItem>(
|
||||||
|
Regex::make(constraint, Config.regex_type),
|
||||||
|
std::bind(SEItemEntryMatcher, ph::_1, ph::_2, false)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SearchEngine::clearConstraint()
|
||||||
|
{
|
||||||
|
m_search_predicate.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SearchEngine::find(SearchDirection direction, bool wrap, bool skip_current)
|
||||||
|
{
|
||||||
|
return search(w, m_search_predicate, direction, wrap, skip_current);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
|
||||||
|
bool SearchEngine::actionRunnable()
|
||||||
|
{
|
||||||
|
return !w.empty() && !w.current()->value().isSong();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SearchEngine::runAction()
|
||||||
{
|
{
|
||||||
size_t option = w.choice();
|
size_t option = w.choice();
|
||||||
if (option > ConstraintsNumber && option < SearchButton)
|
if (option > ConstraintsNumber && option < SearchButton)
|
||||||
w.current()->value().buffer().clear();
|
w.current()->value().buffer().clear();
|
||||||
|
|
||||||
if (option < ConstraintsNumber)
|
if (option < ConstraintsNumber)
|
||||||
{
|
{
|
||||||
Statusbar::ScopedLock slock;
|
Statusbar::ScopedLock slock;
|
||||||
@@ -268,62 +322,16 @@ void SearchEngine::enterPressed()
|
|||||||
addSongToPlaylist(w.current()->value().song(), true);
|
addSongToPlaylist(w.current()->value().song(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SearchEngine::mouseButtonPressed(MEVENT me)
|
|
||||||
{
|
|
||||||
if (w.empty() || !w.hasCoords(me.x, me.y) || size_t(me.y) >= w.size())
|
|
||||||
return;
|
|
||||||
if (me.bstate & (BUTTON1_PRESSED | BUTTON3_PRESSED))
|
|
||||||
{
|
|
||||||
if (!w.Goto(me.y))
|
|
||||||
return;
|
|
||||||
w.refresh();
|
|
||||||
if ((me.bstate & BUTTON3_PRESSED || w.choice() > ConstraintsNumber) && w.choice() < StaticOptions)
|
|
||||||
enterPressed();
|
|
||||||
else if (w.choice() >= StaticOptions)
|
|
||||||
{
|
|
||||||
if (me.bstate & BUTTON1_PRESSED)
|
|
||||||
addItemToPlaylist();
|
|
||||||
else
|
|
||||||
enterPressed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Screen<WindowType>::mouseButtonPressed(me);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
|
||||||
bool SearchEngine::allowsSearching()
|
bool SearchEngine::itemAvailable()
|
||||||
{
|
{
|
||||||
return w.rbegin()->value().isSong();
|
return !w.empty() && w.current()->value().isSong();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SearchEngine::setSearchConstraint(const std::string &constraint)
|
bool SearchEngine::addItemToPlaylist(bool play)
|
||||||
{
|
{
|
||||||
m_search_predicate = Regex::ItemFilter<SEItem>(
|
return addSongToPlaylist(w.current()->value().song(), play);
|
||||||
Regex::make(constraint, Config.regex_type),
|
|
||||||
std::bind(SEItemEntryMatcher, ph::_1, ph::_2, false)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SearchEngine::clearConstraint()
|
|
||||||
{
|
|
||||||
m_search_predicate.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SearchEngine::find(SearchDirection direction, bool wrap, bool skip_current)
|
|
||||||
{
|
|
||||||
return search(w, m_search_predicate, direction, wrap, skip_current);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************/
|
|
||||||
|
|
||||||
bool SearchEngine::addItemToPlaylist()
|
|
||||||
{
|
|
||||||
bool result = false;
|
|
||||||
if (!w.empty() && w.current()->value().isSong())
|
|
||||||
result = addSongToPlaylist(w.current()->value().song(), false);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<MPD::Song> SearchEngine::getSelectedSongs()
|
std::vector<MPD::Song> SearchEngine::getSelectedSongs()
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ struct SearchEngineWindow: NC::Menu<SEItem>, SongList
|
|||||||
virtual std::vector<MPD::Song> getSelectedSongs() OVERRIDE;
|
virtual std::vector<MPD::Song> getSelectedSongs() OVERRIDE;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SearchEngine: Screen<SearchEngineWindow>, HasSongs, Searchable, Tabbable
|
struct SearchEngine: Screen<SearchEngineWindow>, HasActions, HasSongs, Searchable, Tabbable
|
||||||
{
|
{
|
||||||
SearchEngine();
|
SearchEngine();
|
||||||
|
|
||||||
@@ -104,7 +104,6 @@ struct SearchEngine: Screen<SearchEngineWindow>, HasSongs, Searchable, Tabbable
|
|||||||
|
|
||||||
virtual void update() OVERRIDE { }
|
virtual void update() OVERRIDE { }
|
||||||
|
|
||||||
virtual void enterPressed() OVERRIDE;
|
|
||||||
virtual void mouseButtonPressed(MEVENT me) OVERRIDE;
|
virtual void mouseButtonPressed(MEVENT me) OVERRIDE;
|
||||||
|
|
||||||
virtual bool isLockable() OVERRIDE { return true; }
|
virtual bool isLockable() OVERRIDE { return true; }
|
||||||
@@ -115,9 +114,14 @@ struct SearchEngine: Screen<SearchEngineWindow>, HasSongs, Searchable, Tabbable
|
|||||||
virtual void setSearchConstraint(const std::string &constraint) OVERRIDE;
|
virtual void setSearchConstraint(const std::string &constraint) OVERRIDE;
|
||||||
virtual void clearConstraint() OVERRIDE;
|
virtual void clearConstraint() OVERRIDE;
|
||||||
virtual bool find(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
|
virtual bool find(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
|
||||||
|
|
||||||
|
// HasActions implementation
|
||||||
|
virtual bool actionRunnable() OVERRIDE;
|
||||||
|
virtual void runAction() OVERRIDE;
|
||||||
|
|
||||||
// HasSongs implementation
|
// HasSongs implementation
|
||||||
virtual bool addItemToPlaylist() OVERRIDE;
|
virtual bool itemAvailable() OVERRIDE;
|
||||||
|
virtual bool addItemToPlaylist(bool play) OVERRIDE;
|
||||||
virtual std::vector<MPD::Song> getSelectedSongs() OVERRIDE;
|
virtual std::vector<MPD::Song> getSelectedSongs() OVERRIDE;
|
||||||
|
|
||||||
// private members
|
// private members
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ void SelectedItemsAdder::switchTo()
|
|||||||
{
|
{
|
||||||
using Global::myScreen;
|
using Global::myScreen;
|
||||||
|
|
||||||
auto hs = hasSongs(myScreen);
|
auto hs = dynamic_cast<HasSongs *>(myScreen);
|
||||||
if (!hs)
|
if (!hs)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -169,11 +169,6 @@ std::wstring SelectedItemsAdder::title()
|
|||||||
return previousScreen()->title();
|
return previousScreen()->title();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectedItemsAdder::enterPressed()
|
|
||||||
{
|
|
||||||
w->current()->value().run();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SelectedItemsAdder::mouseButtonPressed(MEVENT me)
|
void SelectedItemsAdder::mouseButtonPressed(MEVENT me)
|
||||||
{
|
{
|
||||||
if (w->empty() || !w->hasCoords(me.x, me.y) || size_t(me.y) >= w->size())
|
if (w->empty() || !w->hasCoords(me.x, me.y) || size_t(me.y) >= w->size())
|
||||||
@@ -182,7 +177,7 @@ void SelectedItemsAdder::mouseButtonPressed(MEVENT me)
|
|||||||
{
|
{
|
||||||
w->Goto(me.y);
|
w->Goto(me.y);
|
||||||
if (me.bstate & BUTTON3_PRESSED)
|
if (me.bstate & BUTTON3_PRESSED)
|
||||||
enterPressed();
|
runAction();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Screen<WindowType>::mouseButtonPressed(me);
|
Screen<WindowType>::mouseButtonPressed(me);
|
||||||
@@ -190,6 +185,18 @@ void SelectedItemsAdder::mouseButtonPressed(MEVENT me)
|
|||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
|
||||||
|
bool SelectedItemsAdder::actionRunnable()
|
||||||
|
{
|
||||||
|
return !w->empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SelectedItemsAdder::runAction()
|
||||||
|
{
|
||||||
|
w->current()->value().run();
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
|
||||||
bool SelectedItemsAdder::allowsSearching()
|
bool SelectedItemsAdder::allowsSearching()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "song.h"
|
#include "song.h"
|
||||||
|
|
||||||
struct SelectedItemsAdder: Screen<NC::Menu<RunnableItem<std::string, void()>> *>, Searchable, Tabbable
|
struct SelectedItemsAdder: Screen<NC::Menu<RunnableItem<std::string, void()>> *>, HasActions, Searchable, Tabbable
|
||||||
{
|
{
|
||||||
typedef SelectedItemsAdder Self;
|
typedef SelectedItemsAdder Self;
|
||||||
typedef typename std::remove_pointer<WindowType>::type Component;
|
typedef typename std::remove_pointer<WindowType>::type Component;
|
||||||
@@ -44,12 +44,15 @@ struct SelectedItemsAdder: Screen<NC::Menu<RunnableItem<std::string, void()>> *>
|
|||||||
|
|
||||||
virtual void update() OVERRIDE { }
|
virtual void update() OVERRIDE { }
|
||||||
|
|
||||||
virtual void enterPressed() OVERRIDE;
|
|
||||||
virtual void mouseButtonPressed(MEVENT me) OVERRIDE;
|
virtual void mouseButtonPressed(MEVENT me) OVERRIDE;
|
||||||
|
|
||||||
virtual bool isLockable() OVERRIDE { return false; }
|
virtual bool isLockable() OVERRIDE { return false; }
|
||||||
virtual bool isMergable() OVERRIDE { return false; }
|
virtual bool isMergable() OVERRIDE { return false; }
|
||||||
|
|
||||||
|
// HasActions implemenetation
|
||||||
|
virtual bool actionRunnable() OVERRIDE;
|
||||||
|
virtual void runAction() OVERRIDE;
|
||||||
|
|
||||||
// Searchable implementation
|
// Searchable implementation
|
||||||
virtual bool allowsSearching() OVERRIDE;
|
virtual bool allowsSearching() OVERRIDE;
|
||||||
virtual void setSearchConstraint(const std::string &constraint) OVERRIDE;
|
virtual void setSearchConstraint(const std::string &constraint) OVERRIDE;
|
||||||
|
|||||||
@@ -39,8 +39,6 @@ struct ServerInfo: Screen<NC::Scrollpad>, Tabbable
|
|||||||
|
|
||||||
virtual void update() OVERRIDE;
|
virtual void update() OVERRIDE;
|
||||||
|
|
||||||
virtual void enterPressed() OVERRIDE { }
|
|
||||||
|
|
||||||
virtual bool isLockable() OVERRIDE { return false; }
|
virtual bool isLockable() OVERRIDE { return false; }
|
||||||
virtual bool isMergable() OVERRIDE { return false; }
|
virtual bool isMergable() OVERRIDE { return false; }
|
||||||
|
|
||||||
|
|||||||
@@ -45,8 +45,6 @@ struct SongInfo: Screen<NC::Scrollpad>, Tabbable
|
|||||||
|
|
||||||
virtual void update() OVERRIDE { }
|
virtual void update() OVERRIDE { }
|
||||||
|
|
||||||
virtual void enterPressed() OVERRIDE { }
|
|
||||||
|
|
||||||
virtual bool isLockable() OVERRIDE { return false; }
|
virtual bool isLockable() OVERRIDE { return false; }
|
||||||
virtual bool isMergable() OVERRIDE { return true; }
|
virtual bool isMergable() OVERRIDE { return true; }
|
||||||
|
|
||||||
|
|||||||
@@ -107,11 +107,6 @@ std::wstring SortPlaylistDialog::title()
|
|||||||
return previousScreen()->title();
|
return previousScreen()->title();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SortPlaylistDialog::enterPressed()
|
|
||||||
{
|
|
||||||
w.current()->value().run();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SortPlaylistDialog::mouseButtonPressed(MEVENT me)
|
void SortPlaylistDialog::mouseButtonPressed(MEVENT me)
|
||||||
{
|
{
|
||||||
if (w.hasCoords(me.x, me.y))
|
if (w.hasCoords(me.x, me.y))
|
||||||
@@ -120,13 +115,27 @@ void SortPlaylistDialog::mouseButtonPressed(MEVENT me)
|
|||||||
{
|
{
|
||||||
w.Goto(me.y);
|
w.Goto(me.y);
|
||||||
if (me.bstate & BUTTON3_PRESSED)
|
if (me.bstate & BUTTON3_PRESSED)
|
||||||
enterPressed();
|
runAction();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Screen<WindowType>::mouseButtonPressed(me);
|
Screen<WindowType>::mouseButtonPressed(me);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
|
||||||
|
bool SortPlaylistDialog::actionRunnable()
|
||||||
|
{
|
||||||
|
return !w.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SortPlaylistDialog::runAction()
|
||||||
|
{
|
||||||
|
w.current()->value().run();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
|
||||||
void SortPlaylistDialog::moveSortOrderDown()
|
void SortPlaylistDialog::moveSortOrderDown()
|
||||||
{
|
{
|
||||||
auto cur = w.currentV();
|
auto cur = w.currentV();
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
#include "song.h"
|
#include "song.h"
|
||||||
|
|
||||||
struct SortPlaylistDialog
|
struct SortPlaylistDialog
|
||||||
: Screen<NC::Menu<RunnableItem<std::pair<std::string, MPD::Song::GetFunction>, void()>>>, Tabbable
|
: Screen<NC::Menu<RunnableItem<std::pair<std::string, MPD::Song::GetFunction>, void()>>>, HasActions, Tabbable
|
||||||
{
|
{
|
||||||
typedef SortPlaylistDialog Self;
|
typedef SortPlaylistDialog Self;
|
||||||
|
|
||||||
@@ -41,12 +41,15 @@ struct SortPlaylistDialog
|
|||||||
|
|
||||||
virtual void update() OVERRIDE { }
|
virtual void update() OVERRIDE { }
|
||||||
|
|
||||||
virtual void enterPressed() OVERRIDE;
|
|
||||||
virtual void mouseButtonPressed(MEVENT me) OVERRIDE;
|
virtual void mouseButtonPressed(MEVENT me) OVERRIDE;
|
||||||
|
|
||||||
virtual bool isLockable() OVERRIDE { return false; }
|
virtual bool isLockable() OVERRIDE { return false; }
|
||||||
virtual bool isMergable() OVERRIDE { return false; }
|
virtual bool isMergable() OVERRIDE { return false; }
|
||||||
|
|
||||||
|
// HasActions implementation
|
||||||
|
virtual bool actionRunnable() OVERRIDE;
|
||||||
|
virtual void runAction() OVERRIDE;
|
||||||
|
|
||||||
// private members
|
// private members
|
||||||
void moveSortOrderUp();
|
void moveSortOrderUp();
|
||||||
void moveSortOrderDown();
|
void moveSortOrderDown();
|
||||||
|
|||||||
@@ -379,6 +379,11 @@ int Status::State::currentSongPosition()
|
|||||||
return m_current_song_pos;
|
return m_current_song_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned Status::State::playlistLength()
|
||||||
|
{
|
||||||
|
return m_playlist_length;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned Status::State::elapsedTime()
|
unsigned Status::State::elapsedTime()
|
||||||
{
|
{
|
||||||
return m_elapsed_time;
|
return m_elapsed_time;
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ bool single();
|
|||||||
// misc
|
// misc
|
||||||
int currentSongID();
|
int currentSongID();
|
||||||
int currentSongPosition();
|
int currentSongPosition();
|
||||||
|
unsigned playlistLength();
|
||||||
unsigned elapsedTime();
|
unsigned elapsedTime();
|
||||||
MPD::PlayerState player();
|
MPD::PlayerState player();
|
||||||
unsigned totalTime();
|
unsigned totalTime();
|
||||||
|
|||||||
@@ -329,11 +329,10 @@ void TagEditor::update()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TagEditor::enterPressed()
|
bool TagEditor::enterDirectory()
|
||||||
{
|
{
|
||||||
using Global::wFooter;
|
bool result = false;
|
||||||
|
if (w == Dirs && !Dirs->empty())
|
||||||
if (w == Dirs)
|
|
||||||
{
|
{
|
||||||
MPD::DirectoryIterator directory = Mpd.GetDirectories(Dirs->current()->value().second), end;
|
MPD::DirectoryIterator directory = Mpd.GetDirectories(Dirs->current()->value().second), end;
|
||||||
bool has_subdirs = directory != end;
|
bool has_subdirs = directory != end;
|
||||||
@@ -344,11 +343,194 @@ void TagEditor::enterPressed()
|
|||||||
itsBrowsedDir = Dirs->current()->value().second;
|
itsBrowsedDir = Dirs->current()->value().second;
|
||||||
Dirs->clear();
|
Dirs->clear();
|
||||||
Dirs->reset();
|
Dirs->reset();
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TagEditor::mouseButtonPressed(MEVENT me)
|
||||||
|
{
|
||||||
|
auto tryPreviousColumn = [this]() -> bool {
|
||||||
|
bool result = true;
|
||||||
|
if (w != Dirs)
|
||||||
|
{
|
||||||
|
if (previousColumnAvailable())
|
||||||
|
previousColumn();
|
||||||
|
else
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
auto tryNextColumn = [this]() -> bool {
|
||||||
|
bool result = true;
|
||||||
|
if (w != Tags)
|
||||||
|
{
|
||||||
|
if (nextColumnAvailable())
|
||||||
|
nextColumn();
|
||||||
|
else
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
if (w == FParserDialog)
|
||||||
|
{
|
||||||
|
if (FParserDialog->hasCoords(me.x, me.y))
|
||||||
|
{
|
||||||
|
if (me.bstate & (BUTTON1_PRESSED | BUTTON3_PRESSED))
|
||||||
|
{
|
||||||
|
FParserDialog->Goto(me.y);
|
||||||
|
if (me.bstate & BUTTON3_PRESSED)
|
||||||
|
runAction();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Screen<WindowType>::mouseButtonPressed(me);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (w == FParser || w == FParserHelper)
|
||||||
|
{
|
||||||
|
if (FParser->hasCoords(me.x, me.y))
|
||||||
|
{
|
||||||
|
if (w != FParser)
|
||||||
|
{
|
||||||
|
if (previousColumnAvailable())
|
||||||
|
previousColumn();
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (size_t(me.y) < FParser->size() && (me.bstate & (BUTTON1_PRESSED | BUTTON3_PRESSED)))
|
||||||
|
{
|
||||||
|
FParser->Goto(me.y);
|
||||||
|
if (me.bstate & BUTTON3_PRESSED)
|
||||||
|
runAction();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Screen<WindowType>::mouseButtonPressed(me);
|
||||||
|
}
|
||||||
|
else if (FParserHelper->hasCoords(me.x, me.y))
|
||||||
|
{
|
||||||
|
if (w != FParserHelper)
|
||||||
|
{
|
||||||
|
if (nextColumnAvailable())
|
||||||
|
nextColumn();
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
scrollpadMouseButtonPressed(*FParserHelper, me);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!Dirs->empty() && Dirs->hasCoords(me.x, me.y))
|
||||||
|
{
|
||||||
|
if (!tryPreviousColumn() || !tryPreviousColumn())
|
||||||
|
return;
|
||||||
|
if (size_t(me.y) < Dirs->size() && (me.bstate & (BUTTON1_PRESSED | BUTTON3_PRESSED)))
|
||||||
|
{
|
||||||
|
Dirs->Goto(me.y);
|
||||||
|
if (me.bstate & BUTTON1_PRESSED)
|
||||||
|
enterDirectory();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Statusbar::print("No subdirectories found");
|
Screen<WindowType>::mouseButtonPressed(me);
|
||||||
|
Tags->clear();
|
||||||
}
|
}
|
||||||
else if (w == FParserDialog)
|
else if (!TagTypes->empty() && TagTypes->hasCoords(me.x, me.y))
|
||||||
|
{
|
||||||
|
if (w != TagTypes)
|
||||||
|
{
|
||||||
|
bool success;
|
||||||
|
if (w == Dirs)
|
||||||
|
success = tryNextColumn();
|
||||||
|
else
|
||||||
|
success = tryPreviousColumn();
|
||||||
|
if (!success)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (size_t(me.y) < TagTypes->size() && (me.bstate & (BUTTON1_PRESSED | BUTTON3_PRESSED)))
|
||||||
|
{
|
||||||
|
if (!TagTypes->Goto(me.y))
|
||||||
|
return;
|
||||||
|
TagTypes->refresh();
|
||||||
|
Tags->refresh();
|
||||||
|
if (me.bstate & BUTTON3_PRESSED)
|
||||||
|
runAction();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Screen<WindowType>::mouseButtonPressed(me);
|
||||||
|
}
|
||||||
|
else if (!Tags->empty() && Tags->hasCoords(me.x, me.y))
|
||||||
|
{
|
||||||
|
if (!tryNextColumn() || !tryNextColumn())
|
||||||
|
return;
|
||||||
|
if (size_t(me.y) < Tags->size() && (me.bstate & (BUTTON1_PRESSED | BUTTON3_PRESSED)))
|
||||||
|
{
|
||||||
|
Tags->Goto(me.y);
|
||||||
|
Tags->refresh();
|
||||||
|
if (me.bstate & BUTTON3_PRESSED)
|
||||||
|
runAction();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Screen<WindowType>::mouseButtonPressed(me);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
|
||||||
|
bool TagEditor::allowsSearching()
|
||||||
|
{
|
||||||
|
return w == Dirs || w == Tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TagEditor::setSearchConstraint(const std::string &constraint)
|
||||||
|
{
|
||||||
|
if (w == Dirs)
|
||||||
|
{
|
||||||
|
m_directories_search_predicate = Regex::Filter<std::pair<std::string, std::string>>(
|
||||||
|
Regex::make(constraint, Config.regex_type),
|
||||||
|
std::bind(DirEntryMatcher, ph::_1, ph::_2, false)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (w == Tags)
|
||||||
|
{
|
||||||
|
m_songs_search_predicate = Regex::Filter<MPD::MutableSong>(
|
||||||
|
Regex::make(constraint, Config.regex_type),
|
||||||
|
SongEntryMatcher
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TagEditor::clearConstraint()
|
||||||
|
{
|
||||||
|
if (w == Dirs)
|
||||||
|
m_directories_search_predicate.clear();
|
||||||
|
else if (w == Tags)
|
||||||
|
m_songs_search_predicate.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TagEditor::find(SearchDirection direction, bool wrap, bool skip_current)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
if (w == Dirs)
|
||||||
|
result = search(*Dirs, m_directories_search_predicate, direction, wrap, skip_current);
|
||||||
|
else if (w == Tags)
|
||||||
|
result = search(*Tags, m_songs_search_predicate, direction, wrap, skip_current);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
|
||||||
|
bool TagEditor::actionRunnable()
|
||||||
|
{
|
||||||
|
// TODO: put something more refined here. It requires reworking
|
||||||
|
// runAction though, i.e. splitting it into smaller parts.
|
||||||
|
return (w == Tags && !Tags->empty())
|
||||||
|
|| w != Tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TagEditor::runAction()
|
||||||
|
{
|
||||||
|
using Global::wFooter;
|
||||||
|
|
||||||
|
if (w == FParserDialog)
|
||||||
{
|
{
|
||||||
size_t choice = FParserDialog->choice();
|
size_t choice = FParserDialog->choice();
|
||||||
if (choice == 2) // cancel
|
if (choice == 2) // cancel
|
||||||
@@ -358,9 +540,9 @@ void TagEditor::enterPressed()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
GetPatternList();
|
GetPatternList();
|
||||||
|
|
||||||
// prepare additional windows
|
// prepare additional windows
|
||||||
|
|
||||||
FParserLegend->clear();
|
FParserLegend->clear();
|
||||||
*FParserLegend << "%a - artist\n";
|
*FParserLegend << "%a - artist\n";
|
||||||
*FParserLegend << "%A - album artist\n";
|
*FParserLegend << "%A - album artist\n";
|
||||||
@@ -377,7 +559,7 @@ void TagEditor::enterPressed()
|
|||||||
for (auto it = EditedSongs.begin(); it != EditedSongs.end(); ++it)
|
for (auto it = EditedSongs.begin(); it != EditedSongs.end(); ++it)
|
||||||
*FParserLegend << Config.color2 << " * " << NC::Color::End << (*it)->getName() << '\n';
|
*FParserLegend << Config.color2 << " * " << NC::Color::End << (*it)->getName() << '\n';
|
||||||
FParserLegend->flush();
|
FParserLegend->flush();
|
||||||
|
|
||||||
if (!Patterns.empty())
|
if (!Patterns.empty())
|
||||||
Config.pattern = Patterns.front();
|
Config.pattern = Patterns.front();
|
||||||
FParser->clear();
|
FParser->clear();
|
||||||
@@ -396,7 +578,7 @@ void TagEditor::enterPressed()
|
|||||||
for (std::list<std::string>::const_iterator it = Patterns.begin(); it != Patterns.end(); ++it)
|
for (std::list<std::string>::const_iterator it = Patterns.begin(); it != Patterns.end(); ++it)
|
||||||
FParser->addItem(*it);
|
FParser->addItem(*it);
|
||||||
}
|
}
|
||||||
|
|
||||||
FParser->setTitle(choice == 0 ? "Get tags from filename" : "Rename files");
|
FParser->setTitle(choice == 0 ? "Get tags from filename" : "Rename files");
|
||||||
w = FParser;
|
w = FParser;
|
||||||
FParserUsePreview = 1;
|
FParserUsePreview = 1;
|
||||||
@@ -407,10 +589,10 @@ void TagEditor::enterPressed()
|
|||||||
{
|
{
|
||||||
bool quit = 0;
|
bool quit = 0;
|
||||||
size_t pos = FParser->choice();
|
size_t pos = FParser->choice();
|
||||||
|
|
||||||
if (pos == 4) // save
|
if (pos == 4) // save
|
||||||
FParserUsePreview = 0;
|
FParserUsePreview = 0;
|
||||||
|
|
||||||
if (pos == 0) // change pattern
|
if (pos == 0) // change pattern
|
||||||
{
|
{
|
||||||
std::string new_pattern;
|
std::string new_pattern;
|
||||||
@@ -494,7 +676,7 @@ void TagEditor::enterPressed()
|
|||||||
Config.pattern = FParser->current()->value();
|
Config.pattern = FParser->current()->value();
|
||||||
FParser->at(0).value() = "Pattern: " + Config.pattern;
|
FParser->at(0).value() = "Pattern: " + Config.pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (quit)
|
if (quit)
|
||||||
{
|
{
|
||||||
SavePatternList();
|
SavePatternList();
|
||||||
@@ -503,10 +685,10 @@ void TagEditor::enterPressed()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((w != TagTypes && w != Tags) || Tags->empty()) // after this point we start dealing with tags
|
if ((w != TagTypes && w != Tags) || Tags->empty()) // after this point we start dealing with tags
|
||||||
return;
|
return;
|
||||||
|
|
||||||
EditedSongs.clear();
|
EditedSongs.clear();
|
||||||
// if there are selected songs, perform operations only on them
|
// if there are selected songs, perform operations only on them
|
||||||
if (hasSelected(Tags->begin(), Tags->end()))
|
if (hasSelected(Tags->begin(), Tags->end()))
|
||||||
@@ -520,9 +702,9 @@ void TagEditor::enterPressed()
|
|||||||
for (auto it = Tags->begin(); it != Tags->end(); ++it)
|
for (auto it = Tags->begin(); it != Tags->end(); ++it)
|
||||||
EditedSongs.push_back(&it->value());
|
EditedSongs.push_back(&it->value());
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t id = TagTypes->choice();
|
size_t id = TagTypes->choice();
|
||||||
|
|
||||||
if (w == TagTypes && id == 5)
|
if (w == TagTypes && id == 5)
|
||||||
{
|
{
|
||||||
Actions::confirmAction("Number tracks?");
|
Actions::confirmAction("Number tracks?");
|
||||||
@@ -539,7 +721,7 @@ void TagEditor::enterPressed()
|
|||||||
Statusbar::print("Tracks numbered");
|
Statusbar::print("Tracks numbered");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id < 11)
|
if (id < 11)
|
||||||
{
|
{
|
||||||
MPD::Song::GetFunction get = SongInfo::Tags[id].Get;
|
MPD::Song::GetFunction get = SongInfo::Tags[id].Get;
|
||||||
@@ -637,181 +819,19 @@ void TagEditor::enterPressed()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TagEditor::mouseButtonPressed(MEVENT me)
|
|
||||||
{
|
|
||||||
auto tryPreviousColumn = [this]() -> bool {
|
|
||||||
bool result = true;
|
|
||||||
if (w != Dirs)
|
|
||||||
{
|
|
||||||
if (previousColumnAvailable())
|
|
||||||
previousColumn();
|
|
||||||
else
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
auto tryNextColumn = [this]() -> bool {
|
|
||||||
bool result = true;
|
|
||||||
if (w != Tags)
|
|
||||||
{
|
|
||||||
if (nextColumnAvailable())
|
|
||||||
nextColumn();
|
|
||||||
else
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
if (w == FParserDialog)
|
|
||||||
{
|
|
||||||
if (FParserDialog->hasCoords(me.x, me.y))
|
|
||||||
{
|
|
||||||
if (me.bstate & (BUTTON1_PRESSED | BUTTON3_PRESSED))
|
|
||||||
{
|
|
||||||
FParserDialog->Goto(me.y);
|
|
||||||
if (me.bstate & BUTTON3_PRESSED)
|
|
||||||
enterPressed();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Screen<WindowType>::mouseButtonPressed(me);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (w == FParser || w == FParserHelper)
|
|
||||||
{
|
|
||||||
if (FParser->hasCoords(me.x, me.y))
|
|
||||||
{
|
|
||||||
if (w != FParser)
|
|
||||||
{
|
|
||||||
if (previousColumnAvailable())
|
|
||||||
previousColumn();
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (size_t(me.y) < FParser->size() && (me.bstate & (BUTTON1_PRESSED | BUTTON3_PRESSED)))
|
|
||||||
{
|
|
||||||
FParser->Goto(me.y);
|
|
||||||
if (me.bstate & BUTTON3_PRESSED)
|
|
||||||
enterPressed();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Screen<WindowType>::mouseButtonPressed(me);
|
|
||||||
}
|
|
||||||
else if (FParserHelper->hasCoords(me.x, me.y))
|
|
||||||
{
|
|
||||||
if (w != FParserHelper)
|
|
||||||
{
|
|
||||||
if (nextColumnAvailable())
|
|
||||||
nextColumn();
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
scrollpadMouseButtonPressed(*FParserHelper, me);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!Dirs->empty() && Dirs->hasCoords(me.x, me.y))
|
|
||||||
{
|
|
||||||
if (!tryPreviousColumn() || !tryPreviousColumn())
|
|
||||||
return;
|
|
||||||
if (size_t(me.y) < Dirs->size() && (me.bstate & (BUTTON1_PRESSED | BUTTON3_PRESSED)))
|
|
||||||
{
|
|
||||||
Dirs->Goto(me.y);
|
|
||||||
if (me.bstate & BUTTON1_PRESSED)
|
|
||||||
enterPressed();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Screen<WindowType>::mouseButtonPressed(me);
|
|
||||||
Tags->clear();
|
|
||||||
}
|
|
||||||
else if (!TagTypes->empty() && TagTypes->hasCoords(me.x, me.y))
|
|
||||||
{
|
|
||||||
if (w != TagTypes)
|
|
||||||
{
|
|
||||||
bool success;
|
|
||||||
if (w == Dirs)
|
|
||||||
success = tryNextColumn();
|
|
||||||
else
|
|
||||||
success = tryPreviousColumn();
|
|
||||||
if (!success)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (size_t(me.y) < TagTypes->size() && (me.bstate & (BUTTON1_PRESSED | BUTTON3_PRESSED)))
|
|
||||||
{
|
|
||||||
if (!TagTypes->Goto(me.y))
|
|
||||||
return;
|
|
||||||
TagTypes->refresh();
|
|
||||||
Tags->refresh();
|
|
||||||
if (me.bstate & BUTTON3_PRESSED)
|
|
||||||
enterPressed();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Screen<WindowType>::mouseButtonPressed(me);
|
|
||||||
}
|
|
||||||
else if (!Tags->empty() && Tags->hasCoords(me.x, me.y))
|
|
||||||
{
|
|
||||||
if (!tryNextColumn() || !tryNextColumn())
|
|
||||||
return;
|
|
||||||
if (size_t(me.y) < Tags->size() && (me.bstate & (BUTTON1_PRESSED | BUTTON3_PRESSED)))
|
|
||||||
{
|
|
||||||
Tags->Goto(me.y);
|
|
||||||
Tags->refresh();
|
|
||||||
if (me.bstate & BUTTON3_PRESSED)
|
|
||||||
enterPressed();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Screen<WindowType>::mouseButtonPressed(me);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
|
||||||
bool TagEditor::allowsSearching()
|
bool TagEditor::itemAvailable()
|
||||||
{
|
{
|
||||||
return w == Dirs || w == Tags;
|
if (w == Tags)
|
||||||
|
return !Tags->empty();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TagEditor::setSearchConstraint(const std::string &constraint)
|
bool TagEditor::addItemToPlaylist(bool play)
|
||||||
{
|
{
|
||||||
if (w == Dirs)
|
return addSongToPlaylist(*Tags->currentV(), play);
|
||||||
{
|
|
||||||
m_directories_search_predicate = Regex::Filter<std::pair<std::string, std::string>>(
|
|
||||||
Regex::make(constraint, Config.regex_type),
|
|
||||||
std::bind(DirEntryMatcher, ph::_1, ph::_2, false)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if (w == Tags)
|
|
||||||
{
|
|
||||||
m_songs_search_predicate = Regex::Filter<MPD::MutableSong>(
|
|
||||||
Regex::make(constraint, Config.regex_type),
|
|
||||||
SongEntryMatcher
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TagEditor::clearConstraint()
|
|
||||||
{
|
|
||||||
if (w == Dirs)
|
|
||||||
m_directories_search_predicate.clear();
|
|
||||||
else if (w == Tags)
|
|
||||||
m_songs_search_predicate.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TagEditor::find(SearchDirection direction, bool wrap, bool skip_current)
|
|
||||||
{
|
|
||||||
bool result = false;
|
|
||||||
if (w == Dirs)
|
|
||||||
result = search(*Dirs, m_directories_search_predicate, direction, wrap, skip_current);
|
|
||||||
else if (w == Tags)
|
|
||||||
result = search(*Tags, m_songs_search_predicate, direction, wrap, skip_current);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************/
|
|
||||||
|
|
||||||
bool TagEditor::addItemToPlaylist()
|
|
||||||
{
|
|
||||||
bool result = false;
|
|
||||||
if (w == Tags && !Tags->empty())
|
|
||||||
result = addSongToPlaylist(*Tags->currentV(), false);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<MPD::Song> TagEditor::getSelectedSongs()
|
std::vector<MPD::Song> TagEditor::getSelectedSongs()
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ struct TagsWindow: NC::Menu<MPD::MutableSong>, SongList
|
|||||||
virtual std::vector<MPD::Song> getSelectedSongs() OVERRIDE;
|
virtual std::vector<MPD::Song> getSelectedSongs() OVERRIDE;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TagEditor: Screen<NC::Window *>, HasColumns, HasSongs, Searchable, Tabbable
|
struct TagEditor: Screen<NC::Window *>, HasActions, HasColumns, HasSongs, Searchable, Tabbable
|
||||||
{
|
{
|
||||||
TagEditor();
|
TagEditor();
|
||||||
|
|
||||||
@@ -62,7 +62,6 @@ struct TagEditor: Screen<NC::Window *>, HasColumns, HasSongs, Searchable, Tabbab
|
|||||||
virtual void refresh() OVERRIDE;
|
virtual void refresh() OVERRIDE;
|
||||||
virtual void update() OVERRIDE;
|
virtual void update() OVERRIDE;
|
||||||
|
|
||||||
virtual void enterPressed() OVERRIDE;
|
|
||||||
virtual void mouseButtonPressed(MEVENT) OVERRIDE;
|
virtual void mouseButtonPressed(MEVENT) OVERRIDE;
|
||||||
|
|
||||||
virtual bool isLockable() OVERRIDE { return true; }
|
virtual bool isLockable() OVERRIDE { return true; }
|
||||||
@@ -73,9 +72,14 @@ struct TagEditor: Screen<NC::Window *>, HasColumns, HasSongs, Searchable, Tabbab
|
|||||||
virtual void setSearchConstraint(const std::string &constraint) OVERRIDE;
|
virtual void setSearchConstraint(const std::string &constraint) OVERRIDE;
|
||||||
virtual void clearConstraint() OVERRIDE;
|
virtual void clearConstraint() OVERRIDE;
|
||||||
virtual bool find(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
|
virtual bool find(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
|
||||||
|
|
||||||
|
// HasActions implementation
|
||||||
|
virtual bool actionRunnable() OVERRIDE;
|
||||||
|
virtual void runAction() OVERRIDE;
|
||||||
|
|
||||||
// HasSongs implementation
|
// HasSongs implementation
|
||||||
virtual bool addItemToPlaylist() OVERRIDE;
|
virtual bool itemAvailable() OVERRIDE;
|
||||||
|
virtual bool addItemToPlaylist(bool play) OVERRIDE;
|
||||||
virtual std::vector<MPD::Song> getSelectedSongs() OVERRIDE;
|
virtual std::vector<MPD::Song> getSelectedSongs() OVERRIDE;
|
||||||
|
|
||||||
// HasColumns implementation
|
// HasColumns implementation
|
||||||
@@ -86,6 +90,7 @@ struct TagEditor: Screen<NC::Window *>, HasColumns, HasSongs, Searchable, Tabbab
|
|||||||
virtual void nextColumn() OVERRIDE;
|
virtual void nextColumn() OVERRIDE;
|
||||||
|
|
||||||
// private members
|
// private members
|
||||||
|
bool enterDirectory();
|
||||||
void LocateSong(const MPD::Song &s);
|
void LocateSong(const MPD::Song &s);
|
||||||
const std::string &CurrentDir() { return itsBrowsedDir; }
|
const std::string &CurrentDir() { return itsBrowsedDir; }
|
||||||
|
|
||||||
|
|||||||
@@ -99,7 +99,32 @@ std::wstring TinyTagEditor::title()
|
|||||||
return L"Tiny tag editor";
|
return L"Tiny tag editor";
|
||||||
}
|
}
|
||||||
|
|
||||||
void TinyTagEditor::enterPressed()
|
void TinyTagEditor::mouseButtonPressed(MEVENT me)
|
||||||
|
{
|
||||||
|
if (w.empty() || !w.hasCoords(me.x, me.y) || size_t(me.y) >= w.size())
|
||||||
|
return;
|
||||||
|
if (me.bstate & (BUTTON1_PRESSED | BUTTON3_PRESSED))
|
||||||
|
{
|
||||||
|
if (!w.Goto(me.y))
|
||||||
|
return;
|
||||||
|
if (me.bstate & BUTTON3_PRESSED)
|
||||||
|
{
|
||||||
|
w.refresh();
|
||||||
|
runAction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Screen<WindowType>::mouseButtonPressed(me);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
|
||||||
|
bool TinyTagEditor::actionRunnable()
|
||||||
|
{
|
||||||
|
return !w.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TinyTagEditor::runAction()
|
||||||
{
|
{
|
||||||
size_t option = w.choice();
|
size_t option = w.choice();
|
||||||
if (option < 19) // separator after comment
|
if (option < 19) // separator after comment
|
||||||
@@ -129,7 +154,7 @@ void TinyTagEditor::enterPressed()
|
|||||||
w.at(option).value() << NC::Format::Bold << "Filename:" << NC::Format::NoBold << ' ' << (itsEdited.getNewName().empty() ? itsEdited.getName() : itsEdited.getNewName());
|
w.at(option).value() << NC::Format::Bold << "Filename:" << NC::Format::NoBold << ' ' << (itsEdited.getNewName().empty() ? itsEdited.getName() : itsEdited.getNewName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (option == 22)
|
if (option == 22)
|
||||||
{
|
{
|
||||||
Statusbar::print("Updating tags...");
|
Statusbar::print("Updating tags...");
|
||||||
@@ -153,23 +178,7 @@ void TinyTagEditor::enterPressed()
|
|||||||
m_previous_screen->switchTo();
|
m_previous_screen->switchTo();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TinyTagEditor::mouseButtonPressed(MEVENT me)
|
/**********************************************************************/
|
||||||
{
|
|
||||||
if (w.empty() || !w.hasCoords(me.x, me.y) || size_t(me.y) >= w.size())
|
|
||||||
return;
|
|
||||||
if (me.bstate & (BUTTON1_PRESSED | BUTTON3_PRESSED))
|
|
||||||
{
|
|
||||||
if (!w.Goto(me.y))
|
|
||||||
return;
|
|
||||||
if (me.bstate & BUTTON3_PRESSED)
|
|
||||||
{
|
|
||||||
w.refresh();
|
|
||||||
enterPressed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Screen<WindowType>::mouseButtonPressed(me);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TinyTagEditor::SetEdited(const MPD::Song &s)
|
void TinyTagEditor::SetEdited(const MPD::Song &s)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
#include "mutable_song.h"
|
#include "mutable_song.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
|
|
||||||
struct TinyTagEditor: Screen<NC::Menu<NC::Buffer>>
|
struct TinyTagEditor: Screen<NC::Menu<NC::Buffer>>, HasActions
|
||||||
{
|
{
|
||||||
TinyTagEditor();
|
TinyTagEditor();
|
||||||
|
|
||||||
@@ -42,12 +42,15 @@ struct TinyTagEditor: Screen<NC::Menu<NC::Buffer>>
|
|||||||
|
|
||||||
virtual void update() OVERRIDE { }
|
virtual void update() OVERRIDE { }
|
||||||
|
|
||||||
virtual void enterPressed() OVERRIDE;
|
|
||||||
virtual void mouseButtonPressed(MEVENT me) OVERRIDE;
|
virtual void mouseButtonPressed(MEVENT me) OVERRIDE;
|
||||||
|
|
||||||
virtual bool isLockable() OVERRIDE { return false; }
|
virtual bool isLockable() OVERRIDE { return false; }
|
||||||
virtual bool isMergable() OVERRIDE { return true; }
|
virtual bool isMergable() OVERRIDE { return true; }
|
||||||
|
|
||||||
|
// HasActions implemenetation
|
||||||
|
virtual bool actionRunnable() OVERRIDE;
|
||||||
|
virtual void runAction() OVERRIDE;
|
||||||
|
|
||||||
// private members
|
// private members
|
||||||
void SetEdited(const MPD::Song &);
|
void SetEdited(const MPD::Song &);
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ struct Visualizer: Screen<NC::Window>, Tabbable
|
|||||||
|
|
||||||
virtual int windowTimeout() OVERRIDE;
|
virtual int windowTimeout() OVERRIDE;
|
||||||
|
|
||||||
virtual void enterPressed() OVERRIDE { }
|
|
||||||
virtual void mouseButtonPressed(MEVENT) OVERRIDE { }
|
virtual void mouseButtonPressed(MEVENT) OVERRIDE { }
|
||||||
|
|
||||||
virtual bool isLockable() OVERRIDE { return true; }
|
virtual bool isLockable() OVERRIDE { return true; }
|
||||||
|
|||||||
Reference in New Issue
Block a user