diff options
Diffstat (limited to 'editor')
-rw-r--r-- | editor/editor_node.cpp | 111 | ||||
-rw-r--r-- | editor/editor_node.h | 21 | ||||
-rw-r--r-- | editor/export_template_manager.cpp | 113 | ||||
-rw-r--r-- | editor/export_template_manager.h | 3 |
4 files changed, 244 insertions, 4 deletions
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index f7a952d5cc..477a6b7f73 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -47,6 +47,7 @@ #include "core/translation.h" #include "core/version.h" #include "main/input_default.h" +#include "main/main.h" #include "scene/resources/packed_scene.h" #include "servers/physics_2d_server.h" @@ -2270,6 +2271,23 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { OS::get_singleton()->shell_open(String("file://") + OS::get_singleton()->get_user_data_dir()); } break; + case FILE_INSTALL_ANDROID_SOURCE: { + + if (p_confirmed) { + export_template_manager->install_android_template(); + } else { + if (DirAccess::exists("res://android/build")) { + remove_android_build_template->popup_centered_minsize(); + } else if (export_template_manager->can_install_android_template()) { + install_android_build_template->popup_centered_minsize(); + } else { + custom_build_manage_templates->popup_centered_minsize(); + } + } + } break; + case FILE_EXPLORE_ANDROID_BUILD_TEMPLATES: { + OS::get_singleton()->shell_open(String("file://") + ProjectSettings::get_singleton()->get_resource_path().plus_file("android")); + } break; case FILE_QUIT: case RUN_PROJECT_MANAGER: { @@ -5044,6 +5062,68 @@ void EditorNode::_print_handler(void *p_this, const String &p_string, bool p_err en->log->add_message(p_string, p_error ? EditorLog::MSG_TYPE_ERROR : EditorLog::MSG_TYPE_STD); } +static void _execute_thread(void *p_ud) { + + EditorNode::ExecuteThreadArgs *eta = (EditorNode::ExecuteThreadArgs *)p_ud; + Error err = OS::get_singleton()->execute(eta->path, eta->args, true, NULL, &eta->output, &eta->exitcode, true, eta->execute_output_mutex); + print_verbose("Thread exit status: " + itos(eta->exitcode)); + if (err != OK) { + eta->exitcode = err; + } + + eta->done = true; +} + +int EditorNode::execute_and_show_output(const String &p_title, const String &p_path, const List<String> &p_arguments, bool p_close_on_ok, bool p_close_on_errors) { + + execute_output_dialog->set_title(p_title); + execute_output_dialog->get_ok()->set_disabled(true); + execute_outputs->clear(); + execute_outputs->set_scroll_follow(true); + execute_output_dialog->popup_centered_ratio(); + + ExecuteThreadArgs eta; + eta.path = p_path; + eta.args = p_arguments; + eta.execute_output_mutex = Mutex::create(); + eta.exitcode = 255; + eta.done = false; + + int prev_len = 0; + + eta.execute_output_thread = Thread::create(_execute_thread, &eta); + + ERR_FAIL_COND_V(!eta.execute_output_thread, 0); + + while (!eta.done) { + eta.execute_output_mutex->lock(); + if (prev_len != eta.output.length()) { + String to_add = eta.output.substr(prev_len, eta.output.length()); + prev_len = eta.output.length(); + execute_outputs->add_text(to_add); + Main::iteration(); + } + eta.execute_output_mutex->unlock(); + OS::get_singleton()->delay_usec(1000); + } + + Thread::wait_to_finish(eta.execute_output_thread); + memdelete(eta.execute_output_thread); + memdelete(eta.execute_output_mutex); + execute_outputs->add_text("\nExit Code: " + itos(eta.exitcode)); + + if (p_close_on_errors && eta.exitcode != 0) { + execute_output_dialog->hide(); + } + if (p_close_on_ok && eta.exitcode == 0) { + execute_output_dialog->hide(); + } + + execute_output_dialog->get_ok()->set_disabled(false); + + return eta.exitcode; +} + EditorNode::EditorNode() { Input::get_singleton()->set_use_accumulated_input(true); @@ -5618,12 +5698,13 @@ EditorNode::EditorNode() { tool_menu = memnew(PopupMenu); tool_menu->set_name("Tools"); tool_menu->connect("index_pressed", this, "_tool_menu_option"); + p->add_separator(); p->add_child(tool_menu); p->add_submenu_item(TTR("Tools"), "Tools"); - tool_menu->add_shortcut(ED_SHORTCUT("editor/orphan_resource_explorer", TTR("Orphan Resource Explorer")), TOOLS_ORPHAN_RESOURCES); + tool_menu->add_item(TTR("Orphan Resource Explorer"), TOOLS_ORPHAN_RESOURCES); + tool_menu->add_item(TTR("Open Project Data Folder"), RUN_PROJECT_DATA_FOLDER); p->add_separator(); - - p->add_shortcut(ED_SHORTCUT("editor/open_project_data_folder", TTR("Open Project Data Folder")), RUN_PROJECT_DATA_FOLDER); + p->add_item(TTR("Install Android Build Template"), FILE_INSTALL_ANDROID_SOURCE); p->add_separator(); #ifdef OSX_ENABLED @@ -5970,6 +6051,24 @@ EditorNode::EditorNode() { save_confirmation->connect("confirmed", this, "_menu_confirm_current"); save_confirmation->connect("custom_action", this, "_discard_changes"); + custom_build_manage_templates = memnew(ConfirmationDialog); + custom_build_manage_templates->set_text(TTR("Android build template is missing, please install relevant templates.")); + custom_build_manage_templates->get_ok()->set_text(TTR("Manage Templates")); + custom_build_manage_templates->connect("confirmed", this, "_menu_option", varray(SETTINGS_MANAGE_EXPORT_TEMPLATES)); + gui_base->add_child(custom_build_manage_templates); + + install_android_build_template = memnew(ConfirmationDialog); + install_android_build_template->set_text(TTR("This will install the Android project for custom builds.\nNote that, in order to use it, it needs to be enabled per export preset.")); + install_android_build_template->get_ok()->set_text(TTR("Install")); + install_android_build_template->connect("confirmed", this, "_menu_confirm_current"); + gui_base->add_child(install_android_build_template); + + remove_android_build_template = memnew(ConfirmationDialog); + remove_android_build_template->set_text(TTR("Android build template is already installed and it won't be overwritten.\nRemove the \"build\" directory manually before attempting this operation again.")); + remove_android_build_template->get_ok()->set_text(TTR("Show in File Manager")); + remove_android_build_template->connect("confirmed", this, "_menu_option", varray(FILE_EXPLORE_ANDROID_BUILD_TEMPLATES)); + gui_base->add_child(remove_android_build_template); + file_templates = memnew(EditorFileDialog); file_templates->set_title(TTR("Import Templates From ZIP File")); @@ -6184,6 +6283,12 @@ EditorNode::EditorNode() { load_error_dialog->set_title(TTR("Load Errors")); gui_base->add_child(load_error_dialog); + execute_outputs = memnew(RichTextLabel); + execute_output_dialog = memnew(AcceptDialog); + execute_output_dialog->add_child(execute_outputs); + execute_output_dialog->set_title(TTR("")); + gui_base->add_child(execute_output_dialog); + EditorFileSystem::get_singleton()->connect("sources_changed", this, "_sources_changed"); EditorFileSystem::get_singleton()->connect("filesystem_changed", this, "_fs_changed"); EditorFileSystem::get_singleton()->connect("resources_reimported", this, "_resources_reimported"); diff --git a/editor/editor_node.h b/editor/editor_node.h index 328986fc69..a06708eb54 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -112,6 +112,16 @@ public: DOCK_SLOT_MAX }; + struct ExecuteThreadArgs { + String path; + List<String> args; + String output; + Thread *execute_output_thread; + Mutex *execute_output_mutex; + int exitcode; + volatile bool done; + }; + private: enum { HISTORY_SIZE = 64 @@ -130,6 +140,8 @@ private: FILE_IMPORT_SUBSCENE, FILE_EXPORT_PROJECT, FILE_EXPORT_MESH_LIBRARY, + FILE_INSTALL_ANDROID_SOURCE, + FILE_EXPLORE_ANDROID_BUILD_TEMPLATES, FILE_EXPORT_TILESET, FILE_SAVE_OPTIMIZED, FILE_OPEN_RECENT, @@ -267,6 +279,9 @@ private: RichTextLabel *load_errors; AcceptDialog *load_error_dialog; + RichTextLabel *execute_outputs; + AcceptDialog *execute_output_dialog; + Ref<Theme> theme; PopupMenu *recent_scenes; @@ -290,6 +305,10 @@ private: PopupMenu *editor_layouts; EditorNameDialog *layout_dialog; + ConfirmationDialog *custom_build_manage_templates; + ConfirmationDialog *install_android_build_template; + ConfirmationDialog *remove_android_build_template; + EditorSettingsDialog *settings_config_dialog; RunSettingsDialog *run_settings_dialog; ProjectSettingsEditor *project_settings; @@ -800,6 +819,8 @@ public: void update_keying() const { inspector_dock->update_keying(); }; bool has_scenes_in_session(); + int execute_and_show_output(const String &p_title, const String &p_path, const List<String> &p_arguments, bool p_close_on_ok = true, bool p_close_on_errors = false); + EditorNode(); ~EditorNode(); void get_singleton(const char *arg1, bool arg2); diff --git a/editor/export_template_manager.cpp b/editor/export_template_manager.cpp index 97ccfb0db1..aa2a03510d 100644 --- a/editor/export_template_manager.cpp +++ b/editor/export_template_manager.cpp @@ -308,7 +308,8 @@ bool ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_ p->step(TTR("Importing:") + " " + file, fc); } - FileAccess *f = FileAccess::open(template_path.plus_file(file), FileAccess::WRITE); + String to_write = template_path.plus_file(file); + FileAccess *f = FileAccess::open(to_write, FileAccess::WRITE); if (!f) { ret = unzGoToNextFile(pkg); @@ -320,6 +321,10 @@ bool ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_ memdelete(f); +#ifndef WINDOWS_ENABLED + FileAccess::set_unix_permissions(to_write, (info.external_fa >> 16) & 0x01FF); +#endif + ret = unzGoToNextFile(pkg); fc++; } @@ -541,6 +546,112 @@ void ExportTemplateManager::_notification(int p_what) { } } +bool ExportTemplateManager::can_install_android_template() { + + return FileAccess::exists(EditorSettings::get_singleton()->get_templates_dir().plus_file(VERSION_FULL_CONFIG).plus_file("android_source.zip")); +} + +Error ExportTemplateManager::install_android_template() { + + DirAccessRef da = DirAccess::open("res://"); + ERR_FAIL_COND_V(!da, ERR_CANT_CREATE); + //make android dir (if it does not exist) + + da->make_dir("android"); + { + //add an empty .gdignore file to avoid scan + FileAccessRef f = FileAccess::open("res://android/.gdignore", FileAccess::WRITE); + ERR_FAIL_COND_V(!f, ERR_CANT_CREATE); + f->store_line(""); + f->close(); + } + { + //add version, to ensure building wont work if template and Godot version are mismatch + FileAccessRef f = FileAccess::open("res://android/.build_version", FileAccess::WRITE); + ERR_FAIL_COND_V(!f, ERR_CANT_CREATE); + f->store_line(VERSION_FULL_CONFIG); + f->close(); + } + + Error err = da->make_dir_recursive("android/build"); + ERR_FAIL_COND_V(err != OK, err); + + String source_zip = EditorSettings::get_singleton()->get_templates_dir().plus_file(VERSION_FULL_CONFIG).plus_file("android_source.zip"); + ERR_FAIL_COND_V(!FileAccess::exists(source_zip), ERR_CANT_OPEN); + + FileAccess *src_f = NULL; + zlib_filefunc_def io = zipio_create_io_from_file(&src_f); + + unzFile pkg = unzOpen2(source_zip.utf8().get_data(), &io); + ERR_EXPLAIN("Android sources not in zip format"); + ERR_FAIL_COND_V(!pkg, ERR_CANT_OPEN); + + int ret = unzGoToFirstFile(pkg); + + int total_files = 0; + //count files + while (ret == UNZ_OK) { + total_files++; + ret = unzGoToNextFile(pkg); + } + + ret = unzGoToFirstFile(pkg); + //decompress files + ProgressDialog::get_singleton()->add_task("uncompress", TTR("Uncompressing Android Build Sources"), total_files); + + Set<String> dirs_tested; + + int idx = 0; + while (ret == UNZ_OK) { + + //get filename + unz_file_info info; + char fname[16384]; + ret = unzGetCurrentFileInfo(pkg, &info, fname, 16384, NULL, 0, NULL, 0); + + String name = fname; + + String base_dir = name.get_base_dir(); + + if (!name.ends_with("/")) { + Vector<uint8_t> data; + data.resize(info.uncompressed_size); + + //read + unzOpenCurrentFile(pkg); + unzReadCurrentFile(pkg, data.ptrw(), data.size()); + unzCloseCurrentFile(pkg); + + if (!dirs_tested.has(base_dir)) { + da->make_dir_recursive(String("android/build").plus_file(base_dir)); + dirs_tested.insert(base_dir); + } + + String to_write = String("res://android/build").plus_file(name); + FileAccess *f = FileAccess::open(to_write, FileAccess::WRITE); + if (f) { + f->store_buffer(data.ptr(), data.size()); + memdelete(f); +#ifndef WINDOWS_ENABLED + FileAccess::set_unix_permissions(to_write, (info.external_fa >> 16) & 0x01FF); +#endif + } else { + ERR_PRINTS("Cant uncompress file: " + to_write); + } + } + + ProgressDialog::get_singleton()->task_step("uncompress", name, idx); + + idx++; + ret = unzGoToNextFile(pkg); + } + + ProgressDialog::get_singleton()->end_task("uncompress"); + unzClose(pkg); + + return OK; +} + void ExportTemplateManager::_bind_methods() { ClassDB::bind_method("_download_template", &ExportTemplateManager::_download_template); diff --git a/editor/export_template_manager.h b/editor/export_template_manager.h index 2edd3db6d7..608830c990 100644 --- a/editor/export_template_manager.h +++ b/editor/export_template_manager.h @@ -84,6 +84,9 @@ protected: static void _bind_methods(); public: + bool can_install_android_template(); + Error install_android_template(); + void popup_manager(); ExportTemplateManager(); |