void ScriptCreateDialog::_path_changed(const String &p_path) { is_path_valid = false; is_new_script_created = true; String p = p_path; if (p == "") { _msg_path_valid(false, TTR("Path is empty")); _update_dialog(); return; } p = ProjectSettings::get_singleton()->localize_path(p); if (!p.begins_with("res://")) { _msg_path_valid(false, TTR("Path is not local")); _update_dialog(); return; } if (p.find("/") || p.find("\\")) { DirAccess *d = DirAccess::create(DirAccess::ACCESS_RESOURCES); if (d->change_dir(p.get_base_dir()) != OK) { _msg_path_valid(false, TTR("Invalid base path")); memdelete(d); _update_dialog(); return; } memdelete(d); } /* Does file already exist */ DirAccess *f = DirAccess::create(DirAccess::ACCESS_RESOURCES); if (f->dir_exists(p)) { is_new_script_created = false; is_path_valid = false; _msg_path_valid(false, TTR("Directory of the same name exists")); } else if (f->file_exists(p)) { is_new_script_created = false; is_path_valid = true; _msg_path_valid(true, TTR("File exists, will be reused")); } else { path_error_label->set_text(""); } memdelete(f); _update_dialog(); /* Check file extension */ String extension = p.get_extension(); List<String> extensions; // get all possible extensions for script for (int l = 0; l < language_menu->get_item_count(); l++) { ScriptServer::get_language(l)->get_recognized_extensions(&extensions); } bool found = false; bool match = false; int index = 0; for (List<String>::Element *E = extensions.front(); E; E = E->next()) { if (E->get().nocasecmp_to(extension) == 0) { //FIXME (?) - changing language this way doesn't update controls, needs rework //language_menu->select(index); // change Language option by extension found = true; if (E->get() == ScriptServer::get_language(language_menu->get_selected())->get_extension()) { match = true; } break; } index++; } if (!found) { _msg_path_valid(false, TTR("Invalid extension")); _update_dialog(); return; } if (!match) { _msg_path_valid(false, TTR("Wrong extension chosen")); _update_dialog(); return; } /* All checks passed */ is_path_valid = true; _update_dialog(); }
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 ScriptCreateDialog::_lang_changed(int l) { l = language_menu->get_selected(); ScriptLanguage *language = ScriptServer::get_language(l); if (language->has_named_classes()) { has_named_classes = true; } else { has_named_classes = false; } if (language->supports_builtin_mode()) { supports_built_in = true; } else { supports_built_in = false; is_built_in = false; } if (ScriptServer::get_language(l)->can_inherit_from_file()) { can_inherit_from_file = true; } else { can_inherit_from_file = false; } String selected_ext = "." + language->get_extension(); String path = file_path->get_text(); String extension = ""; if (path != "") { if (path.find(".") >= 0) { extension = path.get_extension(); } if (extension.length() == 0) { // add extension if none path += selected_ext; _path_changed(path); } else { // change extension by selected language List<String> extensions; // get all possible extensions for script for (int l = 0; l < language_menu->get_item_count(); l++) { ScriptServer::get_language(l)->get_recognized_extensions(&extensions); } for (List<String>::Element *E = extensions.front(); E; E = E->next()) { if (E->get().nocasecmp_to(extension) == 0) { path = path.get_basename() + selected_ext; _path_changed(path); break; } } } } else { path = "class" + selected_ext; _path_changed(path); } file_path->set_text(path); bool use_templates = language->is_using_templates(); template_menu->set_disabled(!use_templates); template_menu->clear(); if (use_templates) { template_list = EditorSettings::get_singleton()->get_script_templates(language->get_extension()); String last_lang = EditorSettings::get_singleton()->get_project_metadata("script_setup", "last_selected_language", ""); String last_template = EditorSettings::get_singleton()->get_project_metadata("script_setup", "last_selected_template", ""); template_menu->add_item(TTR("Default")); for (int i = 0; i < template_list.size(); i++) { String s = template_list[i].capitalize(); template_menu->add_item(s); if (language_menu->get_item_text(language_menu->get_selected()) == last_lang && last_template == s) { template_menu->select(i + 1); } } } else { template_menu->add_item(TTR("N/A")); script_template = ""; } _template_changed(template_menu->get_selected()); EditorSettings::get_singleton()->set_project_metadata("script_setup", "last_selected_language", language_menu->get_item_text(language_menu->get_selected())); _update_dialog(); }
String ResourceFormatLoaderNativeScript::get_resource_type(const String &p_path) const { String el = p_path.get_extension().to_lower(); if (el == "gdns") return "NativeScript"; return ""; }
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(); 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); fi->import_valid = ResourceLoader::is_import_valid(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 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) { reimport = true; //it was modified, must be reimported. } else if (!FileAccess::exists(path + ".import")) { reimport = true; //no .import file, obviously reimport } else { uint64_t import_mt = FileAccess::get_modified_time(path + ".import"); if (import_mt != p_dir->files[i]->import_modified_time) { reimport = true; } else if (!_check_missing_imported_files(path)) { 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); } } } 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); } }
void EditorFileSystem::_reimport_file(const String &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()->has_setting("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 (err == OK) { 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() + "\""); } } else { f->store_line("valid=false"); } 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(); fs->files[cpos]->import_valid = ResourceLoader::is_import_valid(p_file); //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); } } EditorResourcePreview::get_singleton()->check_for_invalidation(p_file); }
String ResourceFormatLoaderVideoStreamGDNative::get_resource_type(const String &p_path) const { String el = p_path.get_extension().to_lower(); if (VideoDecoderServer::get_instance()->get_extensions().has(el)) return "VideoStreamGDNative"; 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; }