From 29bcb134ea7cfd7d8fcdc26a465b4337b1437bb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B1=9F=E6=AF=85?= Date: Tue, 11 Nov 2025 15:43:19 +0800 Subject: [PATCH] feat: Add functionality to manually install formatter plugins via zip files in the menu --- .../install_and_update.gd | 48 +++++++++++++++++++ addons/GDQuest_GDScript_formatter/menu.gd | 6 +++ addons/GDQuest_GDScript_formatter/plugin.gd | 23 +++++++++ 3 files changed, 77 insertions(+) diff --git a/addons/GDQuest_GDScript_formatter/install_and_update.gd b/addons/GDQuest_GDScript_formatter/install_and_update.gd index 7f95d0f..4248e8a 100644 --- a/addons/GDQuest_GDScript_formatter/install_and_update.gd +++ b/addons/GDQuest_GDScript_formatter/install_and_update.gd @@ -12,6 +12,9 @@ const URL_GITHUB_API_LATEST_RELEASE = "https://api.github.com/repos/gdquest/GDSc signal installation_completed(binary_path: String) signal installation_failed(error_message: String) +signal show_file_select_dialog +signal zip_file_selected(path: String) + var http_request_state := HttpRequestState.IDLE var http_request: HTTPRequest = HTTPRequest.new() var formatter_cache_dir: String @@ -24,6 +27,7 @@ func _init(cache_dir: String) -> void: func _ready() -> void: add_child(http_request) http_request.request_completed.connect(_on_request_completed) + zip_file_selected.connect(_process_selected_zip_file) func install_or_update_formatter() -> void: @@ -32,6 +36,50 @@ func install_or_update_formatter() -> void: http_request.request(URL_GITHUB_API_LATEST_RELEASE) +func manual_install_formatter() -> void: + print("Starting GDScript formatter installation...") + show_file_select_dialog.emit() + pass + + +func _process_selected_zip_file(path: String) -> void: + if not path: + push_error("Path is invalid") + return + + var file := FileAccess.open(path, FileAccess.READ) + if not file: + push_error("Can not open the file(%s)" % path) + return + + var body: PackedByteArray = file.get_buffer(file.get_length()) + + var asset_info := _get_platform_info() + if asset_info.is_empty(): + var error_message := "Failed to determine platform information" + push_error(error_message) + installation_failed.emit(error_message) + return + + print("Extracting and installing binary...") + var binary_path := _download_and_install_binary(body, asset_info) + if binary_path.is_empty(): + var error_message := "Installation failed" + push_error(error_message) + installation_failed.emit(error_message) + return + + print( + "\n".join( + [ + "GDScript formatter installed successfully!", + "Binary location: " + binary_path, + ], + ), + ) + installation_completed.emit(binary_path) + + func _on_request_completed( _http_result: int, response_code: int, diff --git a/addons/GDQuest_GDScript_formatter/menu.gd b/addons/GDQuest_GDScript_formatter/menu.gd index a6cb716..0d7292f 100644 --- a/addons/GDQuest_GDScript_formatter/menu.gd +++ b/addons/GDQuest_GDScript_formatter/menu.gd @@ -11,6 +11,7 @@ const MENU_ITEMS = { "lint_script": "Lint Current Script", "reorder_code": "Reorder Code", "install_update": "Install or Update Formatter", + "manual_install": "Install Formatter Manually", "uninstall": "Uninstall Formatter", "report_issue": "Report Issue", "help": "Help", @@ -119,6 +120,11 @@ func _populate_menu(show_uninstall: bool = true) -> void: popup_menu.set_item_tooltip(current_item_index, "Download the latest version of the GDScript Formatter") current_item_index += 1 + popup_menu.add_item(MENU_ITEMS["manual_install"], current_item_index) + popup_menu.set_item_metadata(current_item_index, "manual_install") + popup_menu.set_item_tooltip(current_item_index, "Manually install GDScript Formatter") + current_item_index += 1 + if show_uninstall: popup_menu.add_item(MENU_ITEMS["uninstall"], current_item_index) popup_menu.set_item_metadata(current_item_index, "uninstall") diff --git a/addons/GDQuest_GDScript_formatter/plugin.gd b/addons/GDQuest_GDScript_formatter/plugin.gd index f8c9d97..3e0b1f7 100644 --- a/addons/GDQuest_GDScript_formatter/plugin.gd +++ b/addons/GDQuest_GDScript_formatter/plugin.gd @@ -50,6 +50,7 @@ var connection_list: Array[Resource] = [] var installer: FormatterInstaller = null var formatter_cache_dir: String var menu: FormatterMenu = null +var file_select_dialog: EditorFileDialog = null func _init() -> void: @@ -102,6 +103,22 @@ func _enter_tree() -> void: menu.menu_item_selected.connect(_on_menu_item_selected) menu.update_menu(is_formatter_installed_locally()) + file_select_dialog = EditorFileDialog.new() + file_select_dialog.access = EditorFileDialog.ACCESS_FILESYSTEM + file_select_dialog.file_mode = EditorFileDialog.FILE_MODE_OPEN_FILE + file_select_dialog.filters = ["*.zip ; ZIP Archives"] + file_select_dialog.title = "Select Formatter zip file" + get_editor_interface().get_base_control().add_child(file_select_dialog) + installer.show_file_select_dialog.connect( + func _on_show_file_select_dialog(): + if is_instance_valid(file_select_dialog): + file_select_dialog.popup_centered() + ) + file_select_dialog.file_selected.connect( + func _on_file_selected(path: String): + installer.zip_file_selected.emit(path) + ) + update_shortcut() resource_saved.connect(_on_resource_saved) @@ -124,6 +141,10 @@ func _exit_tree() -> void: menu.queue_free() menu = null + if is_instance_valid(file_select_dialog): + file_select_dialog.queue_free() + file_select_dialog = null + func _shortcut_input(event: InputEvent) -> void: if not has_command(get_editor_setting(SETTING_FORMATTER_PATH)): @@ -380,6 +401,8 @@ func _on_menu_item_selected(command: String) -> void: reorder_code() "install_update": installer.install_or_update_formatter() + "manual_install": + installer.manual_install_formatter() "uninstall": uninstall_formatter() "report_issue":