diff --git a/src/helpers.cpp b/src/helpers.cpp index e474cfcd..9d70a00a 100644 --- a/src/helpers.cpp +++ b/src/helpers.cpp @@ -132,54 +132,6 @@ void PlaylistDeleteSong(const string &path, int id) mPlaylistEditor->DeleteOption(id+1); } -bool MoveSongUp(int pos) -{ - if (pos > 0 && !mPlaylist->Empty() && current_screen == csPlaylist) - { - mPlaylist->Swap(pos, pos-1); - Mpd->Move(pos, pos-1); - return true; - } - else - return false; -} - -bool MoveSongDown(int pos) -{ - if (pos+1 < mPlaylist->Size() && !mPlaylist->Empty() && current_screen == csPlaylist) - { - mPlaylist->Swap(pos+1, pos); - Mpd->Move(pos, pos+1); - return true; - } - else - return false; -} - -bool PlaylistMoveSongUp(const string &path, int pos) -{ - if (pos > 0 && !mPlaylistEditor->Empty() && current_screen == csPlaylistEditor) - { - mPlaylistEditor->Swap(pos, pos-1); - Mpd->Move(path, pos, pos-1); - return true; - } - else - return false; -} - -bool PlaylistMoveSongDown(const string &path, int pos) -{ - if (pos+1 < mPlaylistEditor->Size() && !mPlaylistEditor->Empty() && current_screen == csPlaylistEditor) - { - mPlaylistEditor->Swap(pos+1, pos); - Mpd->Move(path, pos, pos+1); - return true; - } - else - return false; -} - string DisplayKeys(int *key, int size) { bool backspace = 1; @@ -258,7 +210,7 @@ bool CaseInsensitiveComparison(string a, string b) void WindowTitle(const string &status) { if (TERMINAL_TYPE != "linux" && Config.set_window_title) - printf("\033]0;%s\7",status.c_str()); + printf("\033]0;%s\7",status.c_str()); } string TotalPlaylistLength() diff --git a/src/helpers.h b/src/helpers.h index 10c0aafa..504296b2 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -36,10 +36,6 @@ void UpdateFoundList(const SongList &, Menu *); void DeleteSong(int); void PlaylistDeleteSong(const string &, int); -bool MoveSongUp(int); -bool MoveSongDown(int); -bool PlaylistMoveSongUp(const string &, int); -bool PlaylistMoveSongDown(const string &, int); string DisplayKeys(int *, int = 2); bool Keypressed(int, const int *); diff --git a/src/mpdpp.cpp b/src/mpdpp.cpp index ce899565..1cb65c3b 100644 --- a/src/mpdpp.cpp +++ b/src/mpdpp.cpp @@ -22,7 +22,7 @@ const string playlist_max_message = "playlist is at the max size"; -MPDConnection::MPDConnection() : isConnected(0), itsMaxPlaylistLength(-1), MPD_HOST("localhost"), MPD_PORT(6600), MPD_TIMEOUT(15), itsUpdater(0), itsErrorHandler(0) +MPDConnection::MPDConnection() : isConnected(0), itsErrorCode(0), itsMaxPlaylistLength(-1), MPD_HOST("localhost"), MPD_PORT(6600), MPD_TIMEOUT(15), itsUpdater(0), itsErrorHandler(0) { itsConnection = 0; itsCurrentStats = 0; @@ -89,6 +89,18 @@ void MPDConnection::Disconnect() ClearQueue(); } +void MPDConnection::SetHostname(const string &host) +{ + int at = host.find("@"); + if (at != string::npos) + { + MPD_PASSWORD = host.substr(0, at); + MPD_HOST = host.substr(at+1); + } + else + MPD_HOST = host; +} + void MPDConnection::SendPassword() const { mpd_sendPasswordCommand(itsConnection, MPD_PASSWORD.c_str()); @@ -486,6 +498,31 @@ void MPDConnection::QueueDeleteSongId(int id) } } +void MPDConnection::QueueMove(int from, int to) +{ + if (isConnected) + { + QueueCommand *q = new QueueCommand; + q->type = qctMove; + q->id = from; + q->id2 = to; + itsQueue.push_back(q); + } +} + +void MPDConnection::QueueMove(const string &playlist, int from, int to) +{ + if (isConnected) + { + QueueCommand *q = new QueueCommand; + q->type = qctPlaylistMove; + q->playlist_path = playlist; + q->id = from; + q->id2 = to; + itsQueue.push_back(q); + } +} + void MPDConnection::QueueDeleteFromPlaylist(const string &playlist, int pos) { if (isConnected) @@ -520,6 +557,12 @@ bool MPDConnection::CommitQueue() case qctDeleteID: mpd_sendDeleteIdCommand(itsConnection, (*it)->id); break; + case qctMove: + mpd_sendMoveCommand(itsConnection, (*it)->id, (*it)->id2); + break; + case qctPlaylistMove: + mpd_sendPlaylistMoveCommand(itsConnection, (char *) (*it)->playlist_path.c_str(), (*it)->id, (*it)->id2); + break; case qctDeleteFromPlaylist: mpd_sendPlaylistDeleteCommand(itsConnection, (char *) (*it)->playlist_path.c_str(), (*it)->id); break; @@ -711,7 +754,7 @@ void MPDConnection::GetDirectoryRecursive(const string &path, SongList &v) const int MPDConnection::CheckForErrors() { - int errid = 0; + itsErrorCode = 0; if (itsConnection->error) { if (itsConnection->error == MPD_ERROR_ACK) @@ -723,19 +766,19 @@ int MPDConnection::CheckForErrors() if (itsErrorHandler) itsErrorHandler(this, itsConnection->errorCode, itsConnection->errorStr, itsErrorHandlerUserdata); - errid = itsConnection->errorCode; + itsErrorCode = itsConnection->errorCode; } else { isConnected = 0; // the rest of errors are fatal to connection if (itsErrorHandler) itsErrorHandler(this, itsConnection->error, itsConnection->errorStr, itsErrorHandlerUserdata); - errid = itsConnection->error; + itsErrorCode = itsConnection->error; } itsLastErrorMessage = itsConnection->errorStr; mpd_clearError(itsConnection); } - return errid; + return itsErrorCode; } void MPDConnection::ClearQueue() diff --git a/src/mpdpp.h b/src/mpdpp.h index d27b3db6..70dfb8c7 100644 --- a/src/mpdpp.h +++ b/src/mpdpp.h @@ -24,7 +24,7 @@ #include "ncmpcpp.h" #include "song.h" -enum QueueCommandType { qctAdd, qctAddToPlaylist, qctDelete, qctDeleteID, qctDeleteFromPlaylist }; +enum QueueCommandType { qctAdd, qctAddToPlaylist, qctDelete, qctDeleteID, qctMove, qctPlaylistMove, qctDeleteFromPlaylist }; enum ItemType { itDirectory, itSong, itPlaylist }; enum PlayerState { psUnknown, psStop, psPlay, psPause }; @@ -45,11 +45,12 @@ struct MPDStatusChanges struct QueueCommand { - QueueCommand() : id(0) { } + QueueCommand() : id(0), id2(0) { } QueueCommandType type; string playlist_path; string item_path; int id; + int id2; }; struct Item @@ -80,10 +81,10 @@ class MPDConnection bool Connected() const; void Disconnect(); - void SetHostname(string hostname) { MPD_HOST = hostname; } + void SetHostname(const string &); void SetPort(int port) { MPD_PORT = port; } void SetTimeout(int timeout) { MPD_TIMEOUT = timeout; } - void SetPassword(string password) { MPD_PASSWORD = password; } + void SetPassword(const string &password) { MPD_PASSWORD = password; } void SendPassword() const; void SetStatusUpdater(StatusUpdater, void *); @@ -118,6 +119,7 @@ class MPDConnection void GetPlaylistChanges(long long, SongList &) const; string GetLastErrorMessage() const { return itsLastErrorMessage; } + int GetErrorCode() const { return itsErrorCode; } Song GetCurrentSong() const; int GetCurrentSongPos() const; @@ -137,6 +139,8 @@ class MPDConnection void QueueAddToPlaylist(const string &, const Song &); void QueueDeleteSong(int); void QueueDeleteSongId(int); + void QueueMove(int, int); + void QueueMove(const string &, int, int); void QueueDeleteFromPlaylist(const string &, int); bool CommitQueue(); @@ -167,6 +171,7 @@ class MPDConnection bool isConnected; string itsLastErrorMessage; + int itsErrorCode; unsigned int itsMaxPlaylistLength; string MPD_HOST; diff --git a/src/ncmpcpp.cpp b/src/ncmpcpp.cpp index 9cb836a7..88fcf0fe 100644 --- a/src/ncmpcpp.cpp +++ b/src/ncmpcpp.cpp @@ -165,7 +165,7 @@ int main(int argc, char *argv[]) if (!Mpd->Connect()) { - printf("Cannot connect to mpd (%s)\n", Mpd->GetLastErrorMessage().c_str()); + printf("Cannot connect to mpd: %s\n", Mpd->GetLastErrorMessage().c_str()); return -1; } @@ -1550,43 +1550,97 @@ int main(int argc, char *argv[]) if (current_screen == csPlaylist) { block_playlist_update = 1; + mPlaylist->SetTimeout(50); if (mPlaylist->IsAnySelected()) { vector list; mPlaylist->GetSelectedList(list); - mPlaylist->Highlight(list[(list.size()-1)/2]-1); - for (vector::const_iterator it = list.begin(); it != list.end(); it++) + + for (vector::iterator it = list.begin(); it != list.end(); it++) { - if (!MoveSongUp(*it-1)) - { - mPlaylist->Go(wDown); - break; - } + --*it; + if (*it == now_playing) + mPlaylist->BoldOption(now_playing+1, 0); + } + + vectororigs(list); + + while (Keypressed(input, Key.MvSongUp) && list.front() > 0) + { + TraceMpdStatus(); + timer = time(NULL); + mPlaylist->Highlight(list[(list.size()-1)/2]); + for (vector::iterator it = list.begin(); it != list.end(); it++) + mPlaylist->Swap(--*it, *it); + mPlaylist->Refresh(); + mPlaylist->ReadKey(input); } + for (int i = 0; i < list.size(); i++) + Mpd->QueueMove(origs[i], list[i]); + Mpd->CommitQueue(); } else - if (MoveSongUp(mPlaylist->GetChoice()-1)) + { + int from, to; + from = to = mPlaylist->GetChoice()-1; + while (Keypressed(input, Key.MvSongUp) && to > 0) + { + TraceMpdStatus(); + timer = time(NULL); + mPlaylist->Swap(to--, to); mPlaylist->Go(wUp); + mPlaylist->Refresh(); + mPlaylist->ReadKey(input); + } + Mpd->Move(from, to); + } + mPlaylist->SetTimeout(ncmpcpp_window_timeout); } else if (wCurrent == mPlaylistEditor) { + mPlaylistEditor->SetTimeout(50); if (mPlaylistEditor->IsAnySelected()) { vector list; mPlaylistEditor->GetSelectedList(list); - mPlaylistEditor->Highlight(list[(list.size()-1)/2]-1); - for (vector::const_iterator it = list.begin(); it != list.end(); it++) + + for (vector::iterator it = list.begin(); it != list.end(); it++) + --*it; + + vectororigs(list); + + while (Keypressed(input, Key.MvSongUp) && list.front() > 0) { - if (!PlaylistMoveSongUp(mPlaylistList->GetCurrentOption(), *it-1)) - { - mPlaylistEditor->Go(wDown); - break; - } + TraceMpdStatus(); + timer = time(NULL); + mPlaylistEditor->Highlight(list[(list.size()-1)/2]); + for (vector::iterator it = list.begin(); it != list.end(); it++) + mPlaylistEditor->Swap(--*it, *it); + mPlaylistEditor->Refresh(); + mPlaylistEditor->ReadKey(input); } + for (int i = 0; i < list.size(); i++) + if (origs[i] != list[i]) + Mpd->QueueMove(mPlaylistList->GetCurrentOption(), origs[i], list[i]); + Mpd->CommitQueue(); } else - if (PlaylistMoveSongUp(mPlaylistList->GetCurrentOption(), mPlaylistEditor->GetChoice()-1)) + { + int from, to; + from = to = mPlaylistEditor->GetChoice()-1; + while (Keypressed(input, Key.MvSongUp) && to > 0) + { + TraceMpdStatus(); + timer = time(NULL); + mPlaylistEditor->Swap(to--, to); mPlaylistEditor->Go(wUp); + mPlaylistEditor->Refresh(); + mPlaylistEditor->ReadKey(input); + } + if (from != to) + Mpd->Move(mPlaylistList->GetCurrentOption(), from, to); + } + mPlaylistEditor->SetTimeout(ncmpcpp_window_timeout); } } else if (Keypressed(input, Key.MvSongDown)) @@ -1594,43 +1648,98 @@ int main(int argc, char *argv[]) if (current_screen == csPlaylist) { block_playlist_update = 1; + mPlaylist->SetTimeout(50); if (mPlaylist->IsAnySelected()) { vector list; mPlaylist->GetSelectedList(list); - mPlaylist->Highlight(list[(list.size()-1)/2]+1); - for (vector::const_reverse_iterator it = list.rbegin(); it != list.rend(); it++) + + for (vector::iterator it = list.begin(); it != list.end(); it++) { - if (!MoveSongDown(*it-1)) - { - mPlaylist->Go(wUp); - break; - } + --*it; + if (*it == now_playing) + mPlaylist->BoldOption(now_playing+1, 0); } + + vectororigs(list); + + while (Keypressed(input, Key.MvSongDown) && list.back() < mPlaylist->Size()-1) + { + TraceMpdStatus(); + timer = time(NULL); + mPlaylist->Highlight(list[(list.size()-1)/2]+2); + for (vector::reverse_iterator it = list.rbegin(); it != list.rend(); it++) + mPlaylist->Swap(++*it, *it); + mPlaylist->Refresh(); + mPlaylist->ReadKey(input); + } + for (int i = list.size()-1; i >= 0; i--) + Mpd->QueueMove(origs[i], list[i]); + Mpd->CommitQueue(); } else - if (MoveSongDown(mPlaylist->GetChoice()-1)) + { + int from, to; + from = to = mPlaylist->GetChoice()-1; + while (Keypressed(input, Key.MvSongDown) && to < mPlaylist->Size()-1) + { + TraceMpdStatus(); + timer = time(NULL); + mPlaylist->Swap(to++, to); mPlaylist->Go(wDown); + mPlaylist->Refresh(); + mPlaylist->ReadKey(input); + } + Mpd->Move(from, to); + } + mPlaylist->SetTimeout(ncmpcpp_window_timeout); + } else if (wCurrent == mPlaylistEditor) { + mPlaylistEditor->SetTimeout(50); if (mPlaylistEditor->IsAnySelected()) { vector list; mPlaylistEditor->GetSelectedList(list); - mPlaylistEditor->Highlight(list[(list.size()-1)/2]+1); - for (vector::const_reverse_iterator it = list.rbegin(); it != list.rend(); it++) + + for (vector::iterator it = list.begin(); it != list.end(); it++) + --*it; + + vectororigs(list); + + while (Keypressed(input, Key.MvSongDown) && list.back() < mPlaylistEditor->Size()-1) { - if (!PlaylistMoveSongDown(mPlaylistList->GetCurrentOption(), *it-1)) - { - mPlaylistEditor->Go(wUp); - break; - } + TraceMpdStatus(); + timer = time(NULL); + mPlaylistEditor->Highlight(list[(list.size()-1)/2]+2); + for (vector::reverse_iterator it = list.rbegin(); it != list.rend(); it++) + mPlaylistEditor->Swap(++*it, *it); + mPlaylistEditor->Refresh(); + mPlaylistEditor->ReadKey(input); } + for (int i = list.size()-1; i >= 0; i--) + if (origs[i] != list[i]) + Mpd->QueueMove(mPlaylistList->GetCurrentOption(), origs[i], list[i]); + Mpd->CommitQueue(); } else - if (PlaylistMoveSongDown(mPlaylistList->GetCurrentOption(), mPlaylistEditor->GetChoice()-1)) + { + int from, to; + from = to = mPlaylistEditor->GetChoice()-1; + while (Keypressed(input, Key.MvSongDown) && to < mPlaylistEditor->Size()-1) + { + TraceMpdStatus(); + timer = time(NULL); + mPlaylistEditor->Swap(to++, to); mPlaylistEditor->Go(wDown); + mPlaylistEditor->Refresh(); + mPlaylistEditor->ReadKey(input); + } + if (from != to) + Mpd->Move(mPlaylistList->GetCurrentOption(), from, to); + } + mPlaylistEditor->SetTimeout(ncmpcpp_window_timeout); } } else if (Keypressed(input, Key.Add)) @@ -2131,27 +2240,27 @@ int main(int argc, char *argv[]) continue; transform(findme.begin(), findme.end(), findme.begin(), tolower); - Menu *mCurrent = static_cast *>(wCurrent); - - for (int i = (wCurrent == mBrowser ? search_engine_static_option : 1); i <= mCurrent->Size(); i++) + ShowMessage("Searching..."); + for (int i = (wCurrent == mBrowser ? search_engine_static_option : 1); i <= wCurrent->Size(); i++) { - string name = OmitBBCodes(mCurrent->GetOption(i)); + string name = OmitBBCodes(wCurrent->GetOption(i)); transform(name.begin(), name.end(), name.begin(), tolower); - if (name.find(findme) != string::npos && !mCurrent->IsStatic(i)) + if (name.find(findme) != string::npos && !wCurrent->IsStatic(i)) { vFoundPositions.push_back(i); if (Keypressed(input, Key.FindForward)) // forward { - if (found_pos < 0 && i >= mCurrent->GetChoice()) + if (found_pos < 0 && i >= wCurrent->GetChoice()) found_pos = vFoundPositions.size()-1; } else // backward { - if (i <= mCurrent->GetChoice()) + if (i <= wCurrent->GetChoice()) found_pos = vFoundPositions.size()-1; } } } + ShowMessage("Searching finished!"); if (Config.wrapped_search ? vFoundPositions.empty() : found_pos < 0) ShowMessage("Unable to find \"" + findme + "\""); @@ -2159,7 +2268,10 @@ int main(int argc, char *argv[]) { wCurrent->Highlight(vFoundPositions[found_pos < 0 ? 0 : found_pos]); if (wCurrent == mPlaylist) + { + timer = time(NULL); mPlaylist->Highlighting(1); + } } } } diff --git a/src/status_checker.cpp b/src/status_checker.cpp index 63ca261b..db3be39f 100644 --- a/src/status_checker.cpp +++ b/src/status_checker.cpp @@ -122,11 +122,13 @@ void NcmpcppErrorCallback(MPDConnection *Mpd, int errorid, string msg, void *dat { if (errorid == MPD_ACK_ERROR_PERMISSION) { + wFooter->SetGetStringHelper(NULL); wFooter->WriteXY(0, Config.statusbar_visibility, "Password: ", 1); - string password = wFooter->GetString(""); + string password = wFooter->GetString(); Mpd->SetPassword(password); Mpd->SendPassword(); Mpd->UpdateStatus(); + wFooter->SetGetStringHelper(TraceMpdStatus); } else ShowMessage(msg); diff --git a/src/window.cpp b/src/window.cpp index aed3a587..8a1ae539 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -460,7 +460,7 @@ string Window::GetString(const string &base, unsigned int length) const case KEY_UP: case KEY_DOWN: break; case KEY_RIGHT: - { + { if (x < maxx) x++; break; @@ -619,9 +619,40 @@ char * ToString(const wchar_t *ws) s += c; delete [] c; } - return (char *)s.c_str(); + char *result = strdup(s.c_str()); + return result; +} + +wchar_t * ToWString(const char *s) +{ + wchar_t *ws = (wchar_t *)calloc(strlen(s)+1, sizeof(wchar_t)); + mbstowcs(ws, s, strlen(s)); + return ws; +} + +string ToString(const wstring &ws) +{ + string s; + for (wstring::const_iterator it = ws.begin(); it != ws.end(); it++) + { + char *c = (char *)calloc(MB_CUR_MAX, sizeof(char)); + wctomb(c, *it); + s += c; + delete [] c; + } + return s; +} + +wstring ToWString(const string &s) +{ + wchar_t *ws = (wchar_t *)calloc(s.length()+1, sizeof(wchar_t)); + mbstowcs(ws, s.c_str(), s.length()); + wstring result = ws; + delete [] ws; + return result; } + string OmitBBCodes(const string &str) { if (str.empty()) @@ -662,7 +693,7 @@ string OmitBBCodes(const string &str) return result; } -int CountBBCodes(const string &str) +/*int CountBBCodes(const string &str) { if (str.empty()) return 0; @@ -742,33 +773,5 @@ int CountBBCodes(const wstring &str) } } return length; -} - -wchar_t * ToWString(const char *s) -{ - wchar_t *ws = (wchar_t *)calloc(strlen(s)+1, sizeof(wchar_t)); - mbstowcs(ws, s, strlen(s)); - return ws; -} - -string ToString(const wstring &ws) -{ - string s; - for (wstring::const_iterator it = ws.begin(); it != ws.end(); it++) - { - char *c = (char *)calloc(MB_CUR_MAX, sizeof(char)); - wctomb(c, *it); - s += c; - delete [] c; - } - return s; -} +}*/ -wstring ToWString(const string &s) -{ - wchar_t *ws = (wchar_t *)calloc(s.length()+1, sizeof(wchar_t)); - mbstowcs(ws, s.c_str(), s.length()); - wstring result = ws; - delete [] ws; - return result; -} diff --git a/src/window.h b/src/window.h index 4c53ce01..50dd8156 100644 --- a/src/window.h +++ b/src/window.h @@ -57,8 +57,8 @@ wstring ToWString(const string &); bool is_valid_color(const string &); string OmitBBCodes(const string &); -int CountBBCodes(const string &); -int CountBBCodes(const wstring &); +//int CountBBCodes(const string &); +//int CountBBCodes(const wstring &); class Window { @@ -122,6 +122,7 @@ class Window virtual void GetSelectedList(vector &) { } virtual bool IsStatic(int) { return 0; } virtual void Highlight(int) { } + virtual string GetOption(int) const { return ""; } virtual void Go(Where) { } // for Menu and Scrollpad class virtual int GetChoice() const { return -1; } // for Menu class virtual void Add(string str) { Write(str); } // for Scrollpad class