mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-07-24 19:32:18 +00:00
cleanup
This commit is contained in:
@@ -1996,8 +1996,6 @@ void Choice::msw_rescale()
|
||||
|
||||
void PluginField::BUILD()
|
||||
{
|
||||
// Wrap the dynamic rows in a single container panel so the field is a proper window-field
|
||||
// (getWindow() != null). The panel owns m_main_sizer; all row controls are children of it.
|
||||
auto* panel = new wxPanel(m_parent, wxID_ANY);
|
||||
wxGetApp().UpdateDarkUI(panel);
|
||||
window = panel;
|
||||
@@ -2005,7 +2003,6 @@ void PluginField::BUILD()
|
||||
m_main_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
panel->SetSizer(m_main_sizer);
|
||||
|
||||
// Initialize with default values or empty
|
||||
if (m_opt.type == coStrings) {
|
||||
const ConfigOptionStrings* vec = m_opt.get_default_value<ConfigOptionStrings>();
|
||||
if (vec != nullptr && !vec->values.empty()) {
|
||||
@@ -2096,13 +2093,11 @@ void PluginField::add_plugin_row(const wxString& value, bool is_last)
|
||||
const auto button_size = wxSize(def_width_thinner() * m_em_unit, -1);
|
||||
auto row_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
// Select button with search icon
|
||||
ScalableButton* select_btn = new ScalableButton(window, wxID_ANY, "search", wxEmptyString,
|
||||
button_size, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, true, 16);
|
||||
wxGetApp().UpdateDarkUI(select_btn);
|
||||
select_btn->SetToolTip(_L("Select plugin"));
|
||||
|
||||
// Display text control
|
||||
wxTextCtrl* display = new wxTextCtrl(window, wxID_ANY, value,
|
||||
wxDefaultPosition, wxSize(def_width_wider() * m_em_unit, wxDefaultCoord),
|
||||
wxTE_READONLY);
|
||||
@@ -2118,7 +2113,6 @@ void PluginField::add_plugin_row(const wxString& value, bool is_last)
|
||||
remove_btn->SetToolTip(_L("Remove plugin"));
|
||||
}
|
||||
|
||||
// Add button (only on last row)
|
||||
ScalableButton* add_btn = nullptr;
|
||||
if (is_last && !m_opt.readonly) {
|
||||
add_btn = new ScalableButton(window, wxID_ANY, "param_add", wxEmptyString,
|
||||
@@ -2239,7 +2233,6 @@ void PluginField::set_value(const boost::any& value, bool change_event)
|
||||
{
|
||||
m_disable_change_event = !change_event;
|
||||
|
||||
// Handle different input types
|
||||
if (value.empty()) {
|
||||
m_values.clear();
|
||||
} else if (value.type() == typeid(std::vector<std::string>)) {
|
||||
@@ -2312,9 +2305,7 @@ void PluginField::msw_rescale()
|
||||
|
||||
namespace {
|
||||
|
||||
// The stored text as a document, or an empty array when it is absent or unparseable. Used to compare
|
||||
// two versions of the value semantically: re-serializing an unchanged document can reorder keys or
|
||||
// drop whitespace, and that alone must not be allowed to mark the preset dirty.
|
||||
// The stored text as a document, or an empty array when it is absent or unparseable.
|
||||
nlohmann::json plugin_overrides_as_json(const std::string& text)
|
||||
{
|
||||
if (text.empty())
|
||||
@@ -2326,12 +2317,8 @@ nlohmann::json plugin_overrides_as_json(const std::string& text)
|
||||
|
||||
void PluginConfigField::BUILD()
|
||||
{
|
||||
// The button *is* the field's window (the ColourPicker idiom). Wrapping it in a panel would make
|
||||
// this a container that OG_CustomCtrl sizes but never lays out, leaving the button unsized — and
|
||||
// a zero-height row collapses its whole option group out of the page.
|
||||
m_button = new ::Button(m_parent, _L("Configure"));
|
||||
// ButtonType::Parameter is the style for a button sitting next to parameter boxes: it is what
|
||||
// gives the button the same height as the fields above it, which a bare wxButton does not.
|
||||
// ButtonType::Parameter gives the button the same height as the parameter fields above it.
|
||||
m_button->SetStyle(ButtonStyle::Regular, ButtonType::Parameter);
|
||||
|
||||
wxSize size(def_width_wider() * m_em_unit, m_button->GetMinSize().GetHeight());
|
||||
@@ -2360,8 +2347,6 @@ void PluginConfigField::update_button_label()
|
||||
const nlohmann::json entries = plugin_overrides_as_json(m_json);
|
||||
const size_t count = entries.is_array() ? entries.size() : 0;
|
||||
|
||||
// The count is the whole state this row can show: which capabilities they belong to, and what
|
||||
// they hold, is the dialog's job.
|
||||
m_button->SetLabel(count == 0 ? _L("Configure")
|
||||
: wxString::Format(_L("Configure (%d)"), int(count)));
|
||||
}
|
||||
@@ -2379,16 +2364,14 @@ void PluginConfigField::open_dialog()
|
||||
edited = dlg.overrides_json();
|
||||
}
|
||||
|
||||
// Only a semantic change is a change: reopening the dialog and closing it must not dirty the
|
||||
// preset just because the document round-tripped through the serializer.
|
||||
// Compare semantically: a round-trip through the serializer can reorder keys or drop whitespace,
|
||||
// and that alone must not dirty the preset.
|
||||
if (plugin_overrides_as_json(m_json) == plugin_overrides_as_json(edited))
|
||||
return;
|
||||
|
||||
m_json = edited;
|
||||
m_value = m_json;
|
||||
update_button_label();
|
||||
// The one call that makes this behave like every other setting: it drives change_opt_value into
|
||||
// the preset config, Tab::update_dirty(), and the revert arrow.
|
||||
on_change_field();
|
||||
}
|
||||
|
||||
|
||||
@@ -32,8 +32,7 @@
|
||||
#define wxMSW false
|
||||
#endif
|
||||
|
||||
// Orca's styled button (Widgets/Button.hpp), used by PluginConfigField. Declared at global scope,
|
||||
// which is where the widget lives.
|
||||
// Orca's styled button (Widgets/Button.hpp), used by PluginConfigField. It lives at global scope.
|
||||
class Button;
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
@@ -487,9 +486,8 @@ public:
|
||||
void enable() override;
|
||||
void disable() override;
|
||||
|
||||
// Window-field: the dynamic rows live inside a single container panel (assigned to the base
|
||||
// `window` in BUILD), so the field exposes one window instead of a bare sizer. This lets focus/
|
||||
// scroll, full-width sizing and teardown operate on the whole field.
|
||||
// The rows live in one container panel (the base `window`), so the field exposes a window instead
|
||||
// of a bare sizer and focus, sizing and teardown apply to the whole field.
|
||||
wxWindow* getWindow() override { return window; }
|
||||
|
||||
void msw_rescale() override;
|
||||
@@ -521,11 +519,10 @@ private:
|
||||
std::function<std::string()> m_selector;
|
||||
};
|
||||
|
||||
// A settings row whose value is a raw JSON document that nobody should type by hand: the row shows a
|
||||
// button, the button opens PluginsConfigDialog, and the document it hands back becomes the field's
|
||||
// value. Routing the edit through the ordinary Field value/on_change_field path is what earns the row
|
||||
// the same dirty state and revert arrow as every other setting — the dialog itself never touches the
|
||||
// preset.
|
||||
// A settings row whose value is a raw JSON document nobody types by hand: the button opens
|
||||
// PluginsConfigDialog and the document it hands back becomes the field's value. The edit goes through
|
||||
// the ordinary Field value/on_change_field path, so the row gets the same dirty state and revert arrow
|
||||
// as any other setting — the dialog never touches the preset.
|
||||
class PluginConfigField : public Field {
|
||||
using Field::Field;
|
||||
public:
|
||||
@@ -535,9 +532,8 @@ public:
|
||||
|
||||
void BUILD() override;
|
||||
|
||||
// Which preset's capabilities the dialog lists. Supplied by the option group, which already
|
||||
// carries its Tab's type; an int for the same reason OptionsGroup::m_config_type is one — it
|
||||
// keeps Preset.hpp out of this header.
|
||||
// Which preset's capabilities the dialog lists; set by the option group. An int for the same
|
||||
// reason OptionsGroup::m_config_type is one: it keeps Preset.hpp out of this header.
|
||||
void set_preset_type(int type) { m_preset_type = type; }
|
||||
|
||||
void set_value(const boost::any& value, bool change_event = false) override;
|
||||
@@ -546,8 +542,8 @@ public:
|
||||
void enable() override;
|
||||
void disable() override;
|
||||
|
||||
// Window-field: the button is the whole field, so it is the window the option group sizes and
|
||||
// positions (the ColourPicker idiom). A container panel would be sized but never laid out.
|
||||
// The button is the whole field, so it is the window the option group sizes and positions (the
|
||||
// ColourPicker idiom). A container panel would be sized but never laid out, collapsing the row.
|
||||
wxWindow* getWindow() override { return window; }
|
||||
|
||||
void msw_rescale() override;
|
||||
|
||||
@@ -127,9 +127,8 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co
|
||||
});
|
||||
}
|
||||
|
||||
// The dialog behind the button edits one preset's overrides, so it has to know which preset. The
|
||||
// group already carries its Tab's type, and fields are built lazily on activate() — too late for
|
||||
// the Tab to reach in and set it afterwards.
|
||||
// The dialog behind the button edits one preset's overrides, so it has to know which preset. Set
|
||||
// here because fields are built lazily on activate() — too late for the Tab to reach in afterwards.
|
||||
if (auto plugin_config_field = dynamic_cast<PluginConfigField*>(field.get()))
|
||||
if (auto config_group = dynamic_cast<ConfigOptionsGroup*>(this))
|
||||
plugin_config_field->set_preset_type(config_group->config_type());
|
||||
@@ -717,9 +716,8 @@ std::string OptionsGroup::pick_plugin(const ConfigOptionDef& opt)
|
||||
if (selection.plugin_key.empty() || selection.name.empty())
|
||||
return {};
|
||||
|
||||
// Validate that the selected capability's plugin is resolvable, but only the bare capability
|
||||
// name is stored in the option; the full "name;uuid;capability" reference is derived lazily
|
||||
// when the preset is serialized (see ConfigBase::save_plugin_collection).
|
||||
// Only the bare capability name is stored; the full "name;uuid;capability" reference is derived when
|
||||
// the preset is serialized (see ConfigBase::save_plugin_collection). Resolve here to reject bad picks.
|
||||
Slic3r::PluginDescriptor descriptor;
|
||||
if (!manager.get_catalog().try_get_plugin_descriptor(selection.plugin_key, descriptor) || descriptor.name.empty())
|
||||
return {};
|
||||
|
||||
@@ -33,8 +33,8 @@ PluginsConfigDialog::PluginsConfigDialog(wxWindow* parent, Preset::Type type, co
|
||||
: WebViewHostDialog(parent, wxID_ANY, preset_type_title(type))
|
||||
, m_type(type)
|
||||
{
|
||||
// Unparseable text is kept, not replaced: parse_plugin_overrides leaves the document empty and
|
||||
// every row goes read-only, so a preset we cannot understand is never silently overwritten.
|
||||
// On failure the document stays empty and every row goes read-only (see m_parse_error), so a preset
|
||||
// we cannot understand is never silently overwritten.
|
||||
if (!parse_plugin_overrides(overrides_json, m_overrides, m_parse_error))
|
||||
BOOST_LOG_TRIVIAL(error) << "Plugins Config dialog: " << m_parse_error;
|
||||
|
||||
@@ -103,9 +103,8 @@ void PluginsConfigDialog::on_script_message(const nlohmann::json& payload)
|
||||
send_capability_config(id);
|
||||
show_status(_L("Configuration updated. Save the preset to persist it."), "success");
|
||||
} else if (command == "remove_preset_override") {
|
||||
// "Restore defaults" for a preset means holding no override at all: the capability goes back
|
||||
// to the global configuration, which is where an untouched preset takes its values from. The
|
||||
// plugin's own get_default_config() is the global config's default, not the preset's.
|
||||
// "Restore defaults" for a preset means holding no override at all: the capability falls back
|
||||
// to the global configuration, not to the plugin's own get_default_config().
|
||||
if (!m_parse_error.empty()) {
|
||||
send_save_error(id, m_parse_error);
|
||||
return;
|
||||
|
||||
@@ -8,16 +8,12 @@
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
// The config half of the Plugins dialog, scoped to one preset instead of one plugin: it lists the
|
||||
// capabilities the edited preset of `m_type` actually uses (see capabilities_in_use) and edits each
|
||||
// one's stored config, falling back to the global config where the preset has no override.
|
||||
// Lists the plugin capabilities the edited preset of `m_type` uses (see capabilities_in_use) and edits
|
||||
// each one's config, falling back to the global config where the preset has no override.
|
||||
//
|
||||
// It is a pure editor over a JSON document: it never writes to the preset and never writes to the
|
||||
// base config file. The caller seeds it with the preset's raw override text and reads the edited
|
||||
// text back from overrides_json(). PluginConfigField, which owns the value, then feeds that through
|
||||
// the normal field/dirty pipeline — which is what makes the revert arrow behave like any other
|
||||
// setting. The capability list and config payloads are shared with PluginsDialog's Config tab
|
||||
// through PluginConfig's statics.
|
||||
// A pure editor over a JSON document: it never writes to the preset and never writes to the base config
|
||||
// file. The caller seeds it with the preset's raw override text and reads the edited text back from
|
||||
// overrides_json(); PluginConfigField owns the value and feeds it through the normal field/dirty pipeline.
|
||||
class PluginsConfigDialog : public WebViewHostDialog
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -66,10 +66,8 @@ struct PluginCapabilityView
|
||||
bool enabled = false;
|
||||
bool can_toggle = false;
|
||||
bool can_run = false;
|
||||
// Whether the capability supplies its own config UI, cached on the loaded capability at load
|
||||
// time. False for the descriptor-only rows shown for a plugin that is not loaded: its
|
||||
// capabilities have not been materialized yet, so there is nothing to configure until it is
|
||||
// activated. Every real capability is configurable; this only picks the editor.
|
||||
// Whether the capability supplies its own config UI; every capability is configurable, this only
|
||||
// picks the editor. False for descriptor-only rows: an unloaded plugin has no capabilities yet.
|
||||
bool has_config_ui = false;
|
||||
};
|
||||
|
||||
@@ -83,7 +81,6 @@ struct PluginChangelogView
|
||||
// View-model for one plugin row in the dialog
|
||||
struct PluginDialogItem
|
||||
{
|
||||
// Identity and display text
|
||||
std::string plugin_key;
|
||||
std::string plugin_id;
|
||||
std::string display_name;
|
||||
@@ -100,7 +97,6 @@ struct PluginDialogItem
|
||||
std::vector<std::string> type_labels;
|
||||
std::vector<PluginChangelogView> changelog;
|
||||
|
||||
// Derived UI state
|
||||
PluginSource source = PluginSource::Local;
|
||||
PluginStatus status = PluginStatus::Inactive;
|
||||
PluginUpdateStatus update_status = PluginUpdateStatus::Normal;
|
||||
@@ -109,7 +105,6 @@ struct PluginDialogItem
|
||||
bool is_loaded = false;
|
||||
bool loading = false;
|
||||
|
||||
// Installation and capability flags
|
||||
bool is_cloud_plugin = false;
|
||||
bool has_local_package = false;
|
||||
bool unauthorized = false;
|
||||
@@ -119,7 +114,6 @@ struct PluginDialogItem
|
||||
// Runtime capabilities in registration order, or descriptor-only type rows when unloaded.
|
||||
std::vector<PluginCapabilityView> capabilities;
|
||||
|
||||
// Row-level actions
|
||||
PluginAvailableActions available_actions;
|
||||
};
|
||||
|
||||
@@ -154,9 +148,8 @@ PluginDescriptor as_cloud_only_descriptor(PluginDescriptor descriptor)
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
// rescan_plugins() clears the whole catalog and rediscovers only local packages. When
|
||||
// callers do not need fresh cloud data, reuse the current cloud rows after the local
|
||||
// rescan so cloud-only rows and cloud-derived UI state do not disappear.
|
||||
// rescan_plugins() clears the whole catalog and rediscovers only local packages, so when no fresh cloud
|
||||
// data is needed, restore the current cloud rows afterwards or cloud-only rows would disappear.
|
||||
void refresh_plugin_catalog_blocking(bool fetch_cloud)
|
||||
{
|
||||
PluginManager& manager = PluginManager::instance();
|
||||
@@ -220,10 +213,9 @@ nlohmann::json build_plugin_payload_item(const PluginDialogItem& dialog_item)
|
||||
}
|
||||
payload_item["capabilities"] = std::move(caps);
|
||||
|
||||
// The Config tab's sidebar, built by the shared builder so it stays identical to
|
||||
// PluginsConfigDialog's. Deliberately not the `capabilities` array above: that one is the list
|
||||
// tab's, carrying enable/run state and descriptor-only rows for plugins that are not activated
|
||||
// yet — neither of which the config view has any use for.
|
||||
// The Config tab's sidebar, built by the shared builder so it stays identical to PluginsConfigDialog's.
|
||||
// Not the `capabilities` array above: that is the list tab's, with enable/run state and descriptor-only
|
||||
// rows the config view has no use for.
|
||||
std::vector<PluginCapabilityIdentifier> config_ids;
|
||||
for (const PluginCapabilityView& capability : dialog_item.capabilities)
|
||||
if (!capability.name.empty())
|
||||
@@ -329,20 +321,17 @@ PluginDialogItem build_plugin_dialog_item(const PluginDescriptor& descriptor)
|
||||
(descriptor.description.empty() ? "No description." : descriptor.description);
|
||||
item.author = descriptor.author;
|
||||
item.version = descriptor.version;
|
||||
// Installed version: the cloud merge overwrites `version` with the latest cloud version, so prefer
|
||||
// the preserved local version, falling back to `version` for local-only / pre-merge descriptors.
|
||||
// The cloud merge overwrites `version` with the latest cloud version, so prefer the preserved local
|
||||
// one, falling back to `version` for local-only / pre-merge descriptors.
|
||||
item.installed_version = descriptor.has_local_package() ?
|
||||
(descriptor.installed_version.empty() ? descriptor.version : descriptor.installed_version) :
|
||||
std::string{};
|
||||
item.latest_version = descriptor.latest_available_version();
|
||||
// why: sort by the same version the row displays (GetDisplayVersion in index.js) - installed when
|
||||
// installed, otherwise latest - so the Version sort matches what the user sees.
|
||||
item.sort_version = item.installed_version.empty() ? item.latest_version : item.installed_version;
|
||||
item.type_label = descriptor.type_label();
|
||||
item.type_key = plugin_capability_type_to_string(descriptor.primary_capability_type());
|
||||
// "types" is the display-only compatibility list. Cloud plugins show the raw labels the
|
||||
// service returned (which may not map to real capability types); local plugins derive them
|
||||
// from the capabilities actually discovered/loaded.
|
||||
// "types" is display-only: cloud plugins show the raw labels the service returned (which may not map
|
||||
// to real capability types); local plugins derive them from the capabilities actually discovered.
|
||||
if (descriptor.is_cloud_plugin() && !descriptor.display_types.empty()) {
|
||||
for (const std::string& label : descriptor.display_types)
|
||||
if (std::find(item.type_labels.begin(), item.type_labels.end(), label) == item.type_labels.end())
|
||||
@@ -506,10 +495,8 @@ void PluginsDialog::on_script_message(const nlohmann::json& payload)
|
||||
|
||||
const std::string command = payload.value("command", "");
|
||||
if (command == "request_plugins") {
|
||||
// The web page finished loading and is asking for the current catalog. Plugin
|
||||
// discovery already runs at startup and on login, so the shared catalog is up to
|
||||
// date by the time the dialog opens. Just render it here - no blocking fetch on
|
||||
// open. The Refresh button (refresh_plugins) is what triggers a fresh discovery.
|
||||
// Discovery already runs at startup and on login, so the shared catalog is up to date by the
|
||||
// time the dialog opens: render it without a blocking fetch. Refresh is what rediscovers.
|
||||
send_plugins();
|
||||
} else if (command == "refresh_plugins") {
|
||||
refresh_plugins();
|
||||
@@ -588,7 +575,6 @@ nlohmann::json PluginsDialog::build_plugins_payload() const
|
||||
for (const PluginDescriptor& row : invalid)
|
||||
items.push_back(build_plugin_dialog_item(row));
|
||||
|
||||
// In-place sort
|
||||
sort_plugin_items_for_dialog(items, m_plugin_sort_key, m_plugin_sort_order);
|
||||
|
||||
for (const PluginDialogItem& item : items)
|
||||
@@ -635,9 +621,7 @@ void PluginsDialog::toggle_plugin(const std::string& plugin_key, bool enabled)
|
||||
|
||||
PluginDescriptor row_data;
|
||||
if (!get_descriptor(plugin_key, row_data)) {
|
||||
// The row no longer maps to a catalog entry (the catalog changed under the UI).
|
||||
// Toggling is a local action, so just re-render from the current catalog; a cloud
|
||||
// fetch (or clearing rescan) adds nothing here.
|
||||
// The catalog changed under the UI. Toggling is local, so just re-render from it.
|
||||
send_plugins();
|
||||
return;
|
||||
}
|
||||
@@ -663,7 +647,6 @@ void PluginsDialog::toggle_plugin(const std::string& plugin_key, bool enabled)
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for capabilities that are currently in use
|
||||
auto loaded_capabilities = manager.get_loader().get_loaded_plugin_capabilities(plugin_key);
|
||||
|
||||
if (!available_actions.can_toggle) {
|
||||
@@ -684,8 +667,7 @@ void PluginsDialog::toggle_plugin(const std::string& plugin_key, bool enabled)
|
||||
}
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << "Cloud plugin installed locally from Plugins dialog: " << plugin_key;
|
||||
// download_and_install_cloud_plugin updates the descriptor with the installed
|
||||
// local package state, so no rescan or cloud fetch is needed before loading.
|
||||
// download_and_install_cloud_plugin already updated the descriptor, so no rescan is needed here.
|
||||
if (!get_descriptor(plugin_key, row_data)) {
|
||||
send_plugins();
|
||||
return;
|
||||
@@ -731,9 +713,7 @@ void PluginsDialog::toggle_plugin_capability(const std::string& plugin_key, Plug
|
||||
|
||||
PluginDescriptor row_data;
|
||||
if (!get_descriptor(plugin_key, row_data)) {
|
||||
// The row no longer maps to a catalog entry (the catalog changed under the UI).
|
||||
// Toggling is a local action, so just re-render from the current catalog; a cloud
|
||||
// fetch (or clearing rescan) adds nothing here.
|
||||
// The catalog changed under the UI. Toggling is local, so just re-render from it.
|
||||
send_plugins();
|
||||
return;
|
||||
}
|
||||
@@ -950,9 +930,8 @@ void PluginsDialog::restore_capability_config(const std::string& plugin_key,
|
||||
PluginCapabilityType type,
|
||||
const std::string& capability_name)
|
||||
{
|
||||
// Discards whatever the user had stored, so confirm first — same as the other destructive
|
||||
// actions in this dialog. The confirmation stays here rather than in PluginConfig: it needs a
|
||||
// parent window, and it is the dialog's business to ask.
|
||||
// Destructive, so confirm first. The confirmation stays here rather than in PluginConfig: it needs
|
||||
// a parent window.
|
||||
const int rc = wxMessageBox(wxString::Format(_L("Restore the default configuration for \"%s\"?\n\n"
|
||||
"This discards the settings currently saved for this capability."),
|
||||
from_u8(capability_name)),
|
||||
@@ -1013,8 +992,8 @@ void PluginsDialog::run_script_plugin(const std::string& plugin_key, const std::
|
||||
|
||||
send_plugins();
|
||||
|
||||
// The row now shows an "Error" status and the Diagnostics tab holds the full text, so surface
|
||||
// the outcome in the footer status bar instead of a modal box (prefer the friendlier override).
|
||||
// The row already shows "Error" and the Diagnostics tab holds the full text, so report in the
|
||||
// footer status bar instead of a modal box.
|
||||
const wxString message = status_message.empty() ? from_u8(normalized_error) : status_message;
|
||||
show_status(message, "error");
|
||||
};
|
||||
@@ -1063,13 +1042,11 @@ void PluginsDialog::run_script_plugin(const std::string& plugin_key, const std::
|
||||
std::string error;
|
||||
ExecutionResult result;
|
||||
|
||||
// Script plugins run on the main/UI thread (not a worker). They hold live, non-owning
|
||||
// ModelObject*/ModelVolume*/ModelInstance* aliases into host data and can mint ObjectIDs,
|
||||
// which libslic3r requires on the main thread (ObjectID.hpp's non-atomic s_last_id). Running
|
||||
// here makes those reads/instantiations legal and means nothing mutates the model underneath
|
||||
// a run. The trade-off is that a slow execute() freezes the UI, so the contract is to keep
|
||||
// execute() quick and offload heavy work to the plugin's own threading.Thread. orca.host.ui
|
||||
// calls already no-op their main-thread marshaling here.
|
||||
// Script plugins run on the main/UI thread, not a worker: they hold live, non-owning
|
||||
// ModelObject*/ModelVolume*/ModelInstance* aliases into host data and can mint ObjectIDs, which
|
||||
// libslic3r requires on the main thread (ObjectID.hpp's non-atomic s_last_id). The trade-off is that
|
||||
// a slow execute() freezes the UI, so plugins must keep execute() quick and offload heavy work to
|
||||
// their own threading.Thread.
|
||||
{
|
||||
wxBusyCursor busy;
|
||||
try {
|
||||
@@ -1098,7 +1075,6 @@ void PluginsDialog::run_script_plugin(const std::string& plugin_key, const std::
|
||||
if (failed) {
|
||||
plugin.reset();
|
||||
cap.reset();
|
||||
// complete_with_error normalizes an empty message to "Script plugin failed." and reports via the status bar.
|
||||
complete_with_error(result.message, wxString());
|
||||
return;
|
||||
}
|
||||
@@ -1122,9 +1098,8 @@ void PluginsDialog::update_plugin(const std::string& plugin_key)
|
||||
PluginDescriptor descriptor;
|
||||
const wxString name = get_descriptor(plugin_key, descriptor) ? from_u8(descriptor.name) : from_u8(plugin_key);
|
||||
|
||||
// update_cloud_plugin unloads the old plugin, deletes its local package, then downloads and
|
||||
// reinstalls the latest version. Each of those steps already runs off the main thread in the
|
||||
// delete/install paths, so run the whole operation on the worker and pump a progress dialog.
|
||||
// update_cloud_plugin unloads the old plugin, deletes its local package and reinstalls the latest
|
||||
// version; all of that is off-main-thread work, so run it on the worker behind a progress dialog.
|
||||
std::string error;
|
||||
bool updated = false;
|
||||
try {
|
||||
@@ -1144,8 +1119,7 @@ void PluginsDialog::update_plugin(const std::string& plugin_key)
|
||||
return;
|
||||
}
|
||||
|
||||
// update_cloud_plugin installs the package and updates the in-memory descriptor
|
||||
// (installed=true, update_available=false) on success.
|
||||
// update_cloud_plugin already updated the in-memory descriptor, so a UI refresh is enough here.
|
||||
send_plugins();
|
||||
show_status(wxString::Format(_L("Updated \"%s\"."), name), "success");
|
||||
}
|
||||
@@ -1332,10 +1306,8 @@ void PluginsDialog::delete_mine_local_and_cloud_plugin(const std::string& plugin
|
||||
return;
|
||||
}
|
||||
|
||||
// delete_mine_local_and_cloud_plugin already updated the in-memory catalog
|
||||
// (finalize_cloud_plugin_removal removes the row and, when a local package existed,
|
||||
// re-syncs the cloud list itself), so a UI refresh is sufficient here - an extra
|
||||
// clearing rescan + cloud fetch would be redundant.
|
||||
// delete_mine_local_and_cloud_plugin already updated the in-memory catalog (see
|
||||
// finalize_cloud_plugin_removal), so a UI refresh is sufficient here.
|
||||
send_plugins();
|
||||
show_status(wxString::Format(_L("Deleted \"%s\"."), plugin_name), "success");
|
||||
}
|
||||
|
||||
@@ -1790,9 +1790,8 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value)
|
||||
return;
|
||||
}
|
||||
|
||||
// Keep this preset's "plugins" manifest in sync when a plugin picker changes, so the edited preset
|
||||
// always carries resolved "name;uuid;capability" references that full_config() and save_to_json()
|
||||
// then pass downstream as-is -- no separate rebuild anywhere else.
|
||||
// Keep this preset's "plugins" manifest in sync when a plugin picker changes, so full_config() and
|
||||
// save_to_json() always find resolved "name;uuid;capability" references and rebuild it nowhere else.
|
||||
if (const ConfigOptionDef* opt_def = m_config->def()->get(opt_key);
|
||||
opt_def && opt_def->is_plugin_backed())
|
||||
m_config->update_plugin_manifest();
|
||||
@@ -3086,10 +3085,8 @@ void TabPrint::build()
|
||||
option.opt.full_width = true;
|
||||
optgroup->append_single_option_line(option, "others_settings_plugin_picker");
|
||||
|
||||
// Its own group rather than the one above: that one hides its labels, and this row needs its
|
||||
// label — and so the revert arrow beside it — to show. No label-width override either: a 0
|
||||
// there means "no label column", which is what the neighbouring full-width groups want and
|
||||
// what would collapse this one.
|
||||
// Its own group: the one above hides its labels, and this row needs its label — and the revert
|
||||
// arrow beside it — to show. No label-width override either, as a 0 there means "no label column".
|
||||
optgroup = page->new_optgroup(L("Plugin Preferences"), L"param_gcode");
|
||||
optgroup->append_single_option_line("plugin_preference_overrides");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user