Browse Source

FileSystemDock will now remove files/dirs to trashcan using OS::move_to_trash

Marcelo Fernandez 8 years ago
parent
commit
20918587d3

+ 2 - 0
core/os/os.h

@@ -335,6 +335,8 @@ public:
 	virtual String get_data_dir() const;
 	virtual String get_resource_dir() const;
 
+	virtual Error move_to_trash(const String &p_path) { return FAILED; }
+
 	enum SystemDir {
 		SYSTEM_DIR_DESKTOP,
 		SYSTEM_DIR_DCIM,

+ 9 - 4
editor/dependency_editor.cpp

@@ -409,17 +409,22 @@ void DependencyRemoveDialog::show(const Vector<String> &to_erase) {
 
 void DependencyRemoveDialog::ok_pressed() {
 
-	DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+	bool changed = false;
+
 	for (Map<String, TreeItem *>::Element *E = files.front(); E; E = E->next()) {
 
 		if (ResourceCache::has(E->key())) {
 			Resource *res = ResourceCache::get(E->key());
 			res->set_path(""); //clear reference to path
 		}
-		da->remove(E->key());
-		EditorFileSystem::get_singleton()->update_file(E->key());
+		String fpath = OS::get_singleton()->get_resource_dir() + E->key().replace_first("res://", "/");
+		OS::get_singleton()->move_to_trash(fpath);
+		changed = true;
+	}
+
+	if (changed) {
+		EditorFileSystem::get_singleton()->scan_changes();
 	}
-	memdelete(da);
 }
 
 DependencyRemoveDialog::DependencyRemoveDialog() {

+ 11 - 9
editor/filesystem_dock.cpp

@@ -1002,7 +1002,7 @@ void FileSystemDock::_file_option(int p_option) {
 			for (int i = 0; i < files->get_item_count(); i++) {
 
 				String path = files->get_item_metadata(i);
-				if (path.ends_with("/") || !files->is_selected(i))
+				if (!files->is_selected(i))
 					continue;
 				torem.push_back(path);
 			}
@@ -1466,6 +1466,7 @@ void FileSystemDock::_files_list_rmb_select(int p_item, const Vector2 &p_pos) {
 
 	bool all_scenes = true;
 	bool all_can_reimport = true;
+	bool is_dir = false;
 	Set<String> types;
 
 	for (int i = 0; i < files->get_item_count(); i++) {
@@ -1481,8 +1482,7 @@ void FileSystemDock::_files_list_rmb_select(int p_item, const Vector2 &p_pos) {
 		}
 
 		if (path.ends_with("/")) {
-			//no operate on dirs
-			return;
+			is_dir = true;
 		}
 
 		int pos;
@@ -1513,17 +1513,19 @@ void FileSystemDock::_files_list_rmb_select(int p_item, const Vector2 &p_pos) {
 
 	file_options->add_separator();
 
-	if (filenames.size() == 1) {
+	if (filenames.size() == 1 && !is_dir) {
 		file_options->add_item(TTR("Edit Dependencies.."), FILE_DEPENDENCIES);
 		file_options->add_item(TTR("View Owners.."), FILE_OWNERS);
 		file_options->add_separator();
 	}
 
-	if (filenames.size() == 1) {
-		file_options->add_item(TTR("Copy Path"), FILE_COPY_PATH);
-		file_options->add_item(TTR("Rename or Move.."), FILE_MOVE);
-	} else {
-		file_options->add_item(TTR("Move To.."), FILE_MOVE);
+	if (!is_dir) {
+		if (filenames.size() == 1) {
+			file_options->add_item(TTR("Copy Path"), FILE_COPY_PATH);
+			file_options->add_item(TTR("Rename or Move.."), FILE_MOVE);
+		} else {
+			file_options->add_item(TTR("Move To.."), FILE_MOVE);
+		}
 	}
 
 	file_options->add_item(TTR("Delete"), FILE_REMOVE);

+ 2 - 0
platform/osx/os_osx.h

@@ -229,6 +229,8 @@ public:
 	void disable_crash_handler();
 	bool is_disable_crash_handler() const;
 
+	virtual Error move_to_trash(const String &p_path);
+
 	OS_OSX();
 };
 

+ 13 - 0
platform/osx/os_osx.mm

@@ -1910,6 +1910,19 @@ int OS_OSX::get_power_percent_left() {
 	return power_manager->get_power_percent_left();
 }
 
+Error OS_OSX::move_to_trash(const String &p_path) {
+	NSFileManager *fm = [NSFileManager defaultManager];
+	NSURL *url = [NSURL fileURLWithPath:@(p_path.utf8().get_data())];
+	NSError *err;
+
+	if (![fm trashItemAtURL:url resultingItemURL:nil error:&err]) {
+		ERR_PRINTS("trashItemAtURL error: " + String(err.localizedDescription.UTF8String));
+		return FAILED;
+	}
+
+	return OK;
+}
+
 OS_OSX *OS_OSX::singleton = NULL;
 
 OS_OSX::OS_OSX() {

+ 27 - 0
platform/windows/os_windows.cpp

@@ -2373,6 +2373,33 @@ bool OS_Windows::is_disable_crash_handler() const {
 	return crash_handler.is_disabled();
 }
 
+Error OS_Windows::move_to_trash(const String &p_path) {
+	SHFILEOPSTRUCTA sf;
+	TCHAR *from = new TCHAR[p_path.length() + 2];
+	strcpy(from, p_path.utf8().get_data());
+	from[p_path.length()] = 0;
+	from[p_path.length() + 1] = 0;
+
+	sf.hwnd = hWnd;
+	sf.wFunc = FO_DELETE;
+	sf.pFrom = from;
+	sf.pTo = NULL;
+	sf.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION;
+	sf.fAnyOperationsAborted = FALSE;
+	sf.hNameMappings = NULL;
+	sf.lpszProgressTitle = NULL;
+
+	int ret = SHFileOperation(&sf);
+	delete[] from;
+
+	if (ret) {
+		ERR_PRINTS("SHFileOperation error: " + itos(ret));
+		return FAILED;
+	}
+
+	return OK;
+}
+
 OS_Windows::OS_Windows(HINSTANCE _hInstance) {
 
 	key_event_pos = 0;

+ 2 - 0
platform/windows/os_windows.h

@@ -290,6 +290,8 @@ public:
 	void disable_crash_handler();
 	bool is_disable_crash_handler() const;
 
+	virtual Error move_to_trash(const String &p_path);
+
 	OS_Windows(HINSTANCE _hInstance);
 	~OS_Windows();
 };

+ 72 - 0
platform/x11/os_x11.cpp

@@ -35,6 +35,7 @@
 #include "servers/physics/physics_server_sw.h"
 #include "servers/visual/visual_server_raster.h"
 #include "servers/visual/visual_server_wrap_mt.h"
+#include <mntent.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -2175,6 +2176,77 @@ bool OS_X11::is_disable_crash_handler() const {
 	return crash_handler.is_disabled();
 }
 
+static String get_mountpoint(const String &p_path) {
+	struct stat s;
+	if (stat(p_path.utf8().get_data(), &s)) {
+		return "";
+	}
+
+	dev_t dev = s.st_dev;
+	FILE *fd = setmntent("/proc/mounts", "r");
+	if (!fd) {
+		return "";
+	}
+
+	struct mntent mnt;
+	char buf[1024];
+	size_t buflen = 1024;
+	while (getmntent_r(fd, &mnt, buf, buflen)) {
+		if (!stat(mnt.mnt_dir, &s) && s.st_dev == dev) {
+			endmntent(fd);
+			return String(mnt.mnt_dir);
+		}
+	}
+
+	endmntent(fd);
+	return "";
+}
+
+Error OS_X11::move_to_trash(const String &p_path) {
+	String trashcan = "";
+	String mnt = get_mountpoint(p_path);
+
+	if (mnt != "") {
+		String path(mnt + "/.Trash-" + itos(getuid()) + "/files");
+		struct stat s;
+		if (!stat(path.utf8().get_data(), &s)) {
+			trashcan = path;
+		}
+	}
+
+	if (trashcan == "") {
+		char *dhome = getenv("XDG_DATA_HOME");
+		if (dhome) {
+			trashcan = String(dhome) + "/Trash/files";
+		}
+	}
+
+	if (trashcan == "") {
+		char *home = getenv("HOME");
+		if (home) {
+			trashcan = String(home) + "/.local/share/Trash/files";
+		}
+	}
+
+	if (trashcan == "") {
+		ERR_PRINTS("move_to_trash: Could not determine trashcan location");
+		return FAILED;
+	}
+
+	List<String> args;
+	args.push_back("-p");
+	args.push_back(trashcan);
+	Error err = execute("/bin/mkdir", args, true);
+	if (err == OK) {
+		List<String> args2;
+		args2.push_back(p_path);
+		args2.push_back(trashcan);
+		err = execute("/bin/mv", args2, true);
+	}
+
+	return err;
+}
+
 OS_X11::OS_X11() {
 
 #ifdef PULSEAUDIO_ENABLED

+ 2 - 0
platform/x11/os_x11.h

@@ -273,6 +273,8 @@ public:
 	void disable_crash_handler();
 	bool is_disable_crash_handler() const;
 
+	virtual Error move_to_trash(const String &p_path);
+
 	OS_X11();
 };