ProjectManager: Warn when projects have different config_version
When opening projects for edition through the project manager, the following checks are now done: 1. If the config_version is lower than the one used by the current engine version, users are asked if they want to convert to the new format or abort editing. Fixes #20626. 2. If the config_version is higher than the expected one (project from a more recent and incompatible engine version), projects are grayed out and can't be edited. Fixes #18758. When editing from the command line, the behaviour is unchanged: projects in situation (1) are automatically converted, while projects in situation (2) show an error message (made more explicit). The "Run" option from the project manager was not changed, so it will still run (1) projects without converting them, and fail running (2) projects. Co-authored-by: groud <gilles.roudiere@gmail.com>
This commit is contained in:
parent
be8c0d57c5
commit
616beb1041
4 changed files with 112 additions and 71 deletions
|
@ -43,8 +43,6 @@
|
|||
|
||||
#include <zlib.h>
|
||||
|
||||
#define FORMAT_VERSION 4
|
||||
|
||||
ProjectSettings *ProjectSettings::singleton = NULL;
|
||||
|
||||
ProjectSettings *ProjectSettings::get_singleton() {
|
||||
|
@ -271,9 +269,9 @@ bool ProjectSettings::_load_resource_pack(const String &p_pack) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void ProjectSettings::_convert_to_last_version() {
|
||||
if (!has_setting("config_version") || (int)get_setting("config_version") <= 3) {
|
||||
void ProjectSettings::_convert_to_last_version(int p_from_version) {
|
||||
|
||||
if (p_from_version <= 3) {
|
||||
// Converts the actions from array to dictionary (array of events to dictionary with deadzone + events)
|
||||
for (Map<StringName, ProjectSettings::VariantContainer>::Element *E = props.front(); E; E = E->next()) {
|
||||
Variant value = E->get().variant;
|
||||
|
@ -396,7 +394,6 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b
|
|||
// Optional, we don't mind if it fails
|
||||
_load_settings_text("res://override.cfg");
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -443,10 +440,6 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b
|
|||
if (resource_path.length() && resource_path[resource_path.length() - 1] == '/')
|
||||
resource_path = resource_path.substr(0, resource_path.length() - 1); // chop end
|
||||
|
||||
// If we're loading a project.godot from source code, we can operate some
|
||||
// ProjectSettings conversions if need be.
|
||||
_convert_to_last_version();
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -537,8 +530,8 @@ Error ProjectSettings::_load_settings_text(const String p_path) {
|
|||
|
||||
int lines = 0;
|
||||
String error_text;
|
||||
|
||||
String section;
|
||||
int config_version = 0;
|
||||
|
||||
while (true) {
|
||||
|
||||
|
@ -549,6 +542,9 @@ Error ProjectSettings::_load_settings_text(const String p_path) {
|
|||
err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, NULL, true);
|
||||
if (err == ERR_FILE_EOF) {
|
||||
memdelete(f);
|
||||
// If we're loading a project.godot from source code, we can operate some
|
||||
// ProjectSettings conversions if need be.
|
||||
_convert_to_last_version(config_version);
|
||||
return OK;
|
||||
} else if (err != OK) {
|
||||
ERR_PRINTS("Error parsing " + p_path + " at line " + itos(lines) + ": " + error_text + " File might be corrupted.");
|
||||
|
@ -558,13 +554,13 @@ Error ProjectSettings::_load_settings_text(const String p_path) {
|
|||
|
||||
if (assign != String()) {
|
||||
if (section == String() && assign == "config_version") {
|
||||
int config_version = value;
|
||||
if (config_version > FORMAT_VERSION) {
|
||||
config_version = value;
|
||||
if (config_version > CONFIG_VERSION) {
|
||||
memdelete(f);
|
||||
ERR_FAIL_COND_V(config_version > FORMAT_VERSION, ERR_FILE_CANT_OPEN);
|
||||
ERR_EXPLAIN(vformat("Can't open project at '%s', its `config_version` (%d) is from a more recent and incompatible version of the engine. Expected config version: %d.", p_path, config_version, CONFIG_VERSION));
|
||||
ERR_FAIL_COND_V(config_version > CONFIG_VERSION, ERR_FILE_CANT_OPEN);
|
||||
}
|
||||
} else {
|
||||
// config_version is checked and dropped
|
||||
if (section == String()) {
|
||||
set(assign, value);
|
||||
} else {
|
||||
|
@ -740,7 +736,7 @@ Error ProjectSettings::_save_settings_text(const String &p_file, const Map<Strin
|
|||
file->store_line("; param=value ; assign values to parameters");
|
||||
file->store_line("");
|
||||
|
||||
file->store_string("config_version=" + itos(FORMAT_VERSION) + "\n");
|
||||
file->store_string("config_version=" + itos(CONFIG_VERSION) + "\n");
|
||||
if (p_custom_features != String())
|
||||
file->store_string("custom_features=\"" + p_custom_features + "\"\n");
|
||||
file->store_string("\n");
|
||||
|
|
|
@ -106,7 +106,7 @@ protected:
|
|||
|
||||
Error _save_custom_bnd(const String &p_file);
|
||||
|
||||
void _convert_to_last_version();
|
||||
void _convert_to_last_version(int p_from_version);
|
||||
|
||||
bool _load_resource_pack(const String &p_pack);
|
||||
|
||||
|
@ -118,6 +118,8 @@ protected:
|
|||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
static const int CONFIG_VERSION = 4;
|
||||
|
||||
void set_setting(const String &p_setting, const Variant &p_value);
|
||||
Variant get_setting(const String &p_setting) const;
|
||||
|
||||
|
|
|
@ -447,13 +447,14 @@ private:
|
|||
ProjectSettings::CustomMap edited_settings;
|
||||
edited_settings["application/config/name"] = project_name->get_text();
|
||||
|
||||
if (current->save_custom(dir.plus_file("/project.godot"), edited_settings, Vector<String>(), true)) {
|
||||
if (current->save_custom(dir.plus_file("project.godot"), edited_settings, Vector<String>(), true) != OK) {
|
||||
set_message(TTR("Couldn't edit project.godot in project path."), MESSAGE_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
hide();
|
||||
emit_signal("project_renamed");
|
||||
emit_signal("projects_updated");
|
||||
|
||||
} else {
|
||||
|
||||
if (mode == MODE_IMPORT) {
|
||||
|
@ -474,12 +475,12 @@ private:
|
|||
initial_settings["application/config/icon"] = "res://icon.png";
|
||||
initial_settings["rendering/environment/default_environment"] = "res://default_env.tres";
|
||||
|
||||
if (ProjectSettings::get_singleton()->save_custom(dir.plus_file("/project.godot"), initial_settings, Vector<String>(), false)) {
|
||||
if (ProjectSettings::get_singleton()->save_custom(dir.plus_file("project.godot"), initial_settings, Vector<String>(), false) != OK) {
|
||||
set_message(TTR("Couldn't create project.godot in project path."), MESSAGE_ERROR);
|
||||
} else {
|
||||
ResourceSaver::save(dir.plus_file("/icon.png"), get_icon("DefaultProjectIcon", "EditorIcons"));
|
||||
ResourceSaver::save(dir.plus_file("icon.png"), get_icon("DefaultProjectIcon", "EditorIcons"));
|
||||
|
||||
FileAccess *f = FileAccess::open(dir.plus_file("/default_env.tres"), FileAccess::WRITE);
|
||||
FileAccess *f = FileAccess::open(dir.plus_file("default_env.tres"), FileAccess::WRITE);
|
||||
if (!f) {
|
||||
set_message(TTR("Couldn't create project.godot in project path."), MESSAGE_ERROR);
|
||||
} else {
|
||||
|
@ -587,7 +588,7 @@ private:
|
|||
dialog_error->popup_centered_minsize();
|
||||
|
||||
} else if (!project_path->get_text().ends_with(".zip")) {
|
||||
dialog_error->set_text(TTR("Package Installed Successfully!"));
|
||||
dialog_error->set_text(TTR("Package installed successfully!"));
|
||||
dialog_error->popup_centered_minsize();
|
||||
}
|
||||
}
|
||||
|
@ -651,7 +652,7 @@ protected:
|
|||
ClassDB::bind_method("_install_path_selected", &ProjectDialog::_install_path_selected);
|
||||
ClassDB::bind_method("_browse_install_path", &ProjectDialog::_browse_install_path);
|
||||
ADD_SIGNAL(MethodInfo("project_created"));
|
||||
ADD_SIGNAL(MethodInfo("project_renamed"));
|
||||
ADD_SIGNAL(MethodInfo("projects_updated"));
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -852,6 +853,7 @@ public:
|
|||
fdialog->connect("file_selected", this, "_file_selected");
|
||||
fdialog_install->connect("dir_selected", this, "_install_path_selected");
|
||||
fdialog_install->connect("file_selected", this, "_install_path_selected");
|
||||
|
||||
set_hide_on_ok(false);
|
||||
mode = MODE_NEW;
|
||||
|
||||
|
@ -864,15 +866,17 @@ struct ProjectItem {
|
|||
String project;
|
||||
String path;
|
||||
String conf;
|
||||
int config_version;
|
||||
uint64_t last_modified;
|
||||
bool favorite;
|
||||
bool grayed;
|
||||
bool ordered_latest_modification;
|
||||
ProjectItem() {}
|
||||
ProjectItem(const String &p_project, const String &p_path, const String &p_conf, uint64_t p_last_modified, bool p_favorite = false, bool p_grayed = false, const bool p_ordered_latest_modification = true) {
|
||||
ProjectItem(const String &p_project, const String &p_path, const String &p_conf, int p_config_version, uint64_t p_last_modified, bool p_favorite = false, bool p_grayed = false, const bool p_ordered_latest_modification = true) {
|
||||
project = p_project;
|
||||
path = p_path;
|
||||
conf = p_conf;
|
||||
config_version = p_config_version;
|
||||
last_modified = p_last_modified;
|
||||
favorite = p_favorite;
|
||||
grayed = p_grayed;
|
||||
|
@ -982,7 +986,7 @@ void ProjectManager::_panel_input(const Ref<InputEvent> &p_ev, Node *p_hb) {
|
|||
_update_project_buttons();
|
||||
|
||||
if (mb->is_doubleclick())
|
||||
_open_project(); //open if doubleclicked
|
||||
_open_selected_projects_ask(); //open if doubleclicked
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1004,7 +1008,7 @@ void ProjectManager::_unhandled_input(const Ref<InputEvent> &p_ev) {
|
|||
|
||||
case KEY_ENTER: {
|
||||
|
||||
_open_project();
|
||||
_open_selected_projects_ask();
|
||||
} break;
|
||||
case KEY_DELETE: {
|
||||
|
||||
|
@ -1187,6 +1191,7 @@ void ProjectManager::_load_recent_projects() {
|
|||
|
||||
String project = _name.get_slice("/", 1);
|
||||
String conf = path.plus_file("project.godot");
|
||||
int config_version = 0; // Assume 0 until we know better
|
||||
bool favorite = (_name.begins_with("favorite_projects/")) ? true : false;
|
||||
bool grayed = false;
|
||||
|
||||
|
@ -1204,7 +1209,7 @@ void ProjectManager::_load_recent_projects() {
|
|||
grayed = true;
|
||||
}
|
||||
|
||||
ProjectItem item(project, path, conf, last_modified, favorite, grayed, set_ordered_latest_modification);
|
||||
ProjectItem item(project, path, conf, config_version, last_modified, favorite, grayed, set_ordered_latest_modification);
|
||||
if (favorite)
|
||||
favorite_projects.push_back(item);
|
||||
else
|
||||
|
@ -1231,14 +1236,11 @@ void ProjectManager::_load_recent_projects() {
|
|||
String project = item.project;
|
||||
String path = item.path;
|
||||
String conf = item.conf;
|
||||
bool is_favorite = item.favorite;
|
||||
bool is_grayed = item.grayed;
|
||||
|
||||
Ref<ConfigFile> cf = memnew(ConfigFile);
|
||||
Error cf_err = cf->load(conf);
|
||||
|
||||
String project_name = TTR("Unnamed Project");
|
||||
|
||||
if (cf_err == OK && cf->has_section_key("application", "config/name")) {
|
||||
project_name = static_cast<String>(cf->get_value("application", "config/name")).xml_unescape();
|
||||
}
|
||||
|
@ -1247,8 +1249,16 @@ void ProjectManager::_load_recent_projects() {
|
|||
continue;
|
||||
|
||||
Ref<Texture> icon;
|
||||
if (cf_err == OK && cf->has_section_key("application", "config/icon")) {
|
||||
String appicon = cf->get_value("application", "config/icon");
|
||||
String main_scene;
|
||||
|
||||
if (cf_err == OK) {
|
||||
item.config_version = (int)cf->get_value("", "config_version", 0);
|
||||
if (item.config_version > ProjectSettings::CONFIG_VERSION) {
|
||||
// Comes from an incompatible (more recent) Godot version, grey it out
|
||||
item.grayed = true;
|
||||
}
|
||||
|
||||
String appicon = cf->get_value("application", "config/icon", "");
|
||||
if (appicon != "") {
|
||||
Ref<Image> img;
|
||||
img.instance();
|
||||
|
@ -1262,21 +1272,19 @@ void ProjectManager::_load_recent_projects() {
|
|||
icon = it;
|
||||
}
|
||||
}
|
||||
|
||||
main_scene = cf->get_value("application", "run/main_scene", "");
|
||||
}
|
||||
|
||||
if (icon.is_null()) {
|
||||
icon = get_icon("DefaultProjectIcon", "EditorIcons");
|
||||
}
|
||||
|
||||
String main_scene;
|
||||
if (cf_err == OK && cf->has_section_key("application", "run/main_scene")) {
|
||||
main_scene = cf->get_value("application", "run/main_scene");
|
||||
} else {
|
||||
main_scene = "";
|
||||
}
|
||||
|
||||
selected_list_copy.erase(project);
|
||||
|
||||
bool is_favorite = item.favorite;
|
||||
bool is_grayed = item.grayed;
|
||||
|
||||
HBoxContainer *hb = memnew(HBoxContainer);
|
||||
hb->set_meta("name", project);
|
||||
hb->set_meta("main_scene", main_scene);
|
||||
|
@ -1354,7 +1362,7 @@ void ProjectManager::_load_recent_projects() {
|
|||
tabs->set_current_tab(0);
|
||||
}
|
||||
|
||||
void ProjectManager::_on_project_renamed() {
|
||||
void ProjectManager::_on_projects_updated() {
|
||||
_load_recent_projects();
|
||||
}
|
||||
|
||||
|
@ -1374,7 +1382,7 @@ void ProjectManager::_on_project_created(const String &dir) {
|
|||
_load_recent_projects();
|
||||
_update_scroll_position(dir);
|
||||
}
|
||||
_open_project();
|
||||
_open_selected_projects_ask();
|
||||
}
|
||||
|
||||
void ProjectManager::_update_scroll_position(const String &dir) {
|
||||
|
@ -1396,14 +1404,18 @@ void ProjectManager::_update_scroll_position(const String &dir) {
|
|||
}
|
||||
}
|
||||
|
||||
void ProjectManager::_open_project_confirm() {
|
||||
void ProjectManager::_confirm_update_settings() {
|
||||
_open_selected_projects();
|
||||
}
|
||||
|
||||
for (Map<String, String>::Element *E = selected_list.front(); E; E = E->next()) {
|
||||
void ProjectManager::_open_selected_projects() {
|
||||
|
||||
for (const Map<String, String>::Element *E = selected_list.front(); E; E = E->next()) {
|
||||
const String &selected = E->key();
|
||||
String path = EditorSettings::get_singleton()->get("projects/" + selected);
|
||||
String conf = path + "/project.godot";
|
||||
String conf = path.plus_file("project.godot");
|
||||
if (!FileAccess::exists(conf)) {
|
||||
dialog_error->set_text(TTR("Can't open project"));
|
||||
dialog_error->set_text(vformat(TTR("Can't open project at '%s'."), path));
|
||||
dialog_error->popup_centered_minsize();
|
||||
return;
|
||||
}
|
||||
|
@ -1431,7 +1443,7 @@ void ProjectManager::_open_project_confirm() {
|
|||
get_tree()->quit();
|
||||
}
|
||||
|
||||
void ProjectManager::_open_project() {
|
||||
void ProjectManager::_open_selected_projects_ask() {
|
||||
|
||||
if (selected_list.size() < 1) {
|
||||
return;
|
||||
|
@ -1440,9 +1452,40 @@ void ProjectManager::_open_project() {
|
|||
if (selected_list.size() > 1) {
|
||||
multi_open_ask->set_text(TTR("Are you sure to open more than one project?"));
|
||||
multi_open_ask->popup_centered_minsize();
|
||||
} else {
|
||||
_open_project_confirm();
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the project settings or don't open
|
||||
String path = EditorSettings::get_singleton()->get("projects/" + selected_list.front()->key());
|
||||
String conf = path.plus_file("project.godot");
|
||||
|
||||
// FIXME: We already parse those in _load_recent_projects, we could instead make
|
||||
// its `projects` list global and reuse its parsed metadata here.
|
||||
Ref<ConfigFile> cf = memnew(ConfigFile);
|
||||
Error cf_err = cf->load(conf);
|
||||
|
||||
if (cf_err != OK) {
|
||||
dialog_error->set_text(vformat(TTR("Can't open project at '%s'."), path));
|
||||
dialog_error->popup_centered_minsize();
|
||||
return;
|
||||
}
|
||||
|
||||
int config_version = (int)cf->get_value("", "config_version", 0);
|
||||
// Check if we need to convert project settings from an earlier engine version
|
||||
if (config_version < ProjectSettings::CONFIG_VERSION) {
|
||||
ask_update_settings->set_text(vformat(TTR("The following project settings file was generated by an older engine version, and needs to be converted for this version:\n\n%s\n\nDo you want to convert it?\nWarning: You will not be able to open the project with previous versions of the engine anymore."), conf));
|
||||
ask_update_settings->popup_centered_minsize();
|
||||
return;
|
||||
}
|
||||
// Check if the file was generated by a newer, incompatible engine version
|
||||
if (config_version > ProjectSettings::CONFIG_VERSION) {
|
||||
dialog_error->set_text(vformat(TTR("Can't open project at '%s'.") + "\n" + TTR("The project settings were created by a newer engine version, whose settings are not compatible with this version."), path));
|
||||
dialog_error->popup_centered_minsize();
|
||||
return;
|
||||
}
|
||||
|
||||
// Open if the project is up-to-date
|
||||
_open_selected_projects();
|
||||
}
|
||||
|
||||
void ProjectManager::_run_project_confirm() {
|
||||
|
@ -1687,8 +1730,8 @@ void ProjectManager::_scan_multiple_folders(PoolStringArray p_files) {
|
|||
|
||||
void ProjectManager::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method("_open_project", &ProjectManager::_open_project);
|
||||
ClassDB::bind_method("_open_project_confirm", &ProjectManager::_open_project_confirm);
|
||||
ClassDB::bind_method("_open_selected_projects_ask", &ProjectManager::_open_selected_projects_ask);
|
||||
ClassDB::bind_method("_open_selected_projects", &ProjectManager::_open_selected_projects);
|
||||
ClassDB::bind_method("_run_project", &ProjectManager::_run_project);
|
||||
ClassDB::bind_method("_run_project_confirm", &ProjectManager::_run_project_confirm);
|
||||
ClassDB::bind_method("_show_project", &ProjectManager::_show_project);
|
||||
|
@ -1703,7 +1746,7 @@ void ProjectManager::_bind_methods() {
|
|||
ClassDB::bind_method("_restart_confirm", &ProjectManager::_restart_confirm);
|
||||
ClassDB::bind_method("_exit_dialog", &ProjectManager::_exit_dialog);
|
||||
ClassDB::bind_method("_load_recent_projects", &ProjectManager::_load_recent_projects);
|
||||
ClassDB::bind_method("_on_project_renamed", &ProjectManager::_on_project_renamed);
|
||||
ClassDB::bind_method("_on_projects_updated", &ProjectManager::_on_projects_updated);
|
||||
ClassDB::bind_method("_on_project_created", &ProjectManager::_on_project_created);
|
||||
ClassDB::bind_method("_update_scroll_position", &ProjectManager::_update_scroll_position);
|
||||
ClassDB::bind_method("_panel_draw", &ProjectManager::_panel_draw);
|
||||
|
@ -1713,6 +1756,7 @@ void ProjectManager::_bind_methods() {
|
|||
ClassDB::bind_method("_install_project", &ProjectManager::_install_project);
|
||||
ClassDB::bind_method("_files_dropped", &ProjectManager::_files_dropped);
|
||||
ClassDB::bind_method("_open_asset_library", &ProjectManager::_open_asset_library);
|
||||
ClassDB::bind_method("_confirm_update_settings", &ProjectManager::_confirm_update_settings);
|
||||
ClassDB::bind_method(D_METHOD("_scan_multiple_folders", "files"), &ProjectManager::_scan_multiple_folders);
|
||||
}
|
||||
|
||||
|
@ -1890,7 +1934,7 @@ ProjectManager::ProjectManager() {
|
|||
Button *open = memnew(Button);
|
||||
open->set_text(TTR("Edit"));
|
||||
tree_vb->add_child(open);
|
||||
open->connect("pressed", this, "_open_project");
|
||||
open->connect("pressed", this, "_open_selected_projects_ask");
|
||||
open_btn = open;
|
||||
|
||||
Button *run = memnew(Button);
|
||||
|
@ -1997,38 +2041,37 @@ ProjectManager::ProjectManager() {
|
|||
language_restart_ask->get_ok()->set_text(TTR("Restart Now"));
|
||||
language_restart_ask->get_ok()->connect("pressed", this, "_restart_confirm");
|
||||
language_restart_ask->get_cancel()->set_text(TTR("Continue"));
|
||||
|
||||
gui_base->add_child(language_restart_ask);
|
||||
|
||||
erase_ask = memnew(ConfirmationDialog);
|
||||
erase_ask->get_ok()->set_text(TTR("Remove"));
|
||||
erase_ask->get_ok()->connect("pressed", this, "_erase_project_confirm");
|
||||
|
||||
gui_base->add_child(erase_ask);
|
||||
|
||||
multi_open_ask = memnew(ConfirmationDialog);
|
||||
multi_open_ask->get_ok()->set_text(TTR("Edit"));
|
||||
multi_open_ask->get_ok()->connect("pressed", this, "_open_project_confirm");
|
||||
|
||||
multi_open_ask->get_ok()->connect("pressed", this, "_open_selected_projects");
|
||||
gui_base->add_child(multi_open_ask);
|
||||
|
||||
multi_run_ask = memnew(ConfirmationDialog);
|
||||
multi_run_ask->get_ok()->set_text(TTR("Run"));
|
||||
multi_run_ask->get_ok()->connect("pressed", this, "_run_project_confirm");
|
||||
|
||||
gui_base->add_child(multi_run_ask);
|
||||
|
||||
multi_scan_ask = memnew(ConfirmationDialog);
|
||||
multi_scan_ask->get_ok()->set_text(TTR("Scan"));
|
||||
|
||||
gui_base->add_child(multi_scan_ask);
|
||||
|
||||
ask_update_settings = memnew(ConfirmationDialog);
|
||||
ask_update_settings->get_ok()->connect("pressed", this, "_confirm_update_settings");
|
||||
gui_base->add_child(ask_update_settings);
|
||||
|
||||
OS::get_singleton()->set_low_processor_usage_mode(true);
|
||||
|
||||
npdialog = memnew(ProjectDialog);
|
||||
gui_base->add_child(npdialog);
|
||||
|
||||
npdialog->connect("project_renamed", this, "_on_project_renamed");
|
||||
npdialog->connect("projects_updated", this, "_on_projects_updated");
|
||||
npdialog->connect("project_created", this, "_on_project_created");
|
||||
_load_recent_projects();
|
||||
|
||||
|
|
|
@ -49,43 +49,41 @@ class ProjectManager : public Control {
|
|||
Button *rename_btn;
|
||||
Button *run_btn;
|
||||
|
||||
FileDialog *scan_dir;
|
||||
|
||||
EditorAssetLibrary *asset_library;
|
||||
|
||||
ProjectListFilter *project_filter;
|
||||
ProjectListFilter *project_order_filter;
|
||||
|
||||
FileDialog *scan_dir;
|
||||
ConfirmationDialog *language_restart_ask;
|
||||
ConfirmationDialog *erase_ask;
|
||||
ConfirmationDialog *multi_open_ask;
|
||||
ConfirmationDialog *multi_run_ask;
|
||||
ConfirmationDialog *multi_scan_ask;
|
||||
ConfirmationDialog *ask_update_settings;
|
||||
ConfirmationDialog *open_templates;
|
||||
AcceptDialog *run_error_diag;
|
||||
AcceptDialog *dialog_error;
|
||||
ProjectDialog *npdialog;
|
||||
|
||||
ScrollContainer *scroll;
|
||||
VBoxContainer *scroll_children;
|
||||
Map<String, String> selected_list; // name -> main_scene
|
||||
String last_clicked;
|
||||
bool importing;
|
||||
|
||||
HBoxContainer *projects_hb;
|
||||
|
||||
TabContainer *tabs;
|
||||
|
||||
OptionButton *language_btn;
|
||||
|
||||
Control *gui_base;
|
||||
|
||||
ConfirmationDialog *open_templates;
|
||||
Map<String, String> selected_list; // name -> main_scene
|
||||
String last_clicked;
|
||||
bool importing;
|
||||
|
||||
void _open_asset_library();
|
||||
void _scan_projects();
|
||||
void _run_project();
|
||||
void _run_project_confirm();
|
||||
void _open_project();
|
||||
void _open_project_confirm();
|
||||
void _open_selected_projects();
|
||||
void _open_selected_projects_ask();
|
||||
void _show_project(const String &p_path);
|
||||
void _import_project();
|
||||
void _new_project();
|
||||
|
@ -98,9 +96,11 @@ class ProjectManager : public Control {
|
|||
void _exit_dialog();
|
||||
void _scan_begin(const String &p_base);
|
||||
|
||||
void _confirm_update_settings();
|
||||
|
||||
void _load_recent_projects();
|
||||
void _on_project_created(const String &dir);
|
||||
void _on_project_renamed();
|
||||
void _on_projects_updated();
|
||||
void _update_scroll_position(const String &dir);
|
||||
void _scan_dir(DirAccess *da, float pos, float total, List<String> *r_projects);
|
||||
|
||||
|
|
Loading…
Reference in a new issue