Merge branch '0.6.x'
Conflicts: NEWS configure.ac src/media_library.cpp src/playlist_editor.cpp src/tags.cpp
This commit is contained in:
6
NEWS
6
NEWS
@@ -5,10 +5,14 @@ ncmpcpp-0.7 (????-??-??)
|
|||||||
* It is now possible to abort the current action using Ctrl-C or Ctrl-G in prompt mode. As a result, empty value is no longer a special value that aborts most of the actions.
|
* It is now possible to abort the current action using Ctrl-C or Ctrl-G in prompt mode. As a result, empty value is no longer a special value that aborts most of the actions.
|
||||||
* Directories and playlists in browser can now be sorted by modification time.
|
* Directories and playlists in browser can now be sorted by modification time.
|
||||||
|
|
||||||
ncmpcpp-0.6.1 (????-??-??)
|
ncmpcpp-0.6.1 (2014-11-06)
|
||||||
|
|
||||||
* Comment tag is now properly written to mp3 files.
|
* Comment tag is now properly written to mp3 files.
|
||||||
* Only ID3v2.4 tags are now saved to mp3 files.
|
* Only ID3v2.4 tags are now saved to mp3 files.
|
||||||
|
* Mouse scrolling with newer ncurses API now works properly.
|
||||||
|
* Adding songs from an album in media library now works properly with fetch delay.
|
||||||
|
* Adding songs from a playlist in playlist editor now works properly with fetch delay.
|
||||||
|
* Trying to fetch lyrics from an empty list doesn't crash the application anymore.
|
||||||
|
|
||||||
ncmpcpp-0.6 (2014-10-25)
|
ncmpcpp-0.6 (2014-10-25)
|
||||||
|
|
||||||
|
|||||||
@@ -326,15 +326,19 @@ void MouseEvent::run()
|
|||||||
|
|
||||||
m_old_mouse_event = m_mouse_event;
|
m_old_mouse_event = m_mouse_event;
|
||||||
getmouse(&m_mouse_event);
|
getmouse(&m_mouse_event);
|
||||||
|
|
||||||
|
# if NCURSES_MOUSE_VERSION == 1
|
||||||
// workaround shitty ncurses behavior introduced in >=5.8, when we mysteriously get
|
// workaround shitty ncurses behavior introduced in >=5.8, when we mysteriously get
|
||||||
// a few times after ncmpcpp startup 2^27 code instead of BUTTON{1,3}_RELEASED. since that
|
// a few times after ncmpcpp startup 2^27 code instead of BUTTON{1,3}_RELEASED. since that
|
||||||
// 2^27 thing shows constantly instead of BUTTON2_PRESSED, it was redefined to be recognized
|
// 2^27 thing shows constantly instead of BUTTON2_PRESSED, it was redefined to be recognized
|
||||||
// as BUTTON2_PRESSED. but clearly we don't want to trigger behavior bound to BUTTON2
|
// as BUTTON5_PRESSED. but clearly we don't want to trigger behavior bound to BUTTON5
|
||||||
// after BUTTON{1,3} was pressed. so, here is the workaround: if last event was BUTTON{1,3}_PRESSED,
|
// after BUTTON{1,3} was pressed. so, here is the workaround: if last event was BUTTON{1,3}_PRESSED,
|
||||||
// we MUST get BUTTON{1,3}_RELEASED afterwards. if we get BUTTON2_PRESSED, erroneus behavior
|
// we MUST get BUTTON{1,3}_RELEASED afterwards. if we get BUTTON5_PRESSED, erroneus behavior
|
||||||
// is about to occur and we need to prevent that.
|
// is about to occur and we need to prevent that.
|
||||||
if (m_old_mouse_event.bstate & (BUTTON1_PRESSED | BUTTON3_PRESSED) && m_mouse_event.bstate & BUTTON2_PRESSED)
|
if (m_old_mouse_event.bstate & (BUTTON1_PRESSED | BUTTON3_PRESSED) && m_mouse_event.bstate & BUTTON5_PRESSED)
|
||||||
return;
|
return;
|
||||||
|
# endif // NCURSES_MOUSE_VERSION == 1
|
||||||
|
|
||||||
if (m_mouse_event.bstate & BUTTON1_PRESSED
|
if (m_mouse_event.bstate & BUTTON1_PRESSED
|
||||||
&& m_mouse_event.y == LINES-(Config.statusbar_visibility ? 2 : 1)
|
&& m_mouse_event.y == LINES-(Config.statusbar_visibility ? 2 : 1)
|
||||||
) // progressbar
|
) // progressbar
|
||||||
@@ -353,17 +357,17 @@ void MouseEvent::run()
|
|||||||
{
|
{
|
||||||
Mpd.Toggle();
|
Mpd.Toggle();
|
||||||
}
|
}
|
||||||
else if ((m_mouse_event.bstate & BUTTON2_PRESSED || m_mouse_event.bstate & BUTTON4_PRESSED)
|
else if ((m_mouse_event.bstate & BUTTON5_PRESSED || m_mouse_event.bstate & BUTTON4_PRESSED)
|
||||||
&& (Config.header_visibility || Config.design == Design::Alternative)
|
&& (Config.header_visibility || Config.design == Design::Alternative)
|
||||||
&& m_mouse_event.y == 0 && size_t(m_mouse_event.x) > COLS-VolumeState.length()
|
&& m_mouse_event.y == 0 && size_t(m_mouse_event.x) > COLS-VolumeState.length()
|
||||||
) // volume
|
) // volume
|
||||||
{
|
{
|
||||||
if (m_mouse_event.bstate & BUTTON2_PRESSED)
|
if (m_mouse_event.bstate & BUTTON5_PRESSED)
|
||||||
get(Type::VolumeDown).execute();
|
get(Type::VolumeDown).execute();
|
||||||
else
|
else
|
||||||
get(Type::VolumeUp).execute();
|
get(Type::VolumeUp).execute();
|
||||||
}
|
}
|
||||||
else if (m_mouse_event.bstate & (BUTTON1_PRESSED | BUTTON2_PRESSED | BUTTON3_PRESSED | BUTTON4_PRESSED))
|
else if (m_mouse_event.bstate & (BUTTON1_PRESSED | BUTTON3_PRESSED | BUTTON4_PRESSED | BUTTON5_PRESSED))
|
||||||
myScreen->mouseButtonPressed(m_mouse_event);
|
myScreen->mouseButtonPressed(m_mouse_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -122,7 +122,11 @@ protected:
|
|||||||
|
|
||||||
struct MouseEvent : public BaseAction
|
struct MouseEvent : public BaseAction
|
||||||
{
|
{
|
||||||
MouseEvent() : BaseAction(Type::MouseEvent, "mouse_event") { }
|
MouseEvent() : BaseAction(Type::MouseEvent, "mouse_event")
|
||||||
|
{
|
||||||
|
m_old_mouse_event.bstate = 0;
|
||||||
|
m_mouse_event.bstate = 0;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool canBeRun() const;
|
virtual bool canBeRun() const;
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ inline MPD::Song *currentSong(BaseScreen *screen)
|
|||||||
{
|
{
|
||||||
MPD::Song *ptr = 0;
|
MPD::Song *ptr = 0;
|
||||||
auto pl = proxySongList(screen);
|
auto pl = proxySongList(screen);
|
||||||
if (pl)
|
if (pl && !pl.empty())
|
||||||
ptr = pl.currentSong();
|
ptr = pl.currentSong();
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,6 +107,9 @@ void Lyrics::switchTo()
|
|||||||
# endif // HAVE_CURL_CURL_H
|
# endif // HAVE_CURL_CURL_H
|
||||||
|
|
||||||
auto s = currentSong(myScreen);
|
auto s = currentSong(myScreen);
|
||||||
|
if (!s)
|
||||||
|
return;
|
||||||
|
|
||||||
if (SetSong(*s))
|
if (SetSong(*s))
|
||||||
{
|
{
|
||||||
SwitchTo::execute(this);
|
SwitchTo::execute(this);
|
||||||
|
|||||||
@@ -57,6 +57,18 @@ size_t itsRightColStartX;
|
|||||||
|
|
||||||
typedef MediaLibrary::AlbumEntry AlbumEntry;
|
typedef MediaLibrary::AlbumEntry AlbumEntry;
|
||||||
|
|
||||||
|
MPD::SongIterator getSongsFromAlbum(const AlbumEntry &album)
|
||||||
|
{
|
||||||
|
Mpd.StartSearch(true);
|
||||||
|
Mpd.AddSearch(Config.media_lib_primary_tag, album.entry().tag());
|
||||||
|
if (!album.isAllTracksEntry())
|
||||||
|
{
|
||||||
|
Mpd.AddSearch(MPD_TAG_ALBUM, album.entry().album());
|
||||||
|
Mpd.AddSearch(MPD_TAG_DATE, album.entry().date());
|
||||||
|
}
|
||||||
|
return Mpd.CommitSearchSongs();
|
||||||
|
}
|
||||||
|
|
||||||
std::string AlbumToString(const AlbumEntry &ae);
|
std::string AlbumToString(const AlbumEntry &ae);
|
||||||
std::string SongToString(const MPD::Song &s);
|
std::string SongToString(const MPD::Song &s);
|
||||||
|
|
||||||
@@ -707,7 +719,15 @@ std::vector<MPD::Song> MediaLibrary::getSelectedSongs()
|
|||||||
}
|
}
|
||||||
// if no item is selected, add songs from right column
|
// if no item is selected, add songs from right column
|
||||||
if (!any_selected && !Albums.empty())
|
if (!any_selected && !Albums.empty())
|
||||||
result.insert(result.end(), Songs.beginV(), Songs.endV());
|
{
|
||||||
|
size_t begin = result.size();
|
||||||
|
std::copy(
|
||||||
|
std::make_move_iterator(getSongsFromAlbum(Albums.current()->value().entry())),
|
||||||
|
std::make_move_iterator(MPD::SongIterator()),
|
||||||
|
std::back_inserter(result)
|
||||||
|
);
|
||||||
|
std::sort(result.begin()+begin, result.end(), SortSongs(false));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (isActiveWindow(Songs))
|
else if (isActiveWindow(Songs))
|
||||||
{
|
{
|
||||||
@@ -979,7 +999,11 @@ void MediaLibrary::AddToPlaylist(bool add_n_play)
|
|||||||
}
|
}
|
||||||
else if (isActiveWindow(Albums))
|
else if (isActiveWindow(Albums))
|
||||||
{
|
{
|
||||||
bool success = addSongsToPlaylist(Songs.beginV(), Songs.endV(), add_n_play, -1);
|
std::vector<MPD::Song> list(
|
||||||
|
std::make_move_iterator(getSongsFromAlbum(Albums.current()->value())),
|
||||||
|
std::make_move_iterator(MPD::SongIterator())
|
||||||
|
);
|
||||||
|
bool success = addSongsToPlaylist(list.begin(), list.end(), add_n_play, -1);
|
||||||
Statusbar::printf("Songs from album \"%1%\" added%2%",
|
Statusbar::printf("Songs from album \"%1%\" added%2%",
|
||||||
Albums.current()->value().entry().album(), withErrors(success)
|
Albums.current()->value().entry().album(), withErrors(success)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -220,11 +220,13 @@ ProxySongList PlaylistEditor::contentProxyList()
|
|||||||
|
|
||||||
void PlaylistEditor::AddToPlaylist(bool add_n_play)
|
void PlaylistEditor::AddToPlaylist(bool add_n_play)
|
||||||
{
|
{
|
||||||
std::vector<MPD::Song> list;
|
|
||||||
|
|
||||||
if (isActiveWindow(Playlists) && !Playlists.empty())
|
if (isActiveWindow(Playlists) && !Playlists.empty())
|
||||||
{
|
{
|
||||||
bool success = addSongsToPlaylist(Content.beginV(), Content.endV(), add_n_play, -1);
|
std::vector<MPD::Song> list(
|
||||||
|
std::make_move_iterator(Mpd.GetPlaylistContent(Playlists.current()->value().path())),
|
||||||
|
std::make_move_iterator(MPD::SongIterator())
|
||||||
|
);
|
||||||
|
bool success = addSongsToPlaylist(list.begin(), list.end(), add_n_play, -1);
|
||||||
Statusbar::printf("Playlist \"%1%\" loaded%2%",
|
Statusbar::printf("Playlist \"%1%\" loaded%2%",
|
||||||
Playlists.current()->value().path(), withErrors(success)
|
Playlists.current()->value().path(), withErrors(success)
|
||||||
);
|
);
|
||||||
@@ -414,8 +416,14 @@ std::vector<MPD::Song> PlaylistEditor::getSelectedSongs()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if no item is selected, add songs from right column
|
// if no item is selected, add songs from right column
|
||||||
if (!any_selected && !Content.empty())
|
if (!any_selected && !Playlists.empty())
|
||||||
std::copy(Content.beginV(), Content.endV(), std::back_inserter(result));
|
{
|
||||||
|
std::copy(
|
||||||
|
std::make_move_iterator(Mpd.GetPlaylistContent(Playlists.current()->value().path())),
|
||||||
|
std::make_move_iterator(MPD::SongIterator()),
|
||||||
|
std::back_inserter(result)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (isActiveWindow(Content))
|
else if (isActiveWindow(Content))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ void drawSeparator(int x)
|
|||||||
|
|
||||||
void genericMouseButtonPressed(NC::Window &w, MEVENT me)
|
void genericMouseButtonPressed(NC::Window &w, MEVENT me)
|
||||||
{
|
{
|
||||||
if (me.bstate & BUTTON2_PRESSED)
|
if (me.bstate & BUTTON5_PRESSED)
|
||||||
{
|
{
|
||||||
if (Config.mouse_list_scroll_whole_page)
|
if (Config.mouse_list_scroll_whole_page)
|
||||||
w.scroll(NC::Scroll::PageDown);
|
w.scroll(NC::Scroll::PageDown);
|
||||||
@@ -58,7 +58,7 @@ void genericMouseButtonPressed(NC::Window &w, MEVENT me)
|
|||||||
|
|
||||||
void scrollpadMouseButtonPressed(NC::Scrollpad &w, MEVENT me)
|
void scrollpadMouseButtonPressed(NC::Scrollpad &w, MEVENT me)
|
||||||
{
|
{
|
||||||
if (me.bstate & BUTTON2_PRESSED)
|
if (me.bstate & BUTTON5_PRESSED)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < Config.lines_scrolled; ++i)
|
for (size_t i = 0; i < Config.lines_scrolled; ++i)
|
||||||
w.scroll(NC::Scroll::Down);
|
w.scroll(NC::Scroll::Down);
|
||||||
|
|||||||
13
src/window.h
13
src/window.h
@@ -95,13 +95,12 @@
|
|||||||
// undefine scroll macro as it collides with Window::scroll
|
// undefine scroll macro as it collides with Window::scroll
|
||||||
#undef scroll
|
#undef scroll
|
||||||
|
|
||||||
#ifndef USE_PDCURSES
|
#if !defined(USE_PDCURSES) && NCURSES_MOUSE_VERSION == 1
|
||||||
// NOTICE: redefine BUTTON2_PRESSED as it doesn't always work, I noticed
|
// NOTICE: define BUTTON5_PRESSED to be BUTTON2_PRESSED with additional mask
|
||||||
// that it sometimes returns 134217728 (2^27) instead of expected mask, so the
|
// (I noticed that it sometimes returns 134217728 (2^27) instead of expected
|
||||||
// modified define does it right but is rather experimental.
|
// mask, so the modified define does it right.
|
||||||
# undef BUTTON2_PRESSED
|
# define BUTTON5_PRESSED (BUTTON2_PRESSED | (1U << 27))
|
||||||
# define BUTTON2_PRESSED (NCURSES_MOUSE_MASK(2, NCURSES_BUTTON_PRESSED) | (1U << 27))
|
#endif // !defined(USE_PDCURSES) && NCURSES_MOUSE_VERSION == 1
|
||||||
#endif // USE_PDCURSES
|
|
||||||
|
|
||||||
// workaraund for win32
|
// workaraund for win32
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
|||||||
Reference in New Issue
Block a user