summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMillionOstrich <31486600+MillionOstrich@users.noreply.github.com>2017-10-01 23:24:49 +0100
committerMillionOstrich <31486600+MillionOstrich@users.noreply.github.com>2017-10-09 15:10:40 +0100
commit40d1866b051f24b42e5de37c08b300214a0092a6 (patch)
treeed9dc323d834196f804d236114f2efffb2938e76
parent716e5b2943965688127d079bbdba91597907e483 (diff)
Rework DependencyRemoveDialog for deleting folders
DependencyRemoveDialog now takes two lists (files and folders) to delete. Sort the folders above files in DependencyRemoveDialog & use some more icons. Stop files which will be deleted from also being listed as having broken dependencies. Add right-click option for removing folder to filesystem folder tree.
-rw-r--r--editor/dependency_editor.cpp154
-rw-r--r--editor/dependency_editor.h27
-rw-r--r--editor/filesystem_dock.cpp37
-rw-r--r--editor/filesystem_dock.h1
4 files changed, 149 insertions, 70 deletions
diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp
index 5305c4f256..64f1c4ccb2 100644
--- a/editor/dependency_editor.cpp
+++ b/editor/dependency_editor.cpp
@@ -337,92 +337,142 @@ DependencyEditorOwners::DependencyEditorOwners() {
///////////////////////
-void DependencyRemoveDialog::_fill_owners(EditorFileSystemDirectory *efsd) {
+void DependencyRemoveDialog::_find_files_in_removed_folder(EditorFileSystemDirectory *efsd, const String &p_folder) {
+ if (!efsd)
+ return;
+
+ for (int i = 0; i < efsd->get_subdir_count(); ++i) {
+ _find_files_in_removed_folder(efsd->get_subdir(i), p_folder);
+ }
+ for (int i = 0; i < efsd->get_file_count(); i++) {
+ String file = efsd->get_file_path(i);
+ ERR_FAIL_COND(all_remove_files.has(file)); //We are deleting a directory which is contained in a directory we are deleting...
+ all_remove_files[file] = p_folder; //Point the file to the ancestor directory we are deleting so we know what to parent it under in the tree.
+ }
+}
+void DependencyRemoveDialog::_find_all_removed_dependencies(EditorFileSystemDirectory *efsd, Vector<RemovedDependency> &p_removed) {
if (!efsd)
return;
for (int i = 0; i < efsd->get_subdir_count(); i++) {
- _fill_owners(efsd->get_subdir(i));
+ _find_all_removed_dependencies(efsd->get_subdir(i), p_removed);
}
for (int i = 0; i < efsd->get_file_count(); i++) {
+ const String path = efsd->get_file_path(i);
- Vector<String> deps = efsd->get_file_deps(i);
- //print_line(":::"+efsd->get_file_path(i));
- Set<String> met;
- for (int j = 0; j < deps.size(); j++) {
- if (files.has(deps[j])) {
- met.insert(deps[j]);
- }
- }
- if (!met.size())
+ //It doesn't matter if a file we are about to delete will have some of its dependencies removed too
+ if (all_remove_files.has(path))
continue;
- exist = true;
-
- Ref<Texture> icon;
- String type = efsd->get_file_type(i);
- if (!has_icon(type, "EditorIcons")) {
- icon = get_icon("Object", "EditorIcons");
- } else {
- icon = get_icon(type, "EditorIcons");
+ Vector<String> all_deps = efsd->get_file_deps(i);
+ for (int j = 0; j < all_deps.size(); ++j) {
+ if (all_remove_files.has(all_deps[j])) {
+ RemovedDependency dep;
+ dep.file = path;
+ dep.file_type = efsd->get_file_type(i);
+ dep.dependency = all_deps[j];
+ dep.dependency_folder = all_remove_files[all_deps[j]];
+ p_removed.push_back(dep);
+ }
}
+ }
+}
- for (Set<String>::Element *E = met.front(); E; E = E->next()) {
+void DependencyRemoveDialog::_build_removed_dependency_tree(const Vector<RemovedDependency> &p_removed) {
+ owners->clear();
+ owners->create_item(); // root
- String which = E->get();
- if (!files[which]) {
- TreeItem *ti = owners->create_item(owners->get_root());
- ti->set_text(0, which.get_file());
- files[which] = ti;
+ Map<String, TreeItem *> tree_items;
+ for (int i = 0; i < p_removed.size(); i++) {
+ RemovedDependency rd = p_removed[i];
+
+ //Ensure that the dependency is already in the tree
+ if (!tree_items.has(rd.dependency)) {
+ if (rd.dependency_folder.length() > 0) {
+ //Ensure the ancestor folder is already in the tree
+ if (!tree_items.has(rd.dependency_folder)) {
+ TreeItem *folder_item = owners->create_item(owners->get_root());
+ folder_item->set_text(0, rd.dependency_folder);
+ folder_item->set_icon(0, get_icon("Folder", "EditorIcons"));
+ tree_items[rd.dependency_folder] = folder_item;
+ }
+ TreeItem *dependency_item = owners->create_item(tree_items[rd.dependency_folder]);
+ dependency_item->set_text(0, rd.dependency);
+ dependency_item->set_icon(0, get_icon("Warning", "EditorIcons"));
+ tree_items[rd.dependency] = dependency_item;
+ } else {
+ TreeItem *dependency_item = owners->create_item(owners->get_root());
+ dependency_item->set_text(0, rd.dependency);
+ dependency_item->set_icon(0, get_icon("Warning", "EditorIcons"));
+ tree_items[rd.dependency] = dependency_item;
}
- TreeItem *ti = owners->create_item(files[which]);
- ti->set_text(0, efsd->get_file_path(i));
- ti->set_icon(0, icon);
}
+
+ //List this file under this dependency
+ Ref<Texture> icon = has_icon(rd.file_type, "EditorIcons") ? get_icon(rd.file_type, "EditorIcons") : get_icon("Object", "EditorIcons");
+ TreeItem *file_item = owners->create_item(tree_items[rd.dependency]);
+ file_item->set_text(0, rd.file);
+ file_item->set_icon(0, icon);
}
}
-void DependencyRemoveDialog::show(const Vector<String> &to_erase) {
-
- exist = false;
+void DependencyRemoveDialog::show(const Vector<String> &p_folders, const Vector<String> &p_files) {
+ all_remove_files.clear();
+ to_delete.clear();
owners->clear();
- files.clear();
- owners->create_item(); // root
- for (int i = 0; i < to_erase.size(); i++) {
- files[to_erase[i]] = NULL;
+
+ for (int i = 0; i < p_folders.size(); ++i) {
+ String folder = p_folders[i].ends_with("/") ? p_folders[i] : (p_folders[i] + "/");
+ _find_files_in_removed_folder(EditorFileSystem::get_singleton()->get_filesystem_path(folder), folder);
+ to_delete.push_back(folder);
+ }
+ for (int i = 0; i < p_files.size(); ++i) {
+ all_remove_files[p_files[i]] = String();
+ to_delete.push_back(p_files[i]);
}
- _fill_owners(EditorFileSystem::get_singleton()->get_filesystem());
+ Vector<RemovedDependency> removed_deps;
+ _find_all_removed_dependencies(EditorFileSystem::get_singleton()->get_filesystem(), removed_deps);
+ removed_deps.sort();
- if (exist) {
- owners->show();
- text->set_text(TTR("The files being removed are required by other resources in order for them to work.\nRemove them anyway? (no undo)"));
- popup_centered_minsize(Size2(500, 220));
- } else {
+ if (removed_deps.empty()) {
owners->hide();
text->set_text(TTR("Remove selected files from the project? (no undo)"));
popup_centered_minsize(Size2(400, 100));
+ } else {
+ _build_removed_dependency_tree(removed_deps);
+ owners->show();
+ text->set_text(TTR("The files being removed are required by other resources in order for them to work.\nRemove them anyway? (no undo)"));
+ popup_centered_minsize(Size2(500, 350));
}
}
void DependencyRemoveDialog::ok_pressed() {
-
- 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());
+ bool files_only = true;
+ for (int i = 0; i < to_delete.size(); ++i) {
+ if (to_delete[i].ends_with("/")) {
+ files_only = false;
+ } else if (ResourceCache::has(to_delete[i])) {
+ Resource *res = ResourceCache::get(to_delete[i]);
res->set_path(""); //clear reference to path
}
- String fpath = OS::get_singleton()->get_resource_dir() + E->key().replace_first("res://", "/");
- OS::get_singleton()->move_to_trash(fpath);
- changed = true;
+
+ String path = OS::get_singleton()->get_resource_dir() + to_delete[i].replace_first("res://", "/");
+ print_line("Moving to trash: " + path);
+ Error err = OS::get_singleton()->move_to_trash(path);
+ if (err != OK) {
+ EditorNode::get_singleton()->add_io_error(TTR("Cannot remove:\n") + to_delete[i] + "\n");
+ }
}
- if (changed) {
+ if (files_only) {
+ //If we only deleted files we should only need to tell the file system about the files we touched.
+ for (int i = 0; i < to_delete.size(); ++i) {
+ EditorFileSystem::get_singleton()->update_file(to_delete[i]);
+ }
+ } else {
EditorFileSystem::get_singleton()->scan_changes();
}
}
diff --git a/editor/dependency_editor.h b/editor/dependency_editor.h
index 4dfb9de268..c7e9baa5c2 100644
--- a/editor/dependency_editor.h
+++ b/editor/dependency_editor.h
@@ -84,14 +84,33 @@ class DependencyRemoveDialog : public ConfirmationDialog {
Label *text;
Tree *owners;
- bool exist;
- Map<String, TreeItem *> files;
- void _fill_owners(EditorFileSystemDirectory *efsd);
+
+ Map<String, String> all_remove_files;
+ Vector<String> to_delete;
+
+ struct RemovedDependency {
+ String file;
+ String file_type;
+ String dependency;
+ String dependency_folder;
+
+ bool operator<(const RemovedDependency &p_other) const {
+ if (dependency_folder.empty() != p_other.dependency_folder.empty()) {
+ return p_other.dependency_folder.empty();
+ } else {
+ return dependency < p_other.dependency;
+ }
+ }
+ };
+
+ void _find_files_in_removed_folder(EditorFileSystemDirectory *efsd, const String &p_folder);
+ void _find_all_removed_dependencies(EditorFileSystemDirectory *efsd, Vector<RemovedDependency> &p_removed);
+ void _build_removed_dependency_tree(const Vector<RemovedDependency> &p_removed);
void ok_pressed();
public:
- void show(const Vector<String> &to_erase);
+ void show(const Vector<String> &p_folders, const Vector<String> &p_files);
DependencyRemoveDialog();
};
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index 028ea395ce..d1b79cca17 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -937,26 +937,25 @@ void FileSystemDock::_file_option(int p_option) {
rename_dialog_text->grab_focus();
} break;
case FILE_REMOVE: {
-
- Vector<String> torem;
+ Vector<String> remove_files;
+ Vector<String> remove_folders;
for (int i = 0; i < files->get_item_count(); i++) {
-
String path = files->get_item_metadata(i);
- if (!files->is_selected(i))
- continue;
- torem.push_back(path);
+ if (files->is_selected(i) && path != "res://") {
+ if (path.ends_with("/")) {
+ remove_folders.push_back(path);
+ } else {
+ remove_files.push_back(path);
+ }
+ }
}
- if (torem.empty()) {
- EditorNode::get_singleton()->show_warning(TTR("No files selected!"));
- break;
+ if (remove_files.size() + remove_folders.size() > 0) {
+ remove_dialog->show(remove_folders, remove_files);
+ //1) find if used
+ //2) warn
}
-
- remove_dialog->show(torem);
- //1) find if used
- //2) warn
-
} break;
case FILE_INFO: {
@@ -1044,6 +1043,15 @@ void FileSystemDock::_folder_option(int p_option) {
rename_dialog_text->grab_focus();
}
} break;
+ case FOLDER_REMOVE: {
+ Vector<String> remove_folders;
+ Vector<String> remove_files;
+ String path = item->get_metadata(tree->get_selected_column());
+ if (path != "res://") {
+ remove_folders.push_back(path);
+ remove_dialog->show(remove_folders, remove_files);
+ }
+ } break;
case FOLDER_COPY_PATH: {
String path = item->get_metadata(tree->get_selected_column());
OS::get_singleton()->set_clipboard(path);
@@ -1099,6 +1107,7 @@ void FileSystemDock::_dir_rmb_pressed(const Vector2 &p_pos) {
if (fpath != "res://") {
folder_options->add_item(TTR("Rename.."), FOLDER_RENAME);
folder_options->add_item(TTR("Move To.."), FOLDER_MOVE);
+ folder_options->add_item(TTR("Delete"), FOLDER_REMOVE);
}
folder_options->add_separator();
folder_options->add_item(TTR("Show In File Manager"), FOLDER_SHOW_IN_EXPLORER);
diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h
index 1491e1c7a7..e2d1a69137 100644
--- a/editor/filesystem_dock.h
+++ b/editor/filesystem_dock.h
@@ -81,6 +81,7 @@ private:
FOLDER_COLLAPSE_ALL,
FOLDER_MOVE,
FOLDER_RENAME,
+ FOLDER_REMOVE,
FOLDER_SHOW_IN_EXPLORER,
FOLDER_COPY_PATH
};