diff --git a/configure.in b/configure.in index 18084b0e..417e8186 100644 --- a/configure.in +++ b/configure.in @@ -57,7 +57,7 @@ AC_CHECK_HEADERS([langinfo.h], , AC_MSG_WARN(locale detection disabled)) dnl ============================== dnl = checking for libmpdclient2 = dnl ============================== -PKG_CHECK_MODULES([libmpdclient], [libmpdclient >= 2.1], [ +PKG_CHECK_MODULES([libmpdclient], [libmpdclient >= 2.8], [ AC_SUBST(libmpdclient_LIBS) AC_SUBST(libmpdclient_CFLAGS) CPPFLAGS="$CPPFLAGS $libmpdclient_CFLAGS" @@ -67,7 +67,7 @@ PKG_CHECK_MODULES([libmpdclient], [libmpdclient >= 2.1], [ AC_MSG_ERROR([missing mpd/client.h header]) ) ], - AC_MSG_ERROR([libmpdclient >= 2.1 is required!]) + AC_MSG_ERROR([libmpdclient >= 2.8 is required!]) ) dnl ======================== diff --git a/doc/config b/doc/config index 9cb29c09..351de903 100644 --- a/doc/config +++ b/doc/config @@ -137,6 +137,7 @@ ## %p - performer ## %d - disc ## %C - comment +## %P - priority ## $R - begin right alignment ## ## you can also put them in { } and then it will be displayed diff --git a/doc/ncmpcpp.1 b/doc/ncmpcpp.1 index c5799143..371c4c68 100644 --- a/doc/ncmpcpp.1 +++ b/doc/ncmpcpp.1 @@ -413,6 +413,7 @@ For song format you can use: %p - performer %d - disc %C - comment + %P - priority $R - begin right alignment You can also put them in { } and then they will be displayed only if all requested values are available and/or define alternate value with { }|{ } e.g. {%a - %t}|{%f} will check if artist and title tags are available and if they are, display them. Otherwise it'll display filename. diff --git a/src/actions.cpp b/src/actions.cpp index 0304f15c..21ccb02f 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -2250,6 +2250,40 @@ void RefetchArtistInfo::Run() # endif // HAVE_CURL_CURL_H } +bool SetSelectedItemsPriority::canBeRun() const +{ + return myScreen->ActiveWindow() == myPlaylist->Items; +} + +void SetSelectedItemsPriority::Run() +{ + using Global::wFooter; + + assert(myScreen->ActiveWindow() == myPlaylist->Items); + if (myPlaylist->Items->Empty()) + return; + + if (Mpd.Version() < 17) + { + ShowMessage("Priorities are supported in MPD >= 0.17.0"); + return; + } + + LockStatusbar(); + Statusbar() << "Set priority [0-255]: "; + std::string strprio = wFooter->GetString(); + UnlockStatusbar(); + if (!isInteger(strprio.c_str())) + return; + int prio = atoi(strprio.c_str()); + if (prio < 0 || prio > 255) + { + ShowMessage("Entered number is out of range"); + return; + } + myPlaylist->SetSelectedItemsPriority(prio); +} + void ShowSongInfo::Run() { mySongInfo->SwitchTo(); @@ -2594,6 +2628,7 @@ Action *Action::Get(ActionType at) insertAction(new ToggleLibraryTagType()); insertAction(new RefetchLyrics()); insertAction(new RefetchArtistInfo()); + insertAction(new SetSelectedItemsPriority()); insertAction(new ShowSongInfo()); insertAction(new ShowArtistInfo()); insertAction(new ShowLyrics()); diff --git a/src/actions.h b/src/actions.h index a3ffa49a..9e644433 100644 --- a/src/actions.h +++ b/src/actions.h @@ -43,10 +43,10 @@ enum ActionType aApplyFilter, aDisableFilter, aFind, aFindItemForward, aFindItemBackward, aNextFoundItem, aPreviousFoundItem, aToggleFindMode, aToggleReplayGainMode, aToggleSpaceMode, aToggleAddMode, aToggleMouse, aToggleBitrateVisibility, aAddRandomItems, aToggleBrowserSortMode, aToggleLibraryTagType, - aRefetchLyrics, aRefetchArtistInfo, aShowSongInfo, aShowArtistInfo, aShowLyrics, aQuit, - aNextScreen, aPreviousScreen, aShowHelp, aShowPlaylist, aShowBrowser, aShowSearchEngine, - aShowMediaLibrary, aShowPlaylistEditor, aShowTagEditor, aShowOutputs, aShowVisualizer, - aShowClock, aShowServerInfo + aRefetchLyrics, aRefetchArtistInfo, aSetSelectedItemsPriority, aShowSongInfo, aShowArtistInfo, + aShowLyrics, aQuit, aNextScreen, aPreviousScreen, aShowHelp, aShowPlaylist, aShowBrowser, + aShowSearchEngine, aShowMediaLibrary, aShowPlaylistEditor, aShowTagEditor, aShowOutputs, + aShowVisualizer, aShowClock, aShowServerInfo }; struct Action @@ -707,6 +707,13 @@ struct RefetchArtistInfo : public Action virtual void Run(); }; +struct SetSelectedItemsPriority : public Action +{ + SetSelectedItemsPriority() : Action(aSetSelectedItemsPriority, "set_selected_items_priority") { } + virtual bool canBeRun() const; + virtual void Run(); +}; + struct ShowSongInfo : public Action { ShowSongInfo() : Action(aShowSongInfo, "show_song_info") { } diff --git a/src/conv.cpp b/src/conv.cpp index 9df81629..56121ad6 100644 --- a/src/conv.cpp +++ b/src/conv.cpp @@ -178,6 +178,8 @@ MPD::Song::GetFunction toGetFunction(char c) return &MPD::Song::GetComment; case 't': return &MPD::Song::GetTitle; + case 'P': + return &MPD::Song::GetPriority; default: return 0; } diff --git a/src/display.cpp b/src/display.cpp index 6c9b07db..64b6df17 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -50,8 +50,7 @@ namespace return U("Album"); case 'y': return U("Date"); - case 'n': - case 'N': + case 'n': case 'N': return U("Track"); case 'g': return U("Genre"); @@ -63,6 +62,8 @@ namespace return U("Disc"); case 'C': return U("Comment"); + case 'P': + return U("Priority"); default: return U("?"); } diff --git a/src/help.cpp b/src/help.cpp index de7cf2b6..9d34203a 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -269,6 +269,7 @@ void Help::GetKeybindings() KeyDesc(aDelete, "Delete selected item(s) from playlist"); KeyDesc(aClearMainPlaylist, "Clear playlist"); KeyDesc(aCropMainPlaylist, "Clear playlist except playing/selected items"); + KeyDesc(aSetSelectedItemsPriority, "Set priority of selected items"); KeyDesc(aMoveSelectedItemsUp, "Move selected item(s) up"); KeyDesc(aMoveSelectedItemsDown, "Move selected item(s) down"); KeyDesc(aMoveSelectedItemsTo, "Move selected item(s) to cursor position"); diff --git a/src/helpers.cpp b/src/helpers.cpp index 6cecec01..11aa2347 100644 --- a/src/helpers.cpp +++ b/src/helpers.cpp @@ -481,3 +481,14 @@ std::basic_string Scroller(const std::basic_string &str, s result = s; return result; } + +bool isInteger(const char *s) +{ + assert(s); + if (*s == '\0') + return false; + for (const char *it = s; *it != '\0'; ++it) + if (!isdigit(*it) && (it != s || *it != '-')) + return false; + return true; +} diff --git a/src/helpers.h b/src/helpers.h index 43639475..d0a85954 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -221,5 +221,7 @@ std::basic_string Scroller(const std::basic_string &str, s bool askYesNoQuestion(const Buffer &question, void (*callback)()); +bool isInteger(const char *s); + #endif diff --git a/src/mpdpp.cpp b/src/mpdpp.cpp index 7a2e82af..285d0573 100644 --- a/src/mpdpp.cpp +++ b/src/mpdpp.cpp @@ -839,6 +839,22 @@ void MPD::Connection::SetCrossfade(unsigned crossfade) } } +bool MPD::Connection::SetPriority(const Song &s, int prio) +{ + if (!itsConnection) + return false; + if (!isCommandsListEnabled) + { + GoBusy(); + return mpd_run_prio_id(itsConnection, prio, s.GetID()); + } + else + { + assert(!isIdle); + return mpd_send_prio_id(itsConnection, prio, s.GetID()); + } +} + int MPD::Connection::AddSong(const std::string &path, int pos) { if (!itsConnection) diff --git a/src/mpdpp.h b/src/mpdpp.h index bfacf403..62166593 100644 --- a/src/mpdpp.h +++ b/src/mpdpp.h @@ -174,6 +174,8 @@ namespace MPD std::string GetReplayGainMode(); void SetReplayGainMode(ReplayGainMode); + bool SetPriority(const Song &s, int prio); + int AddSong(const std::string &, int = -1); // returns id of added song int AddSong(const Song &, int = -1); // returns id of added song bool AddRandomTag(mpd_tag_type, size_t); diff --git a/src/playlist.cpp b/src/playlist.cpp index db084539..9214de99 100644 --- a/src/playlist.cpp +++ b/src/playlist.cpp @@ -607,3 +607,16 @@ bool Playlist::Add(const MPD::SongList &l, bool play, int position) return true; } + +void Playlist::SetSelectedItemsPriority(int prio) +{ + std::vector list; + myPlaylist->Items->GetSelected(list); + if (list.empty()) + list.push_back(Items->Choice()); + Mpd.StartCommandsList(); + for (std::vector::const_iterator it = list.begin(); it != list.end(); ++it) + Mpd.SetPriority((*Items)[*it], prio); + if (Mpd.CommitCommandsList()) + ShowMessage("Priority set"); +} diff --git a/src/playlist.h b/src/playlist.h index 62fc4980..ecd4d561 100644 --- a/src/playlist.h +++ b/src/playlist.h @@ -78,6 +78,8 @@ class Playlist : public Screen bool Add(const MPD::Song &s, bool in_playlist, bool play, int position = -1); bool Add(const MPD::SongList &l, bool play, int position = -1); + void SetSelectedItemsPriority(int prio); + static std::string SongToString(const MPD::Song &, void *); static std::string SongInColumnsToString(const MPD::Song &, void *); diff --git a/src/settings.cpp b/src/settings.cpp index 6abe2597..8ec5eb4d 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -246,6 +246,7 @@ void NcmpcppKeys::GenerateKeybindings() BIND('`', aRefetchLyrics); BIND('`', aRefetchArtistInfo); BIND('`', aAddRandomItems); + BIND(KEY_CTRL_P, aSetSelectedItemsPriority); BIND('q', aQuit); BIND('k', aScrollUp); diff --git a/src/song.cpp b/src/song.cpp index adb41e99..f5c76cd0 100644 --- a/src/song.cpp +++ b/src/song.cpp @@ -84,6 +84,13 @@ std::string MPD::Song::GetLength(unsigned pos) const return !len ? "-:--" : ShowTime(len); } +std::string MPD::Song::GetPriority(unsigned pos) const +{ + if (pos > 0) + return ""; + return IntoStr(GetPrio()); +} + void MPD::Song::Localize() { # ifdef HAVE_ICONV_H diff --git a/src/song.h b/src/song.h index c682de41..cba72824 100644 --- a/src/song.h +++ b/src/song.h @@ -57,6 +57,7 @@ namespace MPD std::string GetDisc(unsigned = 0) const; std::string GetComment(unsigned = 0) const; std::string GetLength(unsigned = 0) const; + std::string GetPriority(unsigned = 0) const; std::string GetTags(GetFunction) const; @@ -64,6 +65,7 @@ namespace MPD unsigned GetTotalLength() const { return mpd_song_get_duration(itsSong); } unsigned GetPosition() const { return mpd_song_get_pos(itsSong); } unsigned GetID() const { return mpd_song_get_id(itsSong); } + unsigned GetPrio() const { return mpd_song_get_prio(itsSong); } time_t GetMTime() const { return mpd_song_get_last_modified(itsSong); }