diff options
Diffstat (limited to 'editor/project_manager.cpp')
-rw-r--r-- | editor/project_manager.cpp | 98 |
1 files changed, 88 insertions, 10 deletions
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 095ec891cd..709c2caa96 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -765,7 +765,7 @@ public: set_title(TTR("Install Project:") + " " + zip_title); get_ok()->set_text(TTR("Install & Edit")); - name_container->hide(); + name_container->show(); install_path_container->hide(); rasterizer_container->hide(); project_path->grab_focus(); @@ -798,7 +798,7 @@ public: create_dir = memnew(Button); pnhb->add_child(create_dir); - create_dir->set_text(TTR("Create folder")); + create_dir->set_text(TTR("Create Folder")); create_dir->connect("pressed", this, "_create_folder"); path_container = memnew(VBoxContainer); @@ -987,6 +987,24 @@ void ProjectManager::_update_project_buttons() { open_btn->set_disabled(empty_selection); rename_btn->set_disabled(empty_selection); run_btn->set_disabled(empty_selection); + + bool missing_projects = false; + Map<String, String> list_all_projects; + for (int i = 0; i < scroll_children->get_child_count(); i++) { + HBoxContainer *hb = Object::cast_to<HBoxContainer>(scroll_children->get_child(i)); + if (hb) { + list_all_projects.insert(hb->get_meta("name"), hb->get_meta("main_scene")); + } + } + for (Map<String, String>::Element *E = list_all_projects.front(); E; E = E->next()) { + String project_name = E->key().replace("::", "/") + "/project.godot"; + if (!FileAccess::exists(project_name)) { + missing_projects = true; + break; + } + } + + erase_missing_btn->set_visible(missing_projects); } void ProjectManager::_panel_input(const Ref<InputEvent> &p_ev, Node *p_hb) { @@ -1530,13 +1548,13 @@ void ProjectManager::_open_selected_projects_ask() { // Check if the config_version property was empty or 0 if (config_version == 0) { - ask_update_settings->set_text(vformat(TTR("The following project settings file does not specify the version of Godot through which it was created.\n\n%s\n\nIf you proceed with opening it, it will be converted to Godot's current configuration file format.\nWarning: You will not be able to open the project with previous versions of the engine anymore."), conf)); + ask_update_settings->set_text(vformat(TTR("The following project settings file does not specify the version of Godot through which it was created.\n\n%s\n\nIf you proceed with opening it, it will be converted to Godot's current configuration file format.\nWarning: You won't be able to open the project with previous versions of the engine anymore."), conf)); ask_update_settings->popup_centered_minsize(); return; } // 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->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 won't be able to open the project with previous versions of the engine anymore."), conf)); ask_update_settings->popup_centered_minsize(); return; } @@ -1557,7 +1575,7 @@ void ProjectManager::_run_project_confirm() { const String &selected_main = E->get(); if (selected_main == "") { - run_error_diag->set_text(TTR("Can't run project: no main scene defined.\nPlease edit the project and set the main scene in \"Project Settings\" under the \"Application\" category.")); + run_error_diag->set_text(TTR("Can't run project: no main scene defined.\nPlease edit the project and set the main scene in the Project Settings under the \"Application\" category.")); run_error_diag->popup_centered(); return; } @@ -1597,7 +1615,7 @@ void ProjectManager::_run_project() { } if (selected_list.size() > 1) { - multi_run_ask->set_text(TTR("Are you sure to run more than one project?")); + multi_run_ask->set_text(vformat(TTR("Are you sure to run %d projects at once?"), selected_list.size())); multi_run_ask->popup_centered_minsize(); } else { _run_project_confirm(); @@ -1700,15 +1718,61 @@ void ProjectManager::_erase_project_confirm() { _load_recent_projects(); } +void ProjectManager::_erase_missing_projects_confirm() { + + Map<String, String> list_all_projects; + for (int i = 0; i < scroll_children->get_child_count(); i++) { + HBoxContainer *hb = Object::cast_to<HBoxContainer>(scroll_children->get_child(i)); + if (hb) { + list_all_projects.insert(hb->get_meta("name"), hb->get_meta("main_scene")); + } + } + + if (list_all_projects.size() == 0) { + return; + } + + int deleted_projects = 0; + int remaining_projects = 0; + for (Map<String, String>::Element *E = list_all_projects.front(); E; E = E->next()) { + String project_name = E->key().replace("::", "/") + "/project.godot"; + if (!FileAccess::exists(project_name)) { + deleted_projects++; + EditorSettings::get_singleton()->erase("projects/" + E->key()); + EditorSettings::get_singleton()->erase("favorite_projects/" + E->key()); + } else { + remaining_projects++; + } + } + print_line("Deleted " + itos(deleted_projects) + " projects, remaining " + itos(remaining_projects) + " projects"); + EditorSettings::get_singleton()->save(); + selected_list.clear(); + last_clicked = ""; + _load_recent_projects(); +} + void ProjectManager::_erase_project() { if (selected_list.size() == 0) return; - erase_ask->set_text(TTR("Remove project from the list? (Folder contents will not be modified)")); + String confirm_message; + if (selected_list.size() >= 2) { + confirm_message = vformat(TTR("Remove %d projects from the list?\nThe project folders' contents won't be modified."), selected_list.size()); + } else { + confirm_message = TTR("Remove this project from the list?\nThe project folder's contents won't be modified."); + } + + erase_ask->set_text(confirm_message); erase_ask->popup_centered_minsize(); } +void ProjectManager::_erase_missing_projects() { + + erase_missing_ask->set_text(TTR("Remove all missing projects from the list? (Folders contents will not be modified)")); + erase_missing_ask->popup_centered_minsize(); +} + void ProjectManager::_language_selected(int p_id) { String lang = language_btn->get_item_metadata(p_id); @@ -1716,7 +1780,7 @@ void ProjectManager::_language_selected(int p_id) { language_btn->set_text(lang); language_btn->set_icon(get_icon("Environment", "EditorIcons")); - language_restart_ask->set_text(TTR("Language changed.\nThe UI will update next time the editor or project manager starts.")); + language_restart_ask->set_text(TTR("Language changed.\nThe interface will update after restarting the editor or project manager.")); language_restart_ask->popup_centered(); } @@ -1777,7 +1841,8 @@ void ProjectManager::_files_dropped(PoolStringArray p_files, int p_screen) { if (confirm) { multi_scan_ask->get_ok()->disconnect("pressed", this, "_scan_multiple_folders"); multi_scan_ask->get_ok()->connect("pressed", this, "_scan_multiple_folders", varray(folders)); - multi_scan_ask->set_text(vformat(TTR("You are about the scan %s folders for existing Godot projects. Do you confirm?"), folders.size())); + multi_scan_ask->set_text( + vformat(TTR("Are you sure to scan %s folders for existing Godot projects?\nThis could take a while."), folders.size())); multi_scan_ask->popup_centered_minsize(); } else { _scan_multiple_folders(folders); @@ -1804,7 +1869,9 @@ void ProjectManager::_bind_methods() { ClassDB::bind_method("_new_project", &ProjectManager::_new_project); ClassDB::bind_method("_rename_project", &ProjectManager::_rename_project); ClassDB::bind_method("_erase_project", &ProjectManager::_erase_project); + ClassDB::bind_method("_erase_missing_projects", &ProjectManager::_erase_missing_projects); ClassDB::bind_method("_erase_project_confirm", &ProjectManager::_erase_project_confirm); + ClassDB::bind_method("_erase_missing_projects_confirm", &ProjectManager::_erase_missing_projects_confirm); ClassDB::bind_method("_language_selected", &ProjectManager::_language_selected); ClassDB::bind_method("_restart_confirm", &ProjectManager::_restart_confirm); ClassDB::bind_method("_exit_dialog", &ProjectManager::_exit_dialog); @@ -2042,6 +2109,12 @@ ProjectManager::ProjectManager() { erase->connect("pressed", this, "_erase_project"); erase_btn = erase; + Button *erase_missing = memnew(Button); + erase_missing->set_text(TTR("Remove Missing")); + tree_vb->add_child(erase_missing); + erase_missing->connect("pressed", this, "_erase_missing_projects"); + erase_missing_btn = erase_missing; + tree_vb->add_spacer(); if (StreamPeerSSL::is_available()) { @@ -2105,6 +2178,11 @@ ProjectManager::ProjectManager() { language_restart_ask->get_cancel()->set_text(TTR("Continue")); gui_base->add_child(language_restart_ask); + erase_missing_ask = memnew(ConfirmationDialog); + erase_missing_ask->get_ok()->set_text(TTR("Remove All")); + erase_missing_ask->get_ok()->connect("pressed", this, "_erase_missing_projects_confirm"); + gui_base->add_child(erase_missing_ask); + erase_ask = memnew(ConfirmationDialog); erase_ask->get_ok()->set_text(TTR("Remove")); erase_ask->get_ok()->connect("pressed", this, "_erase_project_confirm"); @@ -2153,7 +2231,7 @@ ProjectManager::ProjectManager() { gui_base->add_child(dialog_error); open_templates = memnew(ConfirmationDialog); - open_templates->set_text(TTR("You don't currently have any projects.\nWould you like to explore the official example projects in the Asset Library?")); + open_templates->set_text(TTR("You currently don't have any projects.\nWould you like to explore official example projects in the Asset Library?")); open_templates->get_ok()->set_text(TTR("Open Asset Library")); open_templates->connect("confirmed", this, "_open_asset_library"); add_child(open_templates); |