Example #1
0
void FindInFiles::_scan_dir(String path, PoolStringArray &out_folders) {

	DirAccess *dir = DirAccess::open(path);
	if (dir == NULL) {
		print_line("Cannot open directory! " + path);
		return;
	}

	dir->list_dir_begin();

	for (int i = 0; i < 1000; ++i) {
		String file = dir->get_next();

		if (file == "")
			break;

		// Ignore special dirs and hidden dirs (such as .git and .import)
		if (file == "." || file == ".." || file.begins_with("."))
			continue;

		if (dir->current_is_dir())
			out_folders.append(file);

		else {
			String file_ext = file.get_extension();
			if (_extension_filter.has(file_ext)) {
				_files_to_scan.push_back(path.plus_file(file));
			}
		}
	}
}
Error ResourceImporterImage::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) {

	FileAccess *f = FileAccess::open(p_source_file, FileAccess::READ);
	if (!f) {
		ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
	}

	size_t len = f->get_len();

	Vector<uint8_t> data;
	data.resize(len);

	f->get_buffer(data.ptrw(), len);

	memdelete(f);

	f = FileAccess::open(p_save_path + ".image", FileAccess::WRITE);

	//save the header GDIM
	const uint8_t header[4] = { 'G', 'D', 'I', 'M' };
	f->store_buffer(header, 4);
	//SAVE the extension (so it can be recognized by the loader later
	f->store_pascal_string(p_source_file.get_extension().to_lower());
	//SAVE the actual image
	f->store_buffer(data.ptr(), len);

	memdelete(f);

	return OK;
}
Example #3
0
String ResourceFormatLoaderDynamicFont::get_resource_type(const String &p_path) const {

	String el = p_path.get_extension().to_lower();
	if (el == "ttf")
		return "DynamicFontData";
	return "";
}
Example #4
0
Error ImageLoader::load_image(String p_file, Ref<Image> p_image, FileAccess *p_custom, bool p_force_linear, float p_scale) {
	ERR_FAIL_COND_V(p_image.is_null(), ERR_INVALID_PARAMETER);

	FileAccess *f = p_custom;
	if (!f) {
		Error err;
		f = FileAccess::open(p_file, FileAccess::READ, &err);
		if (!f) {
			ERR_PRINTS("Error opening file: " + p_file);
			return err;
		}
	}

	String extension = p_file.get_extension();

	for (int i = 0; i < loader.size(); i++) {

		if (!loader[i]->recognize(extension))
			continue;
		Error err = loader[i]->load_image(p_image, f, p_force_linear, p_scale);

		if (err != ERR_FILE_UNRECOGNIZED) {

			if (!p_custom)
				memdelete(f);

			return err;
		}
	}

	if (!p_custom)
		memdelete(f);

	return ERR_FILE_UNRECOGNIZED;
}
Example #5
0
String ResourceFormatLoaderVideoStreamTheora::get_resource_type(const String &p_path) const {

	String exl = p_path.get_extension().to_lower();
	if (exl == "ogm" || exl == "ogv")
		return "VideoStreamTheora";
	return "";
}
Example #6
0
void GodotSharpExport::_export_file(const String &p_path, const String &p_type, const Set<String> &) {

	if (p_type != CSharpLanguage::get_singleton()->get_type())
		return;

	ERR_FAIL_COND(p_path.get_extension() != CSharpLanguage::get_singleton()->get_extension());

	// TODO what if the source file is not part of the game's C# project

	if (!GLOBAL_GET("mono/export/include_scripts_content")) {
		// We don't want to include the source code on exported games
		add_file(p_path, Vector<uint8_t>(), false);
		skip();
	}
}
Example #7
0
bool ResourceFormatLoader::recognize_path(const String &p_path, const String &p_for_type) const {

	String extension = p_path.get_extension();

	List<String> extensions;
	if (p_for_type == String()) {
		get_recognized_extensions(&extensions);
	} else {
		get_recognized_extensions_for_type(p_for_type, &extensions);
	}

	for (List<String>::Element *E = extensions.front(); E; E = E->next()) {

		if (E->get().nocasecmp_to(extension) == 0)
			return true;
	}

	return false;
}
Example #8
0
int ResourceFormatImporter::get_import_order(const String &p_path) const {

	Ref<ResourceImporter> importer;

	if (FileAccess::exists(p_path + ".import")) {

		PathAndType pat;
		Error err = _get_path_and_type(p_path, pat);

		if (err == OK) {
			importer = get_importer_by_name(pat.importer);
		}
	} else {

		importer = get_importer_by_extension(p_path.get_extension().to_lower());
	}

	if (importer.is_valid())
		return importer->get_import_order();

	return 0;
}
Example #9
0
String ResourceFormatLoaderNativeScript::get_resource_type(const String &p_path) const {
	String el = p_path.get_extension().to_lower();
	if (el == "gdns")
		return "NativeScript";
	return "";
}
Example #10
0
void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir,const ScanProgress& p_progress) {

	uint64_t current_mtime = FileAccess::get_modified_time(p_dir->get_path());

	bool updated_dir=false;

	//print_line("dir: "+p_dir->get_path()+" MODTIME: "+itos(p_dir->modified_time)+" CTIME: "+itos(current_mtime));

	if (current_mtime!=p_dir->modified_time) {

		updated_dir=true;
		p_dir->modified_time=current_mtime;
		//ooooops, dir changed, see what's going on

		//first mark everything as veryfied

		for(int i=0;i<p_dir->files.size();i++) {

			p_dir->files[i]->verified=false;
		}

		for(int i=0;i<p_dir->subdirs.size();i++) {

			p_dir->get_subdir(i)->verified=false;
		}

		//then scan files and directories and check what's different

		DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
		String cd = p_dir->get_path();
		da->change_dir(cd);
		da->list_dir_begin();
		while (true) {

			bool isdir;
			String f = da->get_next(&isdir);
			if (f=="")
				break;

			if (isdir) {

				if (f.begins_with(".")) //ignore hidden and . / ..
					continue;

				int idx = p_dir->find_dir_index(f);
				if (idx==-1) {

					if (FileAccess::exists(cd.plus_file(f).plus_file("engine.cfg"))) // skip if another project inside this
						continue;

					EditorFileSystemDirectory *efd = memnew( EditorFileSystemDirectory );

					efd->parent=p_dir;
					efd->name=f;
					DirAccess *d = DirAccess::create(DirAccess::ACCESS_RESOURCES);
					d->change_dir(cd.plus_file(f));
					_scan_new_dir(efd,d,p_progress.get_sub(1,1));
					memdelete(d);


					ItemAction ia;
					ia.action=ItemAction::ACTION_DIR_ADD;
					ia.dir=p_dir;
					ia.file=f;
					ia.new_dir=efd;
					scan_actions.push_back(ia);
				} else {
					p_dir->subdirs[idx]->verified=true;
				}


			} else {
				String ext = f.get_extension().to_lower();
				if (!valid_extensions.has(ext))
					continue; //invalid

				int idx = p_dir->find_file_index(f);

				if (idx==-1) {
					//never seen this file, add actition to add it
					EditorFileSystemDirectory::FileInfo *fi = memnew( EditorFileSystemDirectory::FileInfo );
					fi->file=f;

					String path = cd.plus_file(fi->file);
					fi->modified_time=FileAccess::get_modified_time(path);
					fi->meta=_get_meta(path);
					fi->type=ResourceLoader::get_resource_type(path);

					{
						ItemAction ia;
						ia.action=ItemAction::ACTION_FILE_ADD;
						ia.dir=p_dir;
						ia.file=f;
						ia.new_file=fi;
						scan_actions.push_back(ia);
					}

					//take the chance and scan sources
					if (_check_meta_sources(fi->meta)) {

						ItemAction ia;
						ia.action=ItemAction::ACTION_FILE_SOURCES_CHANGED;
						ia.dir=p_dir;
						ia.file=f;
						scan_actions.push_back(ia);
						fi->meta.sources_changed=true;
					} else {
						fi->meta.sources_changed=false;
					}

				} else {
					p_dir->files[idx]->verified=true;
				}


			}

		}

		da->list_dir_end();
		memdelete(da);

	}

	for(int i=0;i<p_dir->files.size();i++) {

		if (updated_dir && !p_dir->files[i]->verified) {
			//this file was removed, add action to remove it
			ItemAction ia;
			ia.action=ItemAction::ACTION_FILE_REMOVE;
			ia.dir=p_dir;
			ia.file=p_dir->files[i]->file;
			scan_actions.push_back(ia);
			continue;

		}

		if (_check_meta_sources(p_dir->files[i]->meta)) {
			ItemAction ia;
			ia.action=ItemAction::ACTION_FILE_SOURCES_CHANGED;
			ia.dir=p_dir;
			ia.file=p_dir->files[i]->file;
			scan_actions.push_back(ia);
			p_dir->files[i]->meta.sources_changed=true;
		} else {
			p_dir->files[i]->meta.sources_changed=false;
		}

		EditorResourcePreview::get_singleton()->check_for_invalidation(p_dir->get_file_path(i));
	}

	for(int i=0;i<p_dir->subdirs.size();i++) {

		if (updated_dir && !p_dir->subdirs[i]->verified) {
			//this directory was removed, add action to remove it
			ItemAction ia;
			ia.action=ItemAction::ACTION_DIR_REMOVE;
			ia.dir=p_dir->subdirs[i];
			scan_actions.push_back(ia);
			continue;

		}
		_scan_fs_changes(p_dir->get_subdir(i),p_progress);
	}

}
Example #11
0
String ResourceFormatPKM::get_resource_type(const String &p_path) const {

	if (p_path.get_extension().to_lower() == "pkm")
		return "ImageTexture";
	return "";
}
Example #12
0
void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const ScanProgress &p_progress) {

	uint64_t current_mtime = FileAccess::get_modified_time(p_dir->get_path());

	bool updated_dir = false;
	String cd = p_dir->get_path();

	//print_line("dir: "+p_dir->get_path()+" MODTIME: "+itos(p_dir->modified_time)+" CTIME: "+itos(current_mtime));

	if (current_mtime != p_dir->modified_time) {

		updated_dir = true;
		p_dir->modified_time = current_mtime;
		//ooooops, dir changed, see what's going on

		//first mark everything as veryfied

		for (int i = 0; i < p_dir->files.size(); i++) {

			p_dir->files[i]->verified = false;
		}

		for (int i = 0; i < p_dir->subdirs.size(); i++) {

			p_dir->get_subdir(i)->verified = false;
		}

		//then scan files and directories and check what's different

		DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);

		da->change_dir(cd);
		da->list_dir_begin();
		while (true) {

			bool isdir;
			String f = da->get_next(&isdir);
			if (f == "")
				break;

			if (isdir) {

				if (f.begins_with(".")) //ignore hidden and . / ..
					continue;

				int idx = p_dir->find_dir_index(f);
				if (idx == -1) {

					if (FileAccess::exists(cd.plus_file(f).plus_file("project.godot"))) // skip if another project inside this
						continue;
					if (FileAccess::exists(cd.plus_file(f).plus_file(".gdignore"))) // skip if another project inside this
						continue;

					EditorFileSystemDirectory *efd = memnew(EditorFileSystemDirectory);

					efd->parent = p_dir;
					efd->name = f;
					DirAccess *d = DirAccess::create(DirAccess::ACCESS_RESOURCES);
					d->change_dir(cd.plus_file(f));
					_scan_new_dir(efd, d, p_progress.get_sub(1, 1));
					memdelete(d);

					ItemAction ia;
					ia.action = ItemAction::ACTION_DIR_ADD;
					ia.dir = p_dir;
					ia.file = f;
					ia.new_dir = efd;
					scan_actions.push_back(ia);
				} else {
					p_dir->subdirs[idx]->verified = true;
				}

			} else {
				String ext = f.get_extension().to_lower();
				if (!valid_extensions.has(ext))
					continue; //invalid

				int idx = p_dir->find_file_index(f);

				if (idx == -1) {
					//never seen this file, add actition to add it
					EditorFileSystemDirectory::FileInfo *fi = memnew(EditorFileSystemDirectory::FileInfo);
					fi->file = f;

					String path = cd.plus_file(fi->file);
					fi->modified_time = FileAccess::get_modified_time(path);
					fi->import_modified_time = 0;
					fi->type = ResourceLoader::get_resource_type(path);

					{
						ItemAction ia;
						ia.action = ItemAction::ACTION_FILE_ADD;
						ia.dir = p_dir;
						ia.file = f;
						ia.new_file = fi;
						scan_actions.push_back(ia);
					}

					if (import_extensions.has(ext)) {
						//if it can be imported, and it was added, it needs to be reimported
						print_line("REIMPORT: file was not found before, reimport");
						print_line("at dir: " + p_dir->get_path() + " file: " + f);
						for (int i = 0; i < p_dir->files.size(); i++) {
							print_line(itos(i) + ": " + p_dir->files[i]->file);
						}
						ItemAction ia;
						ia.action = ItemAction::ACTION_FILE_REIMPORT;
						ia.dir = p_dir;
						ia.file = f;
						scan_actions.push_back(ia);
					}

				} else {
					p_dir->files[idx]->verified = true;
				}
			}
		}

		da->list_dir_end();
		memdelete(da);
	}

	for (int i = 0; i < p_dir->files.size(); i++) {

		if (updated_dir && !p_dir->files[i]->verified) {
			//this file was removed, add action to remove it
			ItemAction ia;
			ia.action = ItemAction::ACTION_FILE_REMOVE;
			ia.dir = p_dir;
			ia.file = p_dir->files[i]->file;
			scan_actions.push_back(ia);
			continue;
		}

		if (import_extensions.has(p_dir->files[i]->file.get_extension().to_lower())) {
			//check here if file must be imported or not

			String path = cd.plus_file(p_dir->files[i]->file);

			uint64_t mt = FileAccess::get_modified_time(path);

			bool reimport = false;

			if (mt != p_dir->files[i]->modified_time) {
				print_line("REIMPORT: modified time changed, reimport");
				reimport = true; //it was modified, must be reimported.
			} else if (!FileAccess::exists(path + ".import")) {
				print_line("REIMPORT: no .import exists, reimport");
				reimport = true; //no .import file, obviously reimport
			} else {

				uint64_t import_mt = FileAccess::get_modified_time(path + ".import");
				//print_line(itos(import_mt) + " vs " + itos(p_dir->files[i]->import_modified_time));
				if (import_mt != p_dir->files[i]->import_modified_time) {
					print_line("REIMPORT: import modified changed, reimport");
					reimport = true;
				} else if (!_check_missing_imported_files(path)) {
					print_line("REIMPORT: imported files removed");
					reimport = true;
				}
			}

			if (reimport) {

				ItemAction ia;
				ia.action = ItemAction::ACTION_FILE_REIMPORT;
				ia.dir = p_dir;
				ia.file = p_dir->files[i]->file;
				scan_actions.push_back(ia);
			}
		}

		EditorResourcePreview::get_singleton()->check_for_invalidation(p_dir->get_file_path(i));
	}

	for (int i = 0; i < p_dir->subdirs.size(); i++) {

		if (updated_dir && !p_dir->subdirs[i]->verified) {
			//this directory was removed, add action to remove it
			ItemAction ia;
			ia.action = ItemAction::ACTION_DIR_REMOVE;
			ia.dir = p_dir->subdirs[i];
			scan_actions.push_back(ia);
			continue;
		}
		_scan_fs_changes(p_dir->get_subdir(i), p_progress);
	}
}
Example #13
0
void EditorFileSystem::_reimport_file(const String &p_file) {

	print_line("REIMPORTING: " + p_file);

	EditorFileSystemDirectory *fs = NULL;
	int cpos = -1;
	bool found = _find_file(p_file, &fs, cpos);
	ERR_FAIL_COND(!found);

	//try to obtain existing params

	Map<StringName, Variant> params;
	String importer_name;

	if (FileAccess::exists(p_file + ".import")) {
		//use existing
		Ref<ConfigFile> cf;
		cf.instance();
		Error err = cf->load(p_file + ".import");
		if (err == OK) {
			List<String> sk;
			cf->get_section_keys("params", &sk);
			for (List<String>::Element *E = sk.front(); E; E = E->next()) {
				params[E->get()] = cf->get_value("params", E->get());
			}
			importer_name = cf->get_value("remap", "importer");
		}

	} else {
		late_added_files.insert(p_file); //imported files do not call update_file(), but just in case..
	}

	Ref<ResourceImporter> importer;
	bool load_default = false;
	//find the importer
	if (importer_name != "") {
		importer = ResourceFormatImporter::get_singleton()->get_importer_by_name(importer_name);
	}

	if (importer.is_null()) {
		//not found by name, find by extension
		importer = ResourceFormatImporter::get_singleton()->get_importer_by_extension(p_file.get_extension());
		load_default = true;
		if (importer.is_null()) {
			ERR_PRINT("BUG: File queued for import, but can't be imported!");
			ERR_FAIL();
		}
	}

	//mix with default params, in case a parameter is missing

	List<ResourceImporter::ImportOption> opts;
	importer->get_import_options(&opts);
	for (List<ResourceImporter::ImportOption>::Element *E = opts.front(); E; E = E->next()) {
		if (!params.has(E->get().option.name)) { //this one is not present
			params[E->get().option.name] = E->get().default_value;
		}
	}

	if (load_default && ProjectSettings::get_singleton()->get("importer_defaults/" + importer->get_importer_name())) {
		//use defaults if exist
		Dictionary d = ProjectSettings::get_singleton()->get("importer_defaults/" + importer->get_importer_name());
		List<Variant> v;
		d.get_key_list(&v);

		for (List<Variant>::Element *E = v.front(); E; E = E->next()) {
			params[E->get()] = d[E->get()];
		}
	}

	//finally, perform import!!
	String base_path = ResourceFormatImporter::get_singleton()->get_import_base_path(p_file);

	List<String> import_variants;
	List<String> gen_files;

	Error err = importer->import(p_file, base_path, params, &import_variants, &gen_files);

	if (err != OK) {
		ERR_PRINTS("Error importing: " + p_file);
	}

	//as import is complete, save the .import file

	FileAccess *f = FileAccess::open(p_file + ".import", FileAccess::WRITE);
	ERR_FAIL_COND(!f);

	//write manually, as order matters ([remap] has to go first for performance).
	f->store_line("[remap]");
	f->store_line("");
	f->store_line("importer=\"" + importer->get_importer_name() + "\"");
	if (importer->get_resource_type() != "") {
		f->store_line("type=\"" + importer->get_resource_type() + "\"");
	}

	if (importer->get_save_extension() == "") {
		//no path
	} else if (import_variants.size()) {
		//import with variants
		for (List<String>::Element *E = import_variants.front(); E; E = E->next()) {

			String path = base_path.c_escape() + "." + E->get() + "." + importer->get_save_extension();

			f->store_line("path." + E->get() + "=\"" + path + "\"");
		}
	} else {

		f->store_line("path=\"" + base_path + "." + importer->get_save_extension() + "\"");
	}

	f->store_line("");

	if (gen_files.size()) {
		f->store_line("[gen]");
		Array genf;
		for (List<String>::Element *E = gen_files.front(); E; E = E->next()) {
			genf.push_back(E->get());
		}

		String value;
		VariantWriter::write_to_string(genf, value);
		f->store_line("files=" + value);
		f->store_line("");
	}

	f->store_line("[params]");
	f->store_line("");

	//store options in provided order, to avoid file changing. Order is also important because first match is accepted first.

	for (List<ResourceImporter::ImportOption>::Element *E = opts.front(); E; E = E->next()) {

		String base = E->get().option.name;
		String value;
		VariantWriter::write_to_string(params[base], value);
		f->store_line(base + "=" + value);
	}

	f->close();
	memdelete(f);

	//update modified times, to avoid reimport
	fs->files[cpos]->modified_time = FileAccess::get_modified_time(p_file);
	fs->files[cpos]->import_modified_time = FileAccess::get_modified_time(p_file + ".import");
	fs->files[cpos]->deps = _get_dependencies(p_file);
	fs->files[cpos]->type = importer->get_resource_type();

	//if file is currently up, maybe the source it was loaded from changed, so import math must be updated for it
	//to reload properly
	if (ResourceCache::has(p_file)) {

		Resource *r = ResourceCache::get(p_file);

		if (r->get_import_path() != String()) {

			String dst_path = ResourceFormatImporter::get_singleton()->get_internal_resource_path(p_file);
			r->set_import_path(dst_path);
			r->set_import_last_modified_time(0);
		}
	}
}
Example #14
0
String ResourceFormatLoaderImage::get_resource_type(const String &p_path) const {

	return p_path.get_extension().to_lower() == "image" ? "Image" : String();
}
Example #15
0
String GDNativeLibraryResourceLoader::get_resource_type(const String &p_path) const {
	String el = p_path.get_extension().to_lower();
	if (el == "gdnlib")
		return "GDNativeLibrary";
	return "";
}
void EditorAssetInstaller::open(const String &p_path, int p_depth) {

	package_path = p_path;
	Set<String> files_sorted;

	FileAccess *src_f = NULL;
	zlib_filefunc_def io = zipio_create_io_from_file(&src_f);

	unzFile pkg = unzOpen2(p_path.utf8().get_data(), &io);
	if (!pkg) {

		error->set_text(TTR("Error opening package file, not in zip format."));
		return;
	}

	int ret = unzGoToFirstFile(pkg);

	while (ret == UNZ_OK) {

		//get filename
		unz_file_info info;
		char fname[16384];
		unzGetCurrentFileInfo(pkg, &info, fname, 16384, NULL, 0, NULL, 0);

		String name = fname;
		files_sorted.insert(name);

		ret = unzGoToNextFile(pkg);
	}

	Map<String, Ref<Texture> > extension_guess;
	{
		extension_guess["png"] = get_icon("Texture", "EditorIcons");
		extension_guess["jpg"] = get_icon("Texture", "EditorIcons");
		extension_guess["tex"] = get_icon("Texture", "EditorIcons");
		extension_guess["atlastex"] = get_icon("Texture", "EditorIcons");
		extension_guess["dds"] = get_icon("Texture", "EditorIcons");
		extension_guess["scn"] = get_icon("PackedScene", "EditorIcons");
		extension_guess["tscn"] = get_icon("PackedScene", "EditorIcons");
		extension_guess["xml"] = get_icon("PackedScene", "EditorIcons");
		extension_guess["xscn"] = get_icon("PackedScene", "EditorIcons");
		extension_guess["material"] = get_icon("Material", "EditorIcons");
		extension_guess["shd"] = get_icon("Shader", "EditorIcons");
		extension_guess["gd"] = get_icon("GDScript", "EditorIcons");
	}

	Ref<Texture> generic_extension = get_icon("Object", "EditorIcons");

	unzClose(pkg);

	updating = true;
	tree->clear();
	TreeItem *root = tree->create_item();
	root->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
	root->set_checked(0, true);
	root->set_icon(0, get_icon("folder", "FileDialog"));
	root->set_text(0, "res://");
	root->set_editable(0, true);
	Map<String, TreeItem *> dir_map;

	for (Set<String>::Element *E = files_sorted.front(); E; E = E->next()) {

		String path = E->get();
		int depth = p_depth;
		bool skip = false;
		while (depth > 0) {
			int pp = path.find("/");
			if (pp == -1) {
				skip = true;
				break;
			}
			path = path.substr(pp + 1, path.length());
			depth--;
		}

		if (skip || path == String())
			continue;

		bool isdir = false;

		if (path.ends_with("/")) {
			//a directory
			path = path.substr(0, path.length() - 1);
			isdir = true;
		}

		int pp = path.find_last("/");

		TreeItem *parent;
		if (pp == -1) {
			parent = root;
		} else {
			String ppath = path.substr(0, pp);
			ERR_CONTINUE(!dir_map.has(ppath));
			parent = dir_map[ppath];
		}

		TreeItem *ti = tree->create_item(parent);
		ti->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
		ti->set_checked(0, true);
		ti->set_editable(0, true);
		if (isdir) {
			dir_map[path] = ti;
			ti->set_text(0, path.get_file() + "/");
			ti->set_icon(0, get_icon("folder", "FileDialog"));
			ti->set_metadata(0, String());
		} else {
			String file = path.get_file();
			String extension = file.get_extension().to_lower();
			if (extension_guess.has(extension)) {
				ti->set_icon(0, extension_guess[extension]);
			} else {
				ti->set_icon(0, generic_extension);
			}
			ti->set_text(0, file);

			String res_path = "res://" + path;
			if (FileAccess::exists(res_path)) {
				ti->set_custom_color(0, get_color("error_color", "Editor"));
				ti->set_tooltip(0, res_path + " (Already Exists)");
				ti->set_checked(0, false);
			} else {
				ti->set_tooltip(0, res_path);
			}

			ti->set_metadata(0, res_path);
		}

		status_map[E->get()] = ti;
	}
	popup_centered_ratio();
	updating = false;
}