浏览代码

FileManager: Added support for deleting directories

Directories can now be deleted using the "Delete..." action from the
context menu
Till Mayer 5 年之前
父节点
当前提交
09189e34e3
共有 3 个文件被更改,包括 66 次插入3 次删除
  1. 36 0
      Applications/FileManager/FileUtils.cpp
  2. 4 2
      Applications/FileManager/FileUtils.h
  3. 26 1
      Applications/FileManager/main.cpp

+ 36 - 0
Applications/FileManager/FileUtils.cpp

@@ -9,6 +9,42 @@
 
 namespace FileUtils {
 
+int delete_directory(String directory, String& file_that_caused_error)
+{
+    CDirIterator iterator(directory, CDirIterator::SkipDots);
+    if (iterator.has_error()) {
+        file_that_caused_error = directory;
+        return -1;
+    }
+
+    while (iterator.has_next()) {
+        auto file_to_delete = String::format("%s/%s", directory.characters(), iterator.next_path().characters());
+        struct stat st;
+
+        if (lstat(file_to_delete.characters(), &st)) {
+            file_that_caused_error = file_to_delete;
+            return errno;
+        }
+
+        if (S_ISDIR(st.st_mode)) {
+            if (delete_directory(file_to_delete, file_to_delete)) {
+                file_that_caused_error = file_to_delete;
+                return errno;
+            }
+        } else if (unlink(file_to_delete.characters())) {
+            file_that_caused_error = file_to_delete;
+            return errno;
+        }
+    }
+
+    if (rmdir(directory.characters())) {
+        file_that_caused_error = directory;
+        return errno;
+    }
+
+    return 0;
+}
+
 bool copy_file_or_directory(const String& src_path, const String& dst_path)
 {
     int duplicate_count = 0;

+ 4 - 2
Applications/FileManager/FileUtils.h

@@ -2,9 +2,11 @@
 #include <AK/String.h>
 
 namespace FileUtils {
-bool copy_file_or_directory(const String& src_path, const String& dst_path);
 
+int delete_directory(String directory, String& file_that_caused_error);
+bool copy_file_or_directory(const String& src_path, const String& dst_path);
 String get_duplicate_name(const String& path, int duplicate_count);
 bool copy_file(const String& src_path, const String& dst_path, const struct stat& src_stat, int src_fd);
 bool copy_directory(const String& src_path, const String& dst_path);
-}
+
+}

+ 26 - 1
Applications/FileManager/main.cpp

@@ -252,8 +252,33 @@ int main(int argc, char** argv)
                     return;
             }
         }
+
         for (auto& path : paths) {
-            if (unlink(path.characters()) < 0) {
+            struct stat st;
+            if (lstat(path.characters(), &st)) {
+                GMessageBox::show(
+                    String::format("lstat(%s) failed: %s", path.characters(), strerror(errno)),
+                    "Delete failed",
+                    GMessageBox::Type::Error,
+                    GMessageBox::InputType::OK,
+                    window);
+                break;
+            }
+
+            if (S_ISDIR(st.st_mode)) {
+                String error_path;
+                int error = FileUtils::delete_directory(path, error_path);
+
+                if (error) {
+                    GMessageBox::show(
+                        String::format("Failed to delete directory \"%s\": %s", error_path.characters(), strerror(error)),
+                        "Delete failed",
+                        GMessageBox::Type::Error,
+                        GMessageBox::InputType::OK,
+                        window);
+                    break;
+                }
+            } else if (unlink(path.characters()) < 0) {
                 int saved_errno = errno;
                 GMessageBox::show(
                     String::format("unlink(%s) failed: %s", path.characters(), strerror(saved_errno)),