From 8f5df28e6243a505215cf87673d7c6b8c4c86e74 Mon Sep 17 00:00:00 2001 From: Andrzej Rybczak Date: Sat, 23 May 2009 17:09:41 +0200 Subject: [PATCH] new feature: allow for files and directories deletion in browser --- doc/config | 10 ++++++++++ doc/ncmpcpp.1 | 6 ++++++ src/browser.cpp | 35 ++++++++++++++++++++++++++++++++ src/browser.h | 1 + src/ncmpcpp.cpp | 52 +++++++++++++++++++++++++++++++++++++++++++++++- src/settings.cpp | 10 ++++++++++ src/settings.h | 2 ++ 7 files changed, 115 insertions(+), 1 deletion(-) diff --git a/doc/config b/doc/config index 10b2ea0a..fe60d676 100644 --- a/doc/config +++ b/doc/config @@ -174,6 +174,16 @@ # #enable_window_title = "yes" # +## +## Note: These triggers will allow you to phisically remove +## files and directories from your hdd in using ncmpcpp's +## browser screen. +## +# +#allow_physical_files_deletion = "no" +# +#allow_physical_directories_deletion = "no" +# ##### lyrics support ##### ## ## supported lyrics databases: diff --git a/doc/ncmpcpp.1 b/doc/ncmpcpp.1 index 05aba139..f9022f86 100644 --- a/doc/ncmpcpp.1 +++ b/doc/ncmpcpp.1 @@ -186,6 +186,12 @@ If your external editor is console application, you need to enable it. .B block_search_constraints_change_if_items_found = yes/no If enabled, fields in Search engine above "Reset" button will be blocked after succesful searching, otherwise they won't. .TP +.B allow_physical_files_deletion = yes/no +If enabled, ncmpcpp will be able to delete files using its browser screen. +.TP +.B allow_physical_directories_deletion = yes/no +If enabled, ncmpcpp will be able to delete directories using its browser screen. +.TP .B enable_window_title = yes/no If enabled, ncmpcpp will override current window title with its own one. .TP diff --git a/src/browser.cpp b/src/browser.cpp index cfb1813c..47f4b11d 100644 --- a/src/browser.cpp +++ b/src/browser.cpp @@ -465,6 +465,41 @@ void Browser::GetDirectory(string dir, string subdir) w->Highlight(highlightme); } +void Browser::ClearDirectory(const std::string &path) const +{ + DIR *dir = opendir(path.c_str()); + if (!dir) + return; + + dirent *file; + struct stat file_stat; + string full_path; + + // omit . and .. + for (int i = 0; i < 2; i++) + { + file = readdir(dir); + if (!file) + { + closedir(dir); + return; + } + } + + while ((file = readdir(dir))) + { + full_path = path; + if (*full_path.rbegin() != '/') + full_path += '/'; + full_path += file->d_name; + lstat(full_path.c_str(), &file_stat); + if (S_ISDIR(file_stat.st_mode)) + ClearDirectory(full_path); + remove(full_path.c_str()); + } + closedir(dir); +} + void Browser::ChangeBrowseMode() { if (Mpd->GetHostname()[0] != '/') diff --git a/src/browser.h b/src/browser.h index 69b9cb2f..1b16e786 100644 --- a/src/browser.h +++ b/src/browser.h @@ -52,6 +52,7 @@ class Browser : public Screen< Menu > void LocateSong(const MPD::Song &); void GetDirectory(std::string, std::string = "/"); + void ClearDirectory(const std::string &) const; void ChangeBrowseMode(); void UpdateItemList(); diff --git a/src/ncmpcpp.cpp b/src/ncmpcpp.cpp index 9f389850..c19231e8 100644 --- a/src/ncmpcpp.cpp +++ b/src/ncmpcpp.cpp @@ -18,6 +18,7 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ +#include #include #include @@ -513,7 +514,56 @@ int main(int argc, char *argv[]) } else if (myScreen == myBrowser && !myBrowser->Main()->Empty() && myBrowser->Main()->Current().type != itPlaylist) { - // delete song/dir implementation here + MPD::Item &item = myBrowser->Main()->Current(); + + if (item.type == itSong && !Config.allow_physical_files_deletion) + { + ShowMessage("Deleting files is disabled by default, see man page for more details"); + continue; + } + if (item.type == itDirectory && (item.song || !Config.allow_physical_directories_deletion)) // [..] + { + ShowMessage("Deleting directories is disabled by default, see man page for more details"); + continue; + } + + LockStatusbar(); + Statusbar() << "Delete " << (item.type == itSong ? "file" : "directory") << ' ' << (item.type == itSong ? item.song->GetName() : item.name) << " ? [y/n] "; + curs_set(1); + int in = 0; + do + { + TraceMpdStatus(); + wFooter->ReadKey(in); + } + while (in != 'y' && in != 'n'); + if (in == 'y') + { + ShowMessage("Deleting..."); + + string path; + if (!Config.local_browser) + path = Config.mpd_music_dir; + path += item.type == itSong ? item.song->GetFile() : item.name; + + if (item.type == itDirectory) + myBrowser->ClearDirectory(path); + + if (remove(path.c_str()) == 0) + { + ShowMessage("%s has been deleted!", item.type == itSong ? "File" : "Directory"); + if (!Config.local_browser) + Mpd->UpdateDirectory(myBrowser->CurrentDir()); + else + myBrowser->GetDirectory(myBrowser->CurrentDir()); + } + else + ShowMessage("Deletion failed: %s", strerror(errno)); + } + else + ShowMessage("Aborted!"); + curs_set(0); + UnlockStatusbar(); } else if (myScreen->ActiveWindow() == myPlaylistEditor->Content && !myPlaylistEditor->Content->Empty()) { diff --git a/src/settings.cpp b/src/settings.cpp index beedb7bc..54ee9858 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -278,6 +278,8 @@ void DefaultConfiguration(ncmpcpp_config &conf) conf.block_search_constraints_change = true; conf.use_console_editor = false; conf.use_cyclic_scrolling = false; + conf.allow_physical_files_deletion = false; + conf.allow_physical_directories_deletion = false; conf.set_window_title = true; conf.mpd_port = 6600; conf.mpd_connection_timeout = 15; @@ -669,6 +671,14 @@ void ReadConfiguration(ncmpcpp_config &conf) { conf.block_search_constraints_change = v == "yes"; } + else if (cl.find("allow_physical_files_deletion") != string::npos) + { + conf.allow_physical_files_deletion = v == "yes"; + } + else if (cl.find("allow_physical_directories_deletion") != string::npos) + { + conf.allow_physical_directories_deletion = v == "yes"; + } else if (cl.find("enable_window_title") != string::npos) { conf.set_window_title = v == "yes"; diff --git a/src/settings.h b/src/settings.h index 191504dd..33310eec 100644 --- a/src/settings.h +++ b/src/settings.h @@ -170,6 +170,8 @@ struct ncmpcpp_config bool block_search_constraints_change; bool use_console_editor; bool use_cyclic_scrolling; + bool allow_physical_files_deletion; + bool allow_physical_directories_deletion; int mpd_port; int mpd_connection_timeout;