summaryrefslogtreecommitdiff
path: root/editor/dependency_editor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'editor/dependency_editor.cpp')
-rw-r--r--editor/dependency_editor.cpp209
1 files changed, 155 insertions, 54 deletions
diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp
index 5305c4f256..ec0ca3add5 100644
--- a/editor/dependency_editor.cpp
+++ b/editor/dependency_editor.cpp
@@ -281,6 +281,47 @@ DependencyEditor::DependencyEditor() {
}
/////////////////////////////////////
+void DependencyEditorOwners::_list_rmb_select(int p_item, const Vector2 &p_pos) {
+
+ file_options->clear();
+ file_options->set_size(Size2(1, 1));
+ if (p_item >= 0) {
+ file_options->add_item(TTR("Open"), FILE_OPEN);
+ }
+
+ file_options->set_position(owners->get_global_position() + p_pos);
+ file_options->popup();
+}
+
+void DependencyEditorOwners::_select_file(int p_idx) {
+
+ String fpath = owners->get_item_text(p_idx);
+
+ if (ResourceLoader::get_resource_type(fpath) == "PackedScene") {
+ editor->open_request(fpath);
+ hide();
+ emit_signal("confirmed");
+ }
+}
+
+void DependencyEditorOwners::_file_option(int p_option) {
+
+ switch (p_option) {
+ case FILE_OPEN: {
+ int idx = owners->get_current();
+ if (idx < 0 || idx >= owners->get_item_count())
+ break;
+ _select_file(idx);
+ } break;
+ }
+}
+
+void DependencyEditorOwners::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("_list_rmb_select"), &DependencyEditorOwners::_list_rmb_select);
+ ClassDB::bind_method(D_METHOD("_file_option"), &DependencyEditorOwners::_file_option);
+ ClassDB::bind_method(D_METHOD("_select_file"), &DependencyEditorOwners::_select_file);
+}
void DependencyEditorOwners::_fill_owners(EditorFileSystemDirectory *efsd) {
@@ -329,100 +370,160 @@ void DependencyEditorOwners::show(const String &p_path) {
set_title(TTR("Owners Of:") + " " + p_path.get_file());
}
-DependencyEditorOwners::DependencyEditorOwners() {
+DependencyEditorOwners::DependencyEditorOwners(EditorNode *p_editor) {
+
+ editor = p_editor;
+
+ file_options = memnew(PopupMenu);
+ add_child(file_options);
+ file_options->connect("id_pressed", this, "_file_option");
owners = memnew(ItemList);
+ owners->set_select_mode(ItemList::SELECT_SINGLE);
+ owners->connect("item_rmb_selected", this, "_list_rmb_select");
+ owners->connect("item_activated", this, "_select_file");
+ owners->set_allow_rmb_select(true);
add_child(owners);
}
///////////////////////
-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();
}
}
@@ -494,7 +595,7 @@ DependencyErrorDialog::DependencyErrorDialog() {
vb->add_margin_child(TTR("Scene failed to load due to missing dependencies:"), files, true);
files->set_v_size_flags(SIZE_EXPAND_FILL);
get_ok()->set_text(TTR("Open Anyway"));
- get_cancel()->set_text(TTR("Done"));
+ get_cancel()->set_text(TTR("Close"));
text = memnew(Label);
vb->add_child(text);