diff --git a/src/slic3r/GUI/PluginsDialog.cpp b/src/slic3r/GUI/PluginsDialog.cpp index 3485f686fa..23cf7a2648 100644 --- a/src/slic3r/GUI/PluginsDialog.cpp +++ b/src/slic3r/GUI/PluginsDialog.cpp @@ -138,6 +138,9 @@ PluginDescriptor as_cloud_only_descriptor(PluginDescriptor descriptor) descriptor.plugin_root.clear(); descriptor.entry_path.clear(); descriptor.installed_version.clear(); + // No local package is left behind, so the package verdict and any load error it produced go with it. + descriptor.metadata_valid = false; + descriptor.clear_error(); if (descriptor.cloud.has_value()) { descriptor.cloud->installed = false; descriptor.cloud->update_available = false; @@ -289,11 +292,10 @@ PluginAvailableActions evaluate_action_policy(const PluginDialogItem& item) available_actions.context_actions.push_back(PluginContextAction{id, label, enabled, danger}); }; - if (is_cloud) { - if (is_mine) - add_action("delete_mine_plugin", "Delete", true, true); - else - add_action("unsubscribe_plugin", "Unsubscribe", true, true); + // Owned cloud plugins fall through to the local delete: it removes the installed package only. + // Deleting a plugin from the cloud is a plugin hub operation and is never offered here. + if (is_cloud && !is_mine) { + add_action("unsubscribe_plugin", "Unsubscribe", true, true); } else if (has_local) { add_action("delete_plugin", "Delete", true, true); } @@ -742,8 +744,6 @@ void PluginsDialog::handle_plugin_menu_action(const std::string& plugin_key, con delete_local_plugin(row_data); } else if (action == "unsubscribe_plugin") { unsubscribe_cloud_plugin(row_data); - } else if (action == "delete_mine_plugin") { - delete_mine_local_and_cloud_plugin(plugin_key); } else if (action == "reload_plugin") { reload_local_plugin(plugin_key, /*clear_cache=*/false); } else if (action == "clear_cache_reload_plugin") { @@ -1071,19 +1071,25 @@ void PluginsDialog::open_plugin_hub() void PluginsDialog::delete_local_plugin(const PluginDescriptor& plugin) { const wxString plugin_name = from_u8(plugin.name); - const int rc = wxMessageBox(wxString::Format(_L("Delete plugin \"%s\"?\n\nThis permanently removes the plugin folder."), plugin_name), - kDeletePluginTitle, wxYES_NO | wxNO_DEFAULT | wxICON_WARNING, this); + const int rc = wxMessageBox( + wxString::Format(plugin.is_cloud_plugin() ? + _L("Delete plugin \"%s\"?\n\nThis removes the local plugin files. The plugin stays in the cloud " + "and can be reinstalled.") : + _L("Delete plugin \"%s\"?\n\nThis permanently removes the plugin folder."), + plugin_name), + kDeletePluginTitle, wxYES_NO | wxNO_DEFAULT | wxICON_WARNING, this); restore_z_order(); if (rc != wxYES) return; auto state = std::make_shared(); run_with_dialog( - [plugin_key = plugin.plugin_key, should_refresh = plugin.is_cloud_plugin(), state]() { + [plugin_key = plugin.plugin_key, cloud_row = as_cloud_only_descriptor(plugin), state]() { std::string error; const bool succeeded = PluginManager::instance().delete_plugin(plugin_key, error); - if (succeeded && should_refresh) - refresh_plugin_metadata_blocking(kFetchCloudMeta); + // Keep the cloud row listed so the plugin stays reinstallable without waiting on a cloud fetch. + if (succeeded && cloud_row.is_cloud_plugin()) + PluginManager::instance().update_cloud_metadata(std::vector{cloud_row}); store_plugin_operation_result(state, succeeded, std::move(error)); }, [this, state, plugin_name]() { @@ -1249,28 +1255,4 @@ void PluginsDialog::reinstall_cloud_plugin(const PluginDescriptor& plugin) show_status(wxString::Format(_L("Reloaded \"%s\"."), plugin_display_name(plugin_key)), "success"); } -void PluginsDialog::delete_mine_local_and_cloud_plugin(const std::string& plugin_key) -{ - PluginDescriptor descriptor; - const std::string display = get_descriptor(plugin_key, descriptor) ? descriptor.name : std::string{}; - const wxString plugin_name = from_u8(display.empty() ? plugin_key : display); - const int rc = wxMessageBox( - wxString::Format(_L("Delete plugin \"%s\" from local and cloud?\n\nThis permanently removes the local plugin files and " - "deletes the plugin from the cloud. This action cannot be undone."), - plugin_name), - kDeletePluginTitle, wxYES_NO | wxNO_DEFAULT | wxICON_WARNING, this); - restore_z_order(); - if (rc != wxYES) - return; - - std::string error; - if (!PluginManager::instance().delete_mine_local_and_cloud_plugin(plugin_key, error)) { - show_status(error.empty() ? _L("Failed to delete plugin from local and cloud.") : from_u8(error), "error"); - return; - } - - send_plugins(); - show_status(wxString::Format(_L("Deleted \"%s\"."), plugin_name), "success"); -} - }} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/PluginsDialog.hpp b/src/slic3r/GUI/PluginsDialog.hpp index b921801166..a0e7bd8022 100644 --- a/src/slic3r/GUI/PluginsDialog.hpp +++ b/src/slic3r/GUI/PluginsDialog.hpp @@ -98,7 +98,6 @@ private: void unsubscribe_cloud_plugin(const Slic3r::PluginDescriptor& plugin); void reload_local_plugin(const std::string& plugin_key, bool clear_cache); void reinstall_cloud_plugin(const Slic3r::PluginDescriptor& plugin); - void delete_mine_local_and_cloud_plugin(const std::string& plugin_key); // In the future, we can allow users to choose which plugin version they want to install. template diff --git a/src/slic3r/Utils/OrcaCloudServiceAgent.cpp b/src/slic3r/Utils/OrcaCloudServiceAgent.cpp index d0f80abf72..a372ab5b7c 100644 --- a/src/slic3r/Utils/OrcaCloudServiceAgent.cpp +++ b/src/slic3r/Utils/OrcaCloudServiceAgent.cpp @@ -3505,25 +3505,6 @@ int OrcaCloudServiceAgent::unsubscribe_plugins(const std::vector& p return 0; } -int OrcaCloudServiceAgent::delete_my_plugin(const std::string& plugin_uuid) -{ - if (plugin_uuid.empty()) - return -1; - - const std::string path = std::string(ORCA_PLUGINS_BASE) + "?ids=" + Http::url_encode(plugin_uuid); - std::string response_body; - unsigned int http_code = 0; - - int result = http_delete(path, &response_body, &http_code); - - if (result != 0 || (http_code != 200 && http_code != 204)) { - BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << " failed: http_code=" << http_code << ", response=" << response_body; - return http_code != 0 ? static_cast(http_code) : result; - } - - return 0; -} - int OrcaCloudServiceAgent::fetch_plugin_changelogs(const std::vector& uuids, std::unordered_map>& changelog) { diff --git a/src/slic3r/Utils/OrcaCloudServiceAgent.hpp b/src/slic3r/Utils/OrcaCloudServiceAgent.hpp index 2f422def07..3ae86ec27c 100644 --- a/src/slic3r/Utils/OrcaCloudServiceAgent.hpp +++ b/src/slic3r/Utils/OrcaCloudServiceAgent.hpp @@ -311,7 +311,6 @@ public: std::string get_plugin_url(const std::string& sharing_token) const; int subscribe_plugin(const std::string& plugin_uuid); int unsubscribe_plugins(const std::vector& plugin_uuids); - int delete_my_plugin(const std::string& plugin_uuid); int fetch_plugin_changelogs(const std::vector& uuids, std::unordered_map>& changelog); // ======================================================================== diff --git a/src/slic3r/plugin/CloudPluginService.cpp b/src/slic3r/plugin/CloudPluginService.cpp index a5d674809a..6b72da3293 100644 --- a/src/slic3r/plugin/CloudPluginService.cpp +++ b/src/slic3r/plugin/CloudPluginService.cpp @@ -113,39 +113,6 @@ bool CloudPluginService::request_cloud_unsubscribe(const PluginDescriptor& plugi return true; } -bool CloudPluginService::request_cloud_delete(const PluginDescriptor& plugin, std::string& error) const -{ - if (!m_orca_agent) { - error = "No cloud agent."; - return false; - } - - if (!plugin.is_cloud_plugin()) { - error = "Only cloud plugins can be deleted."; - return false; - } - - const std::string cloud_uuid = plugin.cloud_uuid(); - if (cloud_uuid.empty()) { - error = "Cloud plugin key is missing UUID."; - return false; - } - - if (!plugin.cloud.has_value() || !plugin.cloud->is_mine) { - error = "Only your own plugins can be deleted from the cloud."; - return false; - } - - int result = m_orca_agent->delete_my_plugin(cloud_uuid); - - if (result != 0) { - error = "Failed to delete plugin from cloud, see logs for more info."; - return false; - } - - return true; -} - bool CloudPluginService::download_cloud_plugin(PluginDescriptor& entry, const std::string& requested_version, CloudPluginDownload& download, diff --git a/src/slic3r/plugin/CloudPluginService.hpp b/src/slic3r/plugin/CloudPluginService.hpp index cb6ded007e..bf244086d0 100644 --- a/src/slic3r/plugin/CloudPluginService.hpp +++ b/src/slic3r/plugin/CloudPluginService.hpp @@ -29,7 +29,6 @@ public: std::vector& unauthorized) const; bool request_cloud_subscribe(const std::string& plugin_uuid, std::string& error) const; bool request_cloud_unsubscribe(const PluginDescriptor& plugin, std::string& error) const; - bool request_cloud_delete(const PluginDescriptor& plugin, std::string& error) const; bool download_cloud_plugin(PluginDescriptor& entry, const std::string& requested_version, CloudPluginDownload& download, diff --git a/src/slic3r/plugin/PluginManager.cpp b/src/slic3r/plugin/PluginManager.cpp index 761a9aad63..37d5651a52 100644 --- a/src/slic3r/plugin/PluginManager.cpp +++ b/src/slic3r/plugin/PluginManager.cpp @@ -1857,7 +1857,7 @@ bool PluginManager::unsubscribe_cloud_plugin(const std::string& plugin_key, std: } if (descriptor.cloud && descriptor.cloud->is_mine) { - error = "Cannot unsubscribe your own plugins. Use Delete from Cloud instead."; + error = "Cannot unsubscribe your own plugins."; set_plugin_error(plugin_key, error); return false; } @@ -1890,7 +1890,7 @@ bool PluginManager::delete_and_unsubscribe_cloud_plugin(const std::string& plugi } if (descriptor.cloud->is_mine) { - error = "Use Delete local and cloud for owned plugins."; + error = "Cannot unsubscribe your own plugins. Use Delete to remove the local files."; set_plugin_error(plugin_key, error); return false; } @@ -1903,72 +1903,6 @@ bool PluginManager::delete_and_unsubscribe_cloud_plugin(const std::string& plugi return finalize_cloud_plugin_removal(descriptor, false, error); } -bool PluginManager::delete_mine_plugin_from_cloud(const std::string& plugin_key, std::string& error) -{ - if (!wait_for_discovery(std::chrono::milliseconds::max(), error)) - return false; - - error.clear(); - - PluginDescriptor descriptor; - if (!try_get_plugin_descriptor(plugin_key, descriptor)) { - error = "Plugin not found: " + plugin_key; - return false; - } - - if (!descriptor.is_cloud_plugin()) { - error = "Only owned cloud plugins can be deleted from the cloud."; - set_plugin_error(plugin_key, error); - return false; - } - - if (!descriptor.cloud->is_mine) { - error = "Only your own plugins can be deleted from the cloud."; - set_plugin_error(plugin_key, error); - return false; - } - - if (!m_cloud_service.request_cloud_delete(descriptor, error)) { - set_plugin_error(plugin_key, error); - return false; - } - - return finalize_cloud_plugin_removal(descriptor, true, error); -} - -bool PluginManager::delete_mine_local_and_cloud_plugin(const std::string& plugin_key, std::string& error) -{ - if (!wait_for_discovery(std::chrono::milliseconds::max(), error)) - return false; - - error.clear(); - - PluginDescriptor descriptor; - if (!try_get_plugin_descriptor(plugin_key, descriptor)) { - error = "Plugin not found: " + plugin_key; - return false; - } - - if (!descriptor.is_cloud_plugin()) { - error = "Only owned cloud plugins can be deleted from local and cloud."; - set_plugin_error(plugin_key, error); - return false; - } - - if (!descriptor.cloud->is_mine) { - error = "Only your own plugins can be deleted from local and cloud."; - set_plugin_error(plugin_key, error); - return false; - } - - if (!m_cloud_service.request_cloud_delete(descriptor, error)) { - set_plugin_error(plugin_key, error); - return false; - } - - return finalize_cloud_plugin_removal(descriptor, false, error); -} - ExecutionResult PluginManager::run_script_capability(const std::string& plugin_key, const std::string& capability_name, std::string& error) { if (plugin_key.empty() || capability_name.empty()) { diff --git a/src/slic3r/plugin/PluginManager.hpp b/src/slic3r/plugin/PluginManager.hpp index 59a2791355..72fb9512b0 100644 --- a/src/slic3r/plugin/PluginManager.hpp +++ b/src/slic3r/plugin/PluginManager.hpp @@ -196,8 +196,6 @@ public: bool delete_plugin(const std::string& plugin_key, std::string& error); bool unsubscribe_cloud_plugin(const std::string& plugin_key, std::string& error); bool delete_and_unsubscribe_cloud_plugin(const std::string& plugin_key, std::string& error); - bool delete_mine_plugin_from_cloud(const std::string& plugin_key, std::string& error); - bool delete_mine_local_and_cloud_plugin(const std::string& plugin_key, std::string& error); ExecutionResult run_script_capability(const std::string& plugin_key, const std::string& capability_name, std::string& error);