mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-11 02:57:39 +00:00
Preserving state of publish dialog
This commit is contained in:
@@ -1744,9 +1744,15 @@ void MainFrame::publish_project()
|
||||
{
|
||||
if (m_plater == nullptr)
|
||||
return;
|
||||
PublishSettingsDialog dlg(this);
|
||||
// Seed the dialog from the session selection (a remembered state or a freshly loaded
|
||||
// published 3MF); a null pointer means "fresh", keeping the dirty defaults.
|
||||
std::vector<std::string> pending_keys;
|
||||
std::vector<Slic3r::PublishedMaterialEntry> pending_material;
|
||||
const bool has_prior = m_plater->get_pending_published(pending_keys, pending_material);
|
||||
PublishSettingsDialog dlg(this, has_prior ? &pending_keys : nullptr, has_prior ? &pending_material : nullptr);
|
||||
if (dlg.ShowModal() != wxID_OK)
|
||||
return;
|
||||
m_plater->set_pending_published(dlg.GetPublishedKeys(), dlg.GetPublishedMaterialKeys());
|
||||
m_plater->export_published_3mf(dlg.GetPublishedKeys(), dlg.GetPublishedMaterialKeys());
|
||||
}
|
||||
|
||||
|
||||
@@ -6750,6 +6750,12 @@ struct Plater::priv
|
||||
SendToPrinterDialog* m_send_to_sdcard_dlg = nullptr;
|
||||
PublishDialog* m_publish_dlg = nullptr;
|
||||
|
||||
// Session-level stash of the last published selection. Written on publish and on
|
||||
// loading a published 3MF; read when the Publish dialog is opened.
|
||||
bool m_has_pending_published{false};
|
||||
std::vector<std::string> m_pending_published_keys;
|
||||
std::vector<Slic3r::PublishedMaterialEntry> m_pending_material_keys;
|
||||
|
||||
// Data
|
||||
Slic3r::DynamicPrintConfig* config; // FIXME: leak?
|
||||
Slic3r::Print fff_print;
|
||||
@@ -9087,6 +9093,15 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
||||
NotificationManager::NotificationLevel::WarningNotificationLevel);
|
||||
}
|
||||
|
||||
// Remember the imported published selection so the Publish dialog is
|
||||
// pre-seeded with the file's settings. Stored after the load so any
|
||||
// per-slot relocations are already reflected in material_keys.
|
||||
if (published_config.published) {
|
||||
this->m_has_pending_published = true;
|
||||
this->m_pending_published_keys = published_config.published_keys;
|
||||
this->m_pending_material_keys = published_config.material_keys;
|
||||
}
|
||||
|
||||
ConfigOption* bed_type_opt = preset_bundle->project_config.option("curr_bed_type");
|
||||
if (bed_type_opt != nullptr) {
|
||||
BedType bed_type = (BedType) bed_type_opt->getInt();
|
||||
@@ -10290,6 +10305,11 @@ void Plater::priv::reset(bool apply_presets_change)
|
||||
|
||||
clear_warnings();
|
||||
|
||||
// A new project must not inherit the previous project's published selection (Feature A/B).
|
||||
m_has_pending_published = false;
|
||||
m_pending_published_keys.clear();
|
||||
m_pending_material_keys.clear();
|
||||
|
||||
set_project_filename("");
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << " call set_project_filename: empty";
|
||||
|
||||
@@ -18411,6 +18431,24 @@ int Plater::export_published_3mf(const std::vector<std::string>& published_keys,
|
||||
return wxID_YES;
|
||||
}
|
||||
|
||||
bool Plater::get_pending_published(std::vector<std::string>& out_keys,
|
||||
std::vector<Slic3r::PublishedMaterialEntry>& out_material) const
|
||||
{
|
||||
if (!p->m_has_pending_published)
|
||||
return false;
|
||||
out_keys = p->m_pending_published_keys;
|
||||
out_material = p->m_pending_material_keys;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Plater::set_pending_published(const std::vector<std::string>& published_keys,
|
||||
const std::vector<Slic3r::PublishedMaterialEntry>& material_keys)
|
||||
{
|
||||
p->m_has_pending_published = true;
|
||||
p->m_pending_published_keys = published_keys;
|
||||
p->m_pending_material_keys = material_keys;
|
||||
}
|
||||
|
||||
Preset* get_printer_preset(const MachineObject* obj)
|
||||
{
|
||||
if (!obj)
|
||||
|
||||
@@ -520,6 +520,10 @@ public:
|
||||
// Export a "published" 3MF embedding the author-selected settings in the file metadata; a
|
||||
// pure export that leaves the in-memory project untouched.
|
||||
int export_published_3mf(const std::vector<std::string>& published_keys, const std::vector<Slic3r::PublishedMaterialEntry>& material_keys);
|
||||
// Session-level stash of the last published selection, seeded into the Publish dialog on
|
||||
// open and written on publish or on loading a published 3MF
|
||||
bool get_pending_published(std::vector<std::string>& out_keys, std::vector<Slic3r::PublishedMaterialEntry>& out_material) const;
|
||||
void set_pending_published(const std::vector<std::string>& published_keys, const std::vector<Slic3r::PublishedMaterialEntry>& material_keys);
|
||||
static TriangleMesh combine_mesh_fff(const ModelObject& mo, int instance_id, std::function<void(const std::string&)> notify_func = {});
|
||||
void export_stl(bool extended = false, bool selection_only = false, bool multi_stls = false, FileType file_type = FT_STL);
|
||||
//BBS: remove amf
|
||||
|
||||
@@ -434,7 +434,8 @@ PublishSettingsDialog::MixedVisualSpec PublishSettingsDialog::make_mixed_visual_
|
||||
return spec;
|
||||
}
|
||||
|
||||
PublishSettingsDialog::PublishSettingsDialog(wxWindow* parent)
|
||||
PublishSettingsDialog::PublishSettingsDialog(wxWindow* parent, const std::vector<std::string>* published_keys,
|
||||
const std::vector<Slic3r::PublishedMaterialEntry>* material_keys)
|
||||
: DPIDialog(parent ? parent : static_cast<wxWindow*>(wxGetApp().mainframe),
|
||||
wxID_ANY,
|
||||
_L("Publish 3MF..."),
|
||||
@@ -522,6 +523,11 @@ PublishSettingsDialog::PublishSettingsDialog(wxWindow* parent)
|
||||
|
||||
build_option_model();
|
||||
|
||||
// Seed from a remembered session selection or a freshly loaded published 3MF (authoritative).
|
||||
if (published_keys != nullptr || material_keys != nullptr)
|
||||
apply_selection(published_keys != nullptr ? *published_keys : std::vector<std::string>(),
|
||||
material_keys != nullptr ? *material_keys : std::vector<Slic3r::PublishedMaterialEntry>());
|
||||
|
||||
auto dlg_btns = new DialogButtons(this, {"OK", "Cancel"});
|
||||
|
||||
dlg_btns->GetOK()->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) {
|
||||
@@ -1691,6 +1697,89 @@ void PublishSettingsDialog::show_menu(wxMouseEvent& evt)
|
||||
PopupMenu(&m, local_pos);
|
||||
}
|
||||
|
||||
void PublishSettingsDialog::apply_selection(const std::vector<std::string>& published_keys,
|
||||
const std::vector<Slic3r::PublishedMaterialEntry>& material_keys)
|
||||
{
|
||||
// The supplied selection is authoritative: clear the dirty-default pre-check first so a
|
||||
// dirty key the user deselected stays off, then re-select exactly what the selection names.
|
||||
for (Row& row : m_rows)
|
||||
if (row.check != nullptr)
|
||||
row.check->SetValue(false);
|
||||
for (Category& cat : m_categories) {
|
||||
if (cat.section != Section::Material)
|
||||
continue;
|
||||
if (cat.enable_check != nullptr)
|
||||
cat.enable_check->SetValue(false);
|
||||
if (cat.full_check != nullptr)
|
||||
cat.full_check->SetValue(false);
|
||||
}
|
||||
|
||||
// Print / printer rows: match by exact row key (the full "#N" opt_id where present).
|
||||
for (const std::string& key : published_keys)
|
||||
for (Row& row : m_rows)
|
||||
if ((row.section == Section::Print || row.section == Section::Printer) && row.check != nullptr && row.key == key) {
|
||||
row.check->SetValue(true);
|
||||
break;
|
||||
}
|
||||
|
||||
// Per-slot material selections, applied positionally by slot.
|
||||
for (const Slic3r::PublishedMaterialEntry& entry : material_keys) {
|
||||
if (entry.slot < 0)
|
||||
continue;
|
||||
bool entry_mixed = false;
|
||||
for (const std::string& k : entry.keys)
|
||||
if (publish_mixed_keys().count(publish_base_key(k)) != 0) {
|
||||
entry_mixed = true;
|
||||
break;
|
||||
}
|
||||
size_t cat_idx = size_t(-1);
|
||||
for (size_t c = 0; c < m_categories.size(); ++c) {
|
||||
const Category& cat = m_categories[c];
|
||||
if (cat.section != Section::Material || cat.is_mixed != entry_mixed || cat.filament_slot != size_t(entry.slot))
|
||||
continue;
|
||||
cat_idx = c;
|
||||
break;
|
||||
}
|
||||
if (cat_idx == size_t(-1))
|
||||
continue; // slot not present in the receiver (out of range / skipped)
|
||||
Category& cat = m_categories[cat_idx];
|
||||
if (cat.enable_check != nullptr) {
|
||||
cat.enable_check->SetValue(true);
|
||||
on_enable_toggle(cat_idx);
|
||||
}
|
||||
if (entry.full && cat.full_check != nullptr) {
|
||||
cat.full_check->SetValue(true);
|
||||
on_full_toggle(cat_idx);
|
||||
} else {
|
||||
// Setting rows are keyed by the base key.
|
||||
for (const std::string& key : entry.keys) {
|
||||
const std::string base = publish_base_key(key);
|
||||
for (const size_t r : cat.rows) {
|
||||
Row& row = m_rows[r];
|
||||
if (row.kind == RowKind::Setting && row.key == base) {
|
||||
row.check->SetValue(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (entry.publish_type && !entry.publish_type_value.empty())
|
||||
for (const size_t r : cat.rows)
|
||||
if (m_rows[r].kind == RowKind::Type && m_rows[r].check != nullptr) {
|
||||
m_rows[r].check->SetValue(true);
|
||||
break;
|
||||
}
|
||||
if (entry.publish_color && !entry.color.empty())
|
||||
for (const size_t r : cat.rows)
|
||||
if (m_rows[r].kind == RowKind::Color && m_rows[r].check != nullptr) {
|
||||
m_rows[r].check->SetValue(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
apply_visibility();
|
||||
}
|
||||
|
||||
std::vector<std::string> PublishSettingsDialog::GetPublishedKeys() const
|
||||
{
|
||||
std::vector<std::string> out;
|
||||
|
||||
@@ -46,7 +46,14 @@ struct MixedDependencyIssue
|
||||
class PublishSettingsDialog : public DPIDialog
|
||||
{
|
||||
public:
|
||||
PublishSettingsDialog(wxWindow* parent = nullptr);
|
||||
// Optional published selection (Feature A/B): when the caller supplies one (either a
|
||||
// remembered session selection or the payload of a freshly loaded published 3MF) the dialog
|
||||
// is seeded from it, overriding the dirty-default pre-check. A non-null pointer to an empty
|
||||
// selection means "publish nothing" (an intentional empty state); a null pointer means "no
|
||||
// remembered selection" (keep the dirty defaults).
|
||||
PublishSettingsDialog(wxWindow* parent = nullptr,
|
||||
const std::vector<std::string>* published_keys = nullptr,
|
||||
const std::vector<Slic3r::PublishedMaterialEntry>* material_keys = nullptr);
|
||||
~PublishSettingsDialog();
|
||||
|
||||
// The selected print/printer setting keys (in display order); printer keys carry a '#N'
|
||||
@@ -179,6 +186,12 @@ private:
|
||||
};
|
||||
|
||||
void build_option_model();
|
||||
// Seed the dialog from a published selection (print/printer keys + per-slot material keys):
|
||||
// the supplied selection is authoritative - it is applied after the dirty pre-check and
|
||||
// overrides it, so deselected dirty keys stay off. Rows/slots not present in the selection
|
||||
// are left unselected. Unknown or out-of-range entries are skipped gracefully.
|
||||
void apply_selection(const std::vector<std::string>& published_keys,
|
||||
const std::vector<Slic3r::PublishedMaterialEntry>& material_keys);
|
||||
// Frozen snapshot of a mixed slot's definition for the page visualization, resolved from
|
||||
// the full config once at dialog-build time. Gradient slots pre-sample exactly what the
|
||||
// slicer will print: the custom curve wins over the gradient_range endpoints over the
|
||||
|
||||
Reference in New Issue
Block a user