diff --git a/src/actions.cpp b/src/actions.cpp index 3b6bf783..4e171322 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -718,10 +718,9 @@ void DeleteBrowserItems::run() ); } - if (myBrowser->isLocal()) - myBrowser->getDirectory(myBrowser->currentDirectory()); - else + if (!myBrowser->isLocal()) Mpd.UpdateDirectory(myBrowser->currentDirectory()); + myBrowser->requestUpdate(); } bool DeleteStoredPlaylist::canBeRun() const @@ -1443,7 +1442,7 @@ void EditDirectoryName::run() Statusbar::printf(msg, wideShorten(new_dir, COLS-const_strlen(msg))); if (!myBrowser->isLocal()) Mpd.UpdateDirectory(getSharedDirectory(old_dir, new_dir)); - myBrowser->getDirectory(myBrowser->currentDirectory()); + myBrowser->requestUpdate(); } else { diff --git a/src/browser.cpp b/src/browser.cpp index c75df79a..50ea3bae 100644 --- a/src/browser.cpp +++ b/src/browser.cpp @@ -71,7 +71,11 @@ bool browserEntryMatcher(const boost::regex &rx, const MPD::Item &item, bool fil } -Browser::Browser() : m_local_browser(false), m_scroll_beginning(0), m_current_directory("/") +Browser::Browser() +: m_update_request(true) +, m_local_browser(false) +, m_scroll_beginning(0) +, m_current_directory("/") { w = NC::Menu(0, MainStartY, COLS, MainHeight, Config.browser_display_mode == DisplayMode::Columns && Config.titles_visibility ? Display::Columns(COLS) : "", Config.main_color, NC::Border()); w.setHighlightColor(Config.main_highlight_color); @@ -117,6 +121,38 @@ std::wstring Browser::title() return result; } +void Browser::update() +{ + if (m_update_request) + { + m_update_request = false; + bool directory_changed = false; + do + { + try + { + getDirectory(m_current_directory); + w.refresh(); + } + catch (MPD::ServerError &err) + { + // If current directory doesn't exist, try getting its + // parent until we either succeed or reach the root. + if (err.code() == MPD_SERVER_ERROR_NO_EXIST) + { + m_current_directory = getParentDirectory(m_current_directory); + directory_changed = true; + } + else + throw; + } + } + while (w.empty() && !inRootDirectory()); + if (directory_changed) + drawHeader(); + } +} + void Browser::enterPressed() { if (w.empty()) diff --git a/src/browser.h b/src/browser.h index 2ab55ace..b310ce51 100644 --- a/src/browser.h +++ b/src/browser.h @@ -37,7 +37,7 @@ struct Browser: Screen>, HasSongs, Searchable, Tabbable virtual std::wstring title() OVERRIDE; virtual ScreenType type() OVERRIDE { return ScreenType::Browser; } - virtual void update() OVERRIDE { } + virtual void update() OVERRIDE; virtual void enterPressed() OVERRIDE; virtual void spacePressed() OVERRIDE; @@ -59,6 +59,8 @@ struct Browser: Screen>, HasSongs, Searchable, Tabbable virtual std::vector getSelectedSongs() OVERRIDE; // private members + void requestUpdate() { m_update_request = true; } + bool inRootDirectory(); bool isParentDirectory(const MPD::Item &item); const std::string ¤tDirectory(); @@ -75,6 +77,7 @@ protected: virtual bool isLockable() OVERRIDE { return true; } private: + bool m_update_request; bool m_local_browser; size_t m_scroll_beginning; std::string m_current_directory; diff --git a/src/mpdpp.cpp b/src/mpdpp.cpp index 863b2a6b..7974cb42 100644 --- a/src/mpdpp.cpp +++ b/src/mpdpp.cpp @@ -69,6 +69,26 @@ bool fetchItemSong(MPD::SongIterator::State &state) namespace MPD { +void checkConnectionErrors(mpd_connection *conn) +{ + mpd_error code = mpd_connection_get_error(conn); + if (code != MPD_ERROR_SUCCESS) + { + std::string msg = mpd_connection_get_error_message(conn); + if (code == MPD_ERROR_SERVER) + { + mpd_server_error server_code = mpd_connection_get_server_error(conn); + bool clearable = mpd_connection_clear_error(conn); + throw ServerError(server_code, msg, clearable); + } + else + { + bool clearable = mpd_connection_clear_error(conn); + throw ClientError(code, msg, clearable); + } + } +} + Connection::Connection() : m_connection(nullptr), m_command_list_active(false), m_idle(false), @@ -817,22 +837,7 @@ void Connection::prechecksNoCommandsList() void Connection::checkErrors() const { - mpd_error code = mpd_connection_get_error(m_connection.get()); - if (code != MPD_ERROR_SUCCESS) - { - std::string msg = mpd_connection_get_error_message(m_connection.get()); - if (code == MPD_ERROR_SERVER) - { - mpd_server_error server_code = mpd_connection_get_server_error(m_connection.get()); - bool clearable = mpd_connection_clear_error(m_connection.get()); - throw ServerError(server_code, msg, clearable); - } - else - { - bool clearable = mpd_connection_clear_error(m_connection.get()); - throw ClientError(code, msg, clearable); - } - } + checkConnectionErrors(m_connection.get()); } } diff --git a/src/mpdpp.h b/src/mpdpp.h index 093290b2..f1865724 100644 --- a/src/mpdpp.h +++ b/src/mpdpp.h @@ -31,6 +31,8 @@ namespace MPD { +void checkConnectionErrors(mpd_connection *conn); + enum PlayerState { psUnknown, psStop, psPlay, psPause }; enum ReplayGainMode { rgmOff, rgmTrack, rgmAlbum }; @@ -398,10 +400,17 @@ struct Iterator: std::iterator // get the first element ++*this; } + ~Iterator() + { + if (m_state) + checkConnectionErrors(m_state->connection()); + } void finish() { - // change the iterator into end iterator + assert(m_state); + // check errors and change the iterator into end iterator + checkConnectionErrors(m_state->connection()); m_state = nullptr; } diff --git a/src/ncmpcpp.cpp b/src/ncmpcpp.cpp index c8789259..4bdf1f02 100644 --- a/src/ncmpcpp.cpp +++ b/src/ncmpcpp.cpp @@ -66,7 +66,7 @@ namespace signal(sig, sighandler); # endif // __sun && __SVR4 } - + void do_at_exit() { // restore old cerr buffer @@ -156,7 +156,7 @@ int main(int argc, char **argv) // just ignore it and wait for the connection to // be reestablished. sigignore(SIGPIPE); - + while (!Actions::ExitMainLoop) { try diff --git a/src/status.cpp b/src/status.cpp index a7db3d0d..51ede82e 100644 --- a/src/status.cpp +++ b/src/status.cpp @@ -450,19 +450,12 @@ void Status::Changes::storedPlaylists() myPlaylistEditor->requestPlaylistsUpdate(); myPlaylistEditor->requestContentsUpdate(); if (!myBrowser->isLocal() && myBrowser->inRootDirectory()) - { - myBrowser->getDirectory("/"); - if (isVisible(myBrowser)) - myBrowser->refresh(); - } + myBrowser->requestUpdate(); } void Status::Changes::database() { - if (isVisible(myBrowser)) - myBrowser->getDirectory(myBrowser->currentDirectory()); - else - myBrowser->main().clear(); + myBrowser->requestUpdate(); # ifdef HAVE_TAGLIB_H myTagEditor->Dirs->clear(); # endif // HAVE_TAGLIB_H diff --git a/src/tiny_tag_editor.cpp b/src/tiny_tag_editor.cpp index a2574594..6a7efd7c 100644 --- a/src/tiny_tag_editor.cpp +++ b/src/tiny_tag_editor.cpp @@ -142,7 +142,7 @@ void TinyTagEditor::enterPressed() if (m_previous_screen == myPlaylist) myPlaylist->main().current()->value() = itsEdited; else if (m_previous_screen == myBrowser) - myBrowser->getDirectory(myBrowser->currentDirectory()); + myBrowser->requestUpdate(); } } else