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

This commit is contained in:
Marcelo Fernandez 2017-09-25 10:15:11 -03:00
parent 09800ac650
commit 20918587d3
9 changed files with 140 additions and 13 deletions

View File

@ -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,

View File

@ -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() {

View File

@ -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);

View File

@ -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();
};

View File

@ -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() {

View File

@ -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;

View File

@ -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();
};

View File

@ -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

View File

@ -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();
};