Forráskód Böngészése

Merge pull request #66706 from PucklaMotzer09/fix_duplicate_uid

Make uids of duplicated items unique in FileSystemDock
Rémi Verschelde 2 éve
szülő
commit
9ba778e6f2
1 módosított fájl, 53 hozzáadás és 24 törlés
  1. 53 24
      editor/filesystem_dock.cpp

+ 53 - 24
editor/filesystem_dock.cpp

@@ -1283,42 +1283,71 @@ void FileSystemDock::_try_duplicate_item(const FileOrFolder &p_item, const Strin
 	}
 
 	Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
-	print_verbose("Duplicating " + old_path + " -> " + new_path);
-	Error err = p_item.is_file ? da->copy(old_path, new_path) : da->copy_dir(old_path, new_path);
-	if (err == OK) {
-		// Move/Rename any corresponding import settings too.
-		if (p_item.is_file && FileAccess::exists(old_path + ".import")) {
-			err = da->copy(old_path + ".import", new_path + ".import");
+
+	if (p_item.is_file) {
+		print_verbose("Duplicating " + old_path + " -> " + new_path);
+
+		// Create the directory structure.
+		da->make_dir_recursive(new_path.get_base_dir());
+
+		if (FileAccess::exists(old_path + ".import")) {
+			Error err = da->copy(old_path, new_path);
 			if (err != OK) {
-				EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + "\n" + old_path + ".import\n");
+				EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + "\n" + old_path + ": " + error_names[err] + "\n");
+				return;
 			}
 
 			// Remove uid from .import file to avoid conflict.
 			Ref<ConfigFile> cfg;
 			cfg.instantiate();
-			cfg->load(new_path + ".import");
+			cfg->load(old_path + ".import");
 			cfg->erase_section_key("remap", "uid");
-			cfg->save(new_path + ".import");
-		} else if (p_item.is_file && (old_path.get_extension() == "tscn" || old_path.get_extension() == "tres")) {
-			// FIXME: Quick hack to fix text resources. This should be fixed properly.
-			Ref<FileAccess> file = FileAccess::open(old_path, FileAccess::READ, &err);
-			if (err == OK) {
-				PackedStringArray lines = file->get_as_utf8_string().split("\n");
-				String line = lines[0];
-
-				if (line.contains("uid")) {
-					line = line.substr(0, line.find(" uid")) + "]";
-					lines.write[0] = line;
+			err = cfg->save(new_path + ".import");
+			if (err != OK) {
+				EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + "\n" + old_path + ".import: " + error_names[err] + "\n");
+				return;
+			}
+		} else {
+			// Files which do not use an uid can just be copied.
+			if (ResourceLoader::get_resource_uid(old_path) == ResourceUID::INVALID_ID) {
+				Error err = da->copy(old_path, new_path);
+				if (err != OK) {
+					EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + "\n" + old_path + ": " + error_names[err] + "\n");
+				}
+				return;
+			}
 
-					Ref<FileAccess> file2 = FileAccess::open(new_path, FileAccess::WRITE, &err);
-					if (err == OK) {
-						file2->store_string(String("\n").join(lines));
-					}
+			// Load the resource and save it again in the new location (this generates a new UID).
+			Error err;
+			Ref<Resource> res = ResourceLoader::load(old_path, "", ResourceFormatLoader::CACHE_MODE_REUSE, &err);
+			if (err == OK && res.is_valid()) {
+				err = ResourceSaver::save(res, new_path, ResourceSaver::FLAG_COMPRESS);
+				if (err != OK) {
+					EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + " " + vformat(TTR("Failed to save resource at %s: %s"), new_path, error_names[err]));
 				}
+			} else if (err != OK) {
+				// When loading files like text files the error is OK but the resource is still null.
+				// We can ignore such files.
+				EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + " " + vformat(TTR("Failed to load resource at %s: %s"), new_path, error_names[err]));
 			}
 		}
 	} else {
-		EditorNode::get_singleton()->add_io_error(TTR("Error duplicating:") + "\n" + old_path + "\n");
+		// Recursively duplicate all files inside the folder.
+		Ref<DirAccess> old_dir = DirAccess::open(old_path);
+		Ref<FileAccess> file_access = FileAccess::create(FileAccess::ACCESS_RESOURCES);
+		old_dir->set_include_navigational(false);
+		old_dir->list_dir_begin();
+		for (String f = old_dir->_get_next(); !f.is_empty(); f = old_dir->_get_next()) {
+			if (f.get_extension() == "import") {
+				continue;
+			}
+			if (file_access->file_exists(old_path + f)) {
+				_try_duplicate_item(FileOrFolder(old_path + f, true), new_path + f);
+			} else if (da->dir_exists(old_path + f)) {
+				_try_duplicate_item(FileOrFolder(old_path + f, false), new_path + f);
+			}
+		}
+		old_dir->list_dir_end();
 	}
 }