mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 09:25:57 +08:00
Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer into et_preview_layout
This commit is contained in:
commit
135352f0db
File diff suppressed because it is too large
Load Diff
@ -490,6 +490,8 @@ std::vector<GCode::LayerToPrint> GCode::collect_layers_to_print(const PrintObjec
|
||||
gap_over_supports += support_layer_height_min;
|
||||
}
|
||||
|
||||
std::vector<std::pair<double, double>> warning_ranges;
|
||||
|
||||
// Pair the object layers with the support layers by z.
|
||||
size_t idx_object_layer = 0;
|
||||
size_t idx_support_layer = 0;
|
||||
@ -535,15 +537,8 @@ std::vector<GCode::LayerToPrint> GCode::collect_layers_to_print(const PrintObjec
|
||||
// Negative support_contact_z is not taken into account, it can result in false positives in cases
|
||||
// where previous layer has object extrusions too (https://github.com/prusa3d/PrusaSlicer/issues/2752)
|
||||
|
||||
if (has_extrusions && layer_to_print.print_z() > maximal_print_z + 2. * EPSILON) {
|
||||
const_cast<Print*>(object.print())->active_step_add_warning(PrintStateBase::WarningLevel::CRITICAL,
|
||||
Slic3r::format(_(L("Empty layer detected between heights %1% and %2%. Make sure the object is printable.")),
|
||||
(last_extrusion_layer ? last_extrusion_layer->print_z() : 0.),
|
||||
layers_to_print.back().print_z())
|
||||
+ "\n" + Slic3r::format(_(L("Object name: %1%")), object.model_object()->name) + "\n\n"
|
||||
+ _(L("This is usually caused by negligibly small extrusions or by a faulty model. "
|
||||
"Try to repair the model or change its orientation on the bed.")));
|
||||
}
|
||||
if (has_extrusions && layer_to_print.print_z() > maximal_print_z + 2. * EPSILON)
|
||||
warning_ranges.emplace_back(std::make_pair((last_extrusion_layer ? last_extrusion_layer->print_z() : 0.), layers_to_print.back().print_z()));
|
||||
|
||||
// Remember last layer with extrusions.
|
||||
if (has_extrusions)
|
||||
@ -551,6 +546,23 @@ std::vector<GCode::LayerToPrint> GCode::collect_layers_to_print(const PrintObjec
|
||||
}
|
||||
}
|
||||
|
||||
if (! warning_ranges.empty()) {
|
||||
std::string warning;
|
||||
size_t i = 0;
|
||||
for (i = 0; i < std::min(warning_ranges.size(), size_t(3)); ++i)
|
||||
warning += Slic3r::format(_(L("Empty layer between %1% and %2%.")),
|
||||
warning_ranges[i].first, warning_ranges[i].second) + "\n";
|
||||
if (i < warning_ranges.size())
|
||||
warning += _(L("(Some lines not shown)")) + "\n";
|
||||
warning += "\n";
|
||||
warning += Slic3r::format(_(L("Object name: %1%")), object.model_object()->name) + "\n\n"
|
||||
+ _(L("Make sure the object is printable. This is usually caused by negligibly small extrusions or by a faulty model. "
|
||||
"Try to repair the model or change its orientation on the bed."));
|
||||
|
||||
const_cast<Print*>(object.print())->active_step_add_warning(
|
||||
PrintStateBase::WarningLevel::CRITICAL, warning);
|
||||
}
|
||||
|
||||
return layers_to_print;
|
||||
}
|
||||
|
||||
|
@ -2441,13 +2441,13 @@ void PrintConfigDef::init_fff_params()
|
||||
def = this->add("slicing_mode", coEnum);
|
||||
def->label = L("Slicing Mode");
|
||||
def->category = L("Advanced");
|
||||
def->tooltip = L("Use \"Even / Odd\" for 3DLabPrint airplane models. Use \"Close holes\" to close all holes in the model.");
|
||||
def->tooltip = L("Use \"Even-odd\" for 3DLabPrint airplane models. Use \"Close holes\" to close all holes in the model.");
|
||||
def->enum_keys_map = &ConfigOptionEnum<SlicingMode>::get_enum_values();
|
||||
def->enum_values.push_back("regular");
|
||||
def->enum_values.push_back("even_odd");
|
||||
def->enum_values.push_back("close_holes");
|
||||
def->enum_labels.push_back(L("Regular"));
|
||||
def->enum_labels.push_back(L("Even / Odd"));
|
||||
def->enum_labels.push_back(L("Even-odd"));
|
||||
def->enum_labels.push_back(L("Close holes"));
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionEnum<SlicingMode>(SlicingMode::Regular));
|
||||
|
@ -13,7 +13,10 @@
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define HAS_GLSAFE
|
||||
#endif // NDEBUG
|
||||
|
||||
#ifdef HAS_GLSAFE
|
||||
extern void glAssertRecentCallImpl(const char *file_name, unsigned int line, const char *function_name);
|
||||
inline void glAssertRecentCall() { glAssertRecentCallImpl(__FILE__, __LINE__, __FUNCTION__); }
|
||||
|
@ -772,9 +772,11 @@ void PageMaterials::set_compatible_printers_html_window(const std::vector<std::s
|
||||
, second_line
|
||||
);
|
||||
} else {
|
||||
wxString second_line = printer_names.empty() ? "" : format_wxstr(_L("Only the following installed printers are compatible with the selected %1%:"),
|
||||
materials->technology == T_FFF ? _CTX(L_CONTEXT("filaments", "WithSelected"), "WithSelected") :
|
||||
_CTX(L_CONTEXT("SLA materials", "WithSelected"), "WithSelected"));
|
||||
wxString second_line;
|
||||
if (!printer_names.empty())
|
||||
second_line = (materials->technology == T_FFF ?
|
||||
_L("Only the following installed printers are compatible with the selected filaments") :
|
||||
_L("Only the following installed printers are compatible with the selected SLA materials")) + ":";
|
||||
text = wxString::Format(
|
||||
"<html>"
|
||||
"<style>"
|
||||
@ -2563,7 +2565,7 @@ bool ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese
|
||||
}
|
||||
if (!check_unsaved_preset_changes)
|
||||
if ((check_unsaved_preset_changes = install_bundles.size() > 0))
|
||||
header = _L_PLURAL("New vendor was installed and one of its printer will be activated", "New vendors were installed and one of theirs printer will be activated", install_bundles.size());
|
||||
header = _L_PLURAL("A new vendor was installed and one of its printers will be activated", "New vendors were installed and one of theirs printers will be activated", install_bundles.size());
|
||||
|
||||
#ifdef __linux__
|
||||
// Desktop integration on Linux
|
||||
|
@ -812,13 +812,11 @@ static boost::optional<Semver> parse_semver_from_ini(std::string path)
|
||||
std::stringstream buffer;
|
||||
buffer << stream.rdbuf();
|
||||
std::string body = buffer.str();
|
||||
size_t end_line = body.find_first_of("\n\r");
|
||||
body.resize(end_line);
|
||||
size_t start = body.find("PrusaSlicer ");
|
||||
if (start == std::string::npos)
|
||||
return boost::none;
|
||||
body = body.substr(start + 12);
|
||||
size_t end = body.find_first_of(" \n\r");
|
||||
size_t end = body.find_first_of(" \n");
|
||||
if (end < body.size())
|
||||
body.resize(end);
|
||||
return Semver::parse(body);
|
||||
|
@ -419,7 +419,7 @@ MeshErrorsInfo ObjectList::get_mesh_errors_info(const int obj_idx, const int vol
|
||||
if (repaired.facets_reversed > 0)
|
||||
tooltip += "\t" + format_wxstr(_L_PLURAL("%1$d facet reversed", "%1$d facets reversed", repaired.facets_reversed), repaired.facets_reversed) + "\n";
|
||||
if (repaired.backwards_edges > 0)
|
||||
tooltip += "\t" + format_wxstr(_L_PLURAL("%1$d backwards edge", "%1$d backwards edges", repaired.backwards_edges), repaired.backwards_edges) + "\n";
|
||||
tooltip += "\t" + format_wxstr(_L_PLURAL("%1$d backward edge", "%1$d backward edges", repaired.backwards_edges), repaired.backwards_edges) + "\n";
|
||||
}
|
||||
if (!stats.manifold()) {
|
||||
remaining_info = format_wxstr(_L_PLURAL("%1$d open edge", "%1$d open edges", stats.open_edges), stats.open_edges);
|
||||
@ -4155,7 +4155,7 @@ void ObjectList::fix_through_netfabb()
|
||||
wxString msg;
|
||||
wxString bullet_suf = "\n - ";
|
||||
if (!succes_models.empty()) {
|
||||
msg = _L_PLURAL("Folowing model is repaired successfully", "Folowing models are repaired successfully", succes_models.size()) + ":";
|
||||
msg = _L_PLURAL("The following model was repaired successfully", "The following models were repaired successfully", succes_models.size()) + ":";
|
||||
for (auto& model : succes_models)
|
||||
msg += bullet_suf + from_u8(model);
|
||||
msg += "\n\n";
|
||||
|
@ -97,6 +97,8 @@ public:
|
||||
// will be also extended to support additional states, requiring at least one state to remain free out of 19 states.
|
||||
static const constexpr size_t EXTRUDERS_LIMIT = 16;
|
||||
|
||||
virtual const float get_cursor_radius_min() const { return CursorRadiusMin; }
|
||||
|
||||
protected:
|
||||
std::array<float, 4> get_cursor_sphere_left_button_color() const override;
|
||||
std::array<float, 4> get_cursor_sphere_right_button_color() const override;
|
||||
@ -120,6 +122,8 @@ protected:
|
||||
std::vector<std::array<float, 4>> m_modified_extruders_colors;
|
||||
std::vector<int> m_original_volumes_extruder_idxs;
|
||||
|
||||
static const constexpr float CursorRadiusMin = 0.1f; // cannot be zero
|
||||
|
||||
private:
|
||||
bool on_init() override;
|
||||
|
||||
|
@ -254,8 +254,8 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
||||
}
|
||||
else if (alt_down) {
|
||||
if (m_tool_type == ToolType::BRUSH && (m_cursor_type == TriangleSelector::CursorType::SPHERE || m_cursor_type == TriangleSelector::CursorType::CIRCLE)) {
|
||||
m_cursor_radius = action == SLAGizmoEventType::MouseWheelDown ? std::max(m_cursor_radius - CursorRadiusStep, CursorRadiusMin)
|
||||
: std::min(m_cursor_radius + CursorRadiusStep, CursorRadiusMax);
|
||||
m_cursor_radius = action == SLAGizmoEventType::MouseWheelDown ? std::max(m_cursor_radius - this->get_cursor_radius_step(), this->get_cursor_radius_min())
|
||||
: std::min(m_cursor_radius + this->get_cursor_radius_step(), this->get_cursor_radius_max());
|
||||
m_parent.set_as_dirty();
|
||||
return true;
|
||||
} else if (m_tool_type == ToolType::SMART_FILL) {
|
||||
|
@ -122,6 +122,10 @@ public:
|
||||
// after all volumes (including transparent ones) are rendered.
|
||||
virtual void render_painter_gizmo() const = 0;
|
||||
|
||||
virtual const float get_cursor_radius_min() const { return CursorRadiusMin; }
|
||||
virtual const float get_cursor_radius_max() const { return CursorRadiusMax; }
|
||||
virtual const float get_cursor_radius_step() const { return CursorRadiusStep; }
|
||||
|
||||
protected:
|
||||
virtual void render_triangles(const Selection& selection) const;
|
||||
void render_cursor() const;
|
||||
|
@ -63,21 +63,26 @@ MsgDialog::MsgDialog(wxWindow *parent, const wxString &title, const wxString &he
|
||||
SetSizerAndFit(main_sizer);
|
||||
}
|
||||
|
||||
void MsgDialog::add_btn(wxWindowID btn_id, bool set_focus /*= false*/, const wxString& label/* = wxString()*/)
|
||||
wxButton* MsgDialog::add_button(wxWindowID btn_id, bool set_focus /*= false*/, const wxString& label/* = wxString()*/)
|
||||
{
|
||||
wxButton* btn = new wxButton(this, btn_id, label);
|
||||
if (set_focus)
|
||||
btn->SetFocus();
|
||||
btn_sizer->Add(btn, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, HORIZ_SPACING);
|
||||
btn->Bind(wxEVT_BUTTON, [this, btn_id](wxCommandEvent&) { this->EndModal(btn_id); });
|
||||
return btn;
|
||||
};
|
||||
|
||||
wxButton* MsgDialog::get_button(wxWindowID btn_id){
|
||||
return static_cast<wxButton*>(FindWindowById(btn_id, this));
|
||||
}
|
||||
|
||||
void MsgDialog::apply_style(long style)
|
||||
{
|
||||
if (style & wxOK) add_btn(wxID_OK, true);
|
||||
if (style & wxYES) add_btn(wxID_YES, true);
|
||||
if (style & wxNO) add_btn(wxID_NO);
|
||||
if (style & wxCANCEL) add_btn(wxID_CANCEL);
|
||||
if (style & wxOK) add_button(wxID_OK, true);
|
||||
if (style & wxYES) add_button(wxID_YES, true);
|
||||
if (style & wxNO) add_button(wxID_NO);
|
||||
if (style & wxCANCEL) add_button(wxID_CANCEL);
|
||||
|
||||
logo->SetBitmap( create_scaled_bitmap(style & wxICON_WARNING ? "exclamation" :
|
||||
style & wxICON_INFORMATION ? "info" :
|
||||
|
@ -42,8 +42,10 @@ protected:
|
||||
};
|
||||
|
||||
MsgDialog(wxWindow *parent, const wxString &title, const wxString &headline, long style = wxOK, wxBitmap bitmap = wxNullBitmap);
|
||||
|
||||
void add_btn(wxWindowID btn_id, bool set_focus = false, const wxString& label = wxString());
|
||||
// returns pointer to created button
|
||||
wxButton* add_button(wxWindowID btn_id, bool set_focus = false, const wxString& label = wxString());
|
||||
// returns pointer to found button or NULL
|
||||
wxButton* get_button(wxWindowID btn_id);
|
||||
void apply_style(long style);
|
||||
void finalize();
|
||||
|
||||
|
@ -1068,14 +1068,12 @@ void NotificationManager::UpdatedItemsInfoNotification::add_type(InfoItemType ty
|
||||
for (it = m_types_and_counts.begin(); it != m_types_and_counts.end(); ++it) {
|
||||
if ((*it).second == 0)
|
||||
continue;
|
||||
text += std::to_string((*it).second);
|
||||
text += _L_PLURAL(" Object was loaded with "," Objects were loaded with ", (*it).second).ToUTF8().data();
|
||||
switch ((*it).first) {
|
||||
case InfoItemType::CustomSupports: text += _utf8("custom supports.\n"); break;
|
||||
case InfoItemType::CustomSeam: text += _utf8("custom seam.\n"); break;
|
||||
case InfoItemType::MmuSegmentation: text += _utf8("multimaterial painting.\n"); break;
|
||||
case InfoItemType::VariableLayerHeight: text += _utf8("variable layer height.\n"); break;
|
||||
case InfoItemType::Sinking: text += _utf8("Partial sinking.\n"); break;
|
||||
case InfoItemType::CustomSupports: text += format(_L_PLURAL("%1$d Object was loaded with custom supports.", "%1$d Objects were loaded with custom supports.", (*it).second), (*it).second) + "\n"; break;
|
||||
case InfoItemType::CustomSeam: text += format(_L_PLURAL("%1$d Object was loaded with custom seam.", "%1$d Objects were loaded with custom seam.", (*it).second), (*it).second) + "\n"; break;
|
||||
case InfoItemType::MmuSegmentation: text += format(_L_PLURAL("%1$d Object was loaded with multimaterial painting.", "%1$d Objects were loaded with multimaterial painting.",(*it).second), (*it).second) + "\n"; break;
|
||||
case InfoItemType::VariableLayerHeight: text += format(_L_PLURAL("%1$d Object was loaded with variable layer height.", "%1$d Objects were loaded with variable layer height.", (*it).second), (*it).second) + "\n"; break;
|
||||
case InfoItemType::Sinking: text += format(_L_PLURAL("%1$d Object was loaded with partial sinking.", "%1$d Objects were loaded with partial sinking.", (*it).second), (*it).second) + "\n"; break;
|
||||
default: BOOST_LOG_TRIVIAL(error) << "Unknown InfoItemType: " << (*it).second; break;
|
||||
}
|
||||
}
|
||||
|
@ -457,6 +457,7 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent) :
|
||||
std::vector<float> extruders = dlg.get_extruders();
|
||||
(project_config.option<ConfigOptionFloats>("wiping_volumes_matrix"))->values = std::vector<double>(matrix.begin(), matrix.end());
|
||||
(project_config.option<ConfigOptionFloats>("wiping_volumes_extruders"))->values = std::vector<double>(extruders.begin(), extruders.end());
|
||||
wxGetApp().plater()->update_project_dirty_from_presets();
|
||||
wxPostEvent(parent, SimpleEvent(EVT_SCHEDULE_BACKGROUND_PROCESS, parent));
|
||||
}
|
||||
}));
|
||||
@ -2423,8 +2424,8 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
||||
|
||||
// show notification about temporarily installed presets
|
||||
if (!names.empty()) {
|
||||
std::string notif_text = into_u8(_L_PLURAL("The preset below was temporarily installed on active instance of PrusaSlicer",
|
||||
"The presets below were temporarily installed on active instance of PrusaSlicer", names.size())) + ":";
|
||||
std::string notif_text = into_u8(_L_PLURAL("The preset below was temporarily installed on the active instance of PrusaSlicer",
|
||||
"The presets below were temporarily installed on the active instance of PrusaSlicer", names.size())) + ":";
|
||||
for (std::string& name : names)
|
||||
notif_text += "\n - " + name;
|
||||
notification_manager->push_notification(NotificationType::CustomNotification,
|
||||
@ -2475,9 +2476,9 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
||||
MessageDialog(q, format_wxstr(_L_PLURAL(
|
||||
"Object size from file %s appears to be zero.\n"
|
||||
"This object has been removed from the model",
|
||||
"Objects size from file %s appear to be zero.\n"
|
||||
"Objects size from file %s appears to be zero.\n"
|
||||
"These objects have been removed from the model", deleted_objects), from_path(filename)) + "\n",
|
||||
_L("Object size is zero"), wxICON_INFORMATION | wxOK).ShowModal();
|
||||
_L("The size of the object is zero"), wxICON_INFORMATION | wxOK).ShowModal();
|
||||
}
|
||||
if (imperial_units)
|
||||
// Convert even if the object is big.
|
||||
@ -2491,9 +2492,9 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
||||
if (answer_convert_from_meters == wxOK_DEFAULT) {
|
||||
RichMessageDialog dlg(q, format_wxstr(_L_PLURAL(
|
||||
"The dimensions of the object from file %s seem to be defined in meters.\n"
|
||||
"The internal unit of PrusaSlicer are millimeters. Do you want to recalculate the dimensions of the object?",
|
||||
"The internal unit of PrusaSlicer is a millimeter. Do you want to recalculate the dimensions of the object?",
|
||||
"The dimensions of some objects from file %s seem to be defined in meters.\n"
|
||||
"The internal unit of PrusaSlicer are millimeters. Do you want to recalculate the dimensions of these objects?", model.objects.size()), from_path(filename)) + "\n",
|
||||
"The internal unit of PrusaSlicer is a millimeter. Do you want to recalculate the dimensions of these objects?", model.objects.size()), from_path(filename)) + "\n",
|
||||
_L("The object is too small"), wxICON_QUESTION | wxYES_NO);
|
||||
dlg.ShowCheckBox(_L("Apply to all the remaining small objects being loaded."));
|
||||
int answer = dlg.ShowModal();
|
||||
@ -2513,9 +2514,9 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
||||
if (answer_convert_from_imperial_units == wxOK_DEFAULT) {
|
||||
RichMessageDialog dlg(q, format_wxstr(_L_PLURAL(
|
||||
"The dimensions of the object from file %s seem to be defined in inches.\n"
|
||||
"The internal unit of PrusaSlicer are millimeters. Do you want to recalculate the dimensions of the object?",
|
||||
"The internal unit of PrusaSlicer is a millimeter. Do you want to recalculate the dimensions of the object?",
|
||||
"The dimensions of some objects from file %s seem to be defined in inches.\n"
|
||||
"The internal unit of PrusaSlicer are millimeters. Do you want to recalculate the dimensions of these objects?", model.objects.size()), from_path(filename)) + "\n",
|
||||
"The internal unit of PrusaSlicer is a millimeter. Do you want to recalculate the dimensions of these objects?", model.objects.size()), from_path(filename)) + "\n",
|
||||
_L("The object is too small"), wxICON_QUESTION | wxYES_NO);
|
||||
dlg.ShowCheckBox(_L("Apply to all the remaining small objects being loaded."));
|
||||
int answer = dlg.ShowModal();
|
||||
|
@ -218,7 +218,7 @@ void PreferencesDialog::build(size_t selected_tab)
|
||||
|
||||
m_optgroup_general->append_separator();
|
||||
|
||||
def.label = L("Ask to save unsaved changes when closing the application or when loading a new project.");
|
||||
def.label = L("Ask to save unsaved changes when closing the application or when loading a new project");
|
||||
def.type = coBool;
|
||||
def.tooltip = L("Always ask for unsaved changes, when: \n"
|
||||
"- Closing PrusaSlicer while some presets are modified,\n"
|
||||
|
@ -39,9 +39,8 @@ static const char *CONFIG_KEY_PRINT = "printhost_print";
|
||||
static const char *CONFIG_KEY_GROUP = "printhost_group";
|
||||
|
||||
PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, bool can_start_print, const wxArrayString &groups)
|
||||
: MsgDialog(static_cast<wxWindow*>(wxGetApp().mainframe), _L("Send G-Code to printer host"), _L("Upload to Printer Host with the following filename:"), wxOK | wxCANCEL)
|
||||
: MsgDialog(static_cast<wxWindow*>(wxGetApp().mainframe), _L("Send G-Code to printer host"), _L("Upload to Printer Host with the following filename:"))
|
||||
, txt_filename(new wxTextCtrl(this, wxID_ANY))
|
||||
, box_print(can_start_print ? new wxCheckBox(this, wxID_ANY, _L("Start printing after upload")) : nullptr)
|
||||
, combo_groups(!groups.IsEmpty() ? new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, groups, wxCB_READONLY) : nullptr)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
@ -55,10 +54,6 @@ PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, bool can_start_pr
|
||||
content_sizer->Add(txt_filename, 0, wxEXPAND);
|
||||
content_sizer->Add(label_dir_hint);
|
||||
content_sizer->AddSpacer(VERT_SPACING);
|
||||
if (box_print != nullptr) {
|
||||
content_sizer->Add(box_print, 0, wxBOTTOM, 2*VERT_SPACING);
|
||||
box_print->SetValue(app_config->get("recent", CONFIG_KEY_PRINT) == "1");
|
||||
}
|
||||
|
||||
if (combo_groups != nullptr) {
|
||||
// Repetier specific: Show a selection of file groups.
|
||||
@ -84,18 +79,37 @@ PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, bool can_start_pr
|
||||
|
||||
wxString suffix = recent_path.substr(recent_path.find_last_of('.'));
|
||||
|
||||
static_cast<wxButton*>(FindWindowById(wxID_OK, this))->Bind(wxEVT_BUTTON, [this, suffix](wxCommandEvent&) {
|
||||
wxString path = txt_filename->GetValue();
|
||||
// .gcode suffix control
|
||||
if (!path.Lower().EndsWith(suffix.Lower()))
|
||||
{
|
||||
MessageDialog msg_wingow(this, wxString::Format(_L("Upload filename doesn't end with \"%s\". Do you wish to continue?"), suffix), wxString(SLIC3R_APP_NAME), wxYES | wxNO);
|
||||
if (msg_wingow.ShowModal() == wxID_NO)
|
||||
return;
|
||||
}
|
||||
EndDialog(wxID_OK);
|
||||
});
|
||||
if (can_start_print) {
|
||||
auto* btn_print = add_button(wxID_YES, false, _L("Upload and Print"));
|
||||
btn_print->Bind(wxEVT_BUTTON, [this, suffix](wxCommandEvent&) {
|
||||
wxString path = txt_filename->GetValue();
|
||||
// .gcode suffix control
|
||||
if (!path.Lower().EndsWith(suffix.Lower()))
|
||||
{
|
||||
MessageDialog msg_wingow(this, wxString::Format(_L("Upload filename doesn't end with \"%s\". Do you wish to continue?"), suffix), wxString(SLIC3R_APP_NAME), wxYES | wxNO);
|
||||
if (msg_wingow.ShowModal() == wxID_NO)
|
||||
return;
|
||||
}
|
||||
start_print_selected = true;
|
||||
EndDialog(wxID_OK);
|
||||
});
|
||||
}
|
||||
add_button(wxID_CANCEL);
|
||||
|
||||
if (auto* btn_ok = get_button(wxID_NO); btn_ok != NULL) {
|
||||
btn_ok->SetLabel(_L("Upload"));
|
||||
btn_ok->Bind(wxEVT_BUTTON, [this, suffix](wxCommandEvent&) {
|
||||
wxString path = txt_filename->GetValue();
|
||||
// .gcode suffix control
|
||||
if (!path.Lower().EndsWith(suffix.Lower()))
|
||||
{
|
||||
MessageDialog msg_wingow(this, wxString::Format(_L("Upload filename doesn't end with \"%s\". Do you wish to continue?"), suffix), wxString(SLIC3R_APP_NAME), wxYES | wxNO);
|
||||
if (msg_wingow.ShowModal() == wxID_NO)
|
||||
return;
|
||||
}
|
||||
EndDialog(wxID_OK);
|
||||
});
|
||||
}
|
||||
finalize();
|
||||
|
||||
#ifdef __linux__
|
||||
@ -125,7 +139,7 @@ fs::path PrintHostSendDialog::filename() const
|
||||
|
||||
bool PrintHostSendDialog::start_print() const
|
||||
{
|
||||
return box_print != nullptr ? box_print->GetValue() : false;
|
||||
return start_print_selected;
|
||||
}
|
||||
|
||||
std::string PrintHostSendDialog::group() const
|
||||
|
@ -36,8 +36,8 @@ public:
|
||||
virtual void EndModal(int ret) override;
|
||||
private:
|
||||
wxTextCtrl *txt_filename;
|
||||
wxCheckBox *box_print;
|
||||
wxComboBox *combo_groups;
|
||||
bool start_print_selected { false };
|
||||
};
|
||||
|
||||
|
||||
|
@ -26,12 +26,14 @@ void ProjectDirtyStateManager::update_from_presets()
|
||||
{
|
||||
m_presets_dirty = false;
|
||||
// check switching of the presets only for exist/loaded project, but not for new
|
||||
if (!wxGetApp().plater()->get_project_filename().IsEmpty()) {
|
||||
for (const auto& [type, name] : wxGetApp().get_selected_presets())
|
||||
GUI_App &app = wxGetApp();
|
||||
if (!app.plater()->get_project_filename().IsEmpty()) {
|
||||
for (const auto& [type, name] : app.get_selected_presets())
|
||||
m_presets_dirty |= !m_initial_presets[type].empty() && m_initial_presets[type] != name;
|
||||
}
|
||||
m_presets_dirty |= wxGetApp().has_unsaved_preset_changes();
|
||||
wxGetApp().mainframe->update_title();
|
||||
m_presets_dirty |= app.has_unsaved_preset_changes();
|
||||
m_project_config_dirty = m_initial_project_config != app.preset_bundle->project_config;
|
||||
app.mainframe->update_title();
|
||||
}
|
||||
|
||||
void ProjectDirtyStateManager::reset_after_save()
|
||||
@ -39,14 +41,17 @@ void ProjectDirtyStateManager::reset_after_save()
|
||||
this->reset_initial_presets();
|
||||
m_plater_dirty = false;
|
||||
m_presets_dirty = false;
|
||||
m_project_config_dirty = false;
|
||||
wxGetApp().mainframe->update_title();
|
||||
}
|
||||
|
||||
void ProjectDirtyStateManager::reset_initial_presets()
|
||||
{
|
||||
m_initial_presets.fill(std::string{});
|
||||
for (const auto& [type, name] : wxGetApp().get_selected_presets())
|
||||
GUI_App &app = wxGetApp();
|
||||
for (const auto& [type, name] : app.get_selected_presets())
|
||||
m_initial_presets[type] = name;
|
||||
m_initial_project_config = app.preset_bundle->project_config;
|
||||
}
|
||||
|
||||
#if ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW
|
||||
|
@ -14,7 +14,7 @@ public:
|
||||
void reset_after_save();
|
||||
void reset_initial_presets();
|
||||
|
||||
bool is_dirty() const { return m_plater_dirty || m_presets_dirty; }
|
||||
bool is_dirty() const { return m_plater_dirty || m_project_config_dirty || m_presets_dirty; }
|
||||
|
||||
#if ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW
|
||||
void render_debug_window() const;
|
||||
@ -25,8 +25,11 @@ private:
|
||||
bool m_plater_dirty { false };
|
||||
// Do the presets indicate the project is dirty?
|
||||
bool m_presets_dirty { false };
|
||||
// Is the project config dirty?
|
||||
bool m_project_config_dirty { false };
|
||||
// Keeps track of preset names selected at the time of last project save.
|
||||
std::array<std::string, Preset::TYPE_COUNT> m_initial_presets;
|
||||
DynamicPrintConfig m_initial_project_config;
|
||||
};
|
||||
|
||||
} // namespace GUI
|
||||
|
@ -1478,7 +1478,7 @@ void TabPrint::build()
|
||||
optgroup = page->new_optgroup(L("Advanced"));
|
||||
optgroup->append_single_option_line("seam_position", category_path + "seam-position");
|
||||
optgroup->append_single_option_line("external_perimeters_first", category_path + "external-perimeters-first");
|
||||
optgroup->append_single_option_line("gap_fill_enabled");
|
||||
optgroup->append_single_option_line("gap_fill_enabled", category_path + "fill-gaps");
|
||||
|
||||
optgroup = page->new_optgroup(L("Fuzzy skin (experimental)"));
|
||||
category_path = "fuzzy-skin_246186/#";
|
||||
@ -1497,12 +1497,14 @@ void TabPrint::build()
|
||||
optgroup->append_single_option_line("bottom_fill_pattern", category_path + "bottom-fill-pattern");
|
||||
|
||||
optgroup = page->new_optgroup(L("Ironing"));
|
||||
optgroup->append_single_option_line("ironing");
|
||||
optgroup->append_single_option_line("ironing_type");
|
||||
optgroup->append_single_option_line("ironing_flowrate");
|
||||
optgroup->append_single_option_line("ironing_spacing");
|
||||
category_path = "ironing_177488#";
|
||||
optgroup->append_single_option_line("ironing", category_path);
|
||||
optgroup->append_single_option_line("ironing_type", category_path + "ironing-type");
|
||||
optgroup->append_single_option_line("ironing_flowrate", category_path + "flow-rate");
|
||||
optgroup->append_single_option_line("ironing_spacing", category_path + "spacing-between-ironing-passes");
|
||||
|
||||
optgroup = page->new_optgroup(L("Reducing printing time"));
|
||||
category_path = "infill_42#";
|
||||
optgroup->append_single_option_line("infill_every_layers", category_path + "combine-infill-every-x-layers");
|
||||
optgroup->append_single_option_line("infill_only_where_needed", category_path + "only-infill-where-needed");
|
||||
|
||||
@ -1540,7 +1542,7 @@ void TabPrint::build()
|
||||
|
||||
optgroup = page->new_optgroup(L("Raft"));
|
||||
optgroup->append_single_option_line("raft_layers", category_path + "raft-layers");
|
||||
optgroup->append_single_option_line("raft_contact_distance");
|
||||
optgroup->append_single_option_line("raft_contact_distance", category_path + "raft-layers");
|
||||
optgroup->append_single_option_line("raft_expansion");
|
||||
|
||||
optgroup = page->new_optgroup(L("Options for support material and raft"));
|
||||
@ -3650,8 +3652,8 @@ void Tab::delete_preset()
|
||||
for (const std::string& printer : ph_printers)
|
||||
msg += "\n \"" + from_u8(printer) + "\",";
|
||||
msg.RemoveLast();
|
||||
msg += "\n" + _L_PLURAL("Note, that selected preset will be deleted from this printer too.",
|
||||
"Note, that selected preset will be deleted from these printers too.", ph_printers.size()) + "\n\n";
|
||||
msg += "\n" + _L_PLURAL("Note, that the selected preset will be deleted from this printer too.",
|
||||
"Note, that the selected preset will be deleted from these printers too.", ph_printers.size()) + "\n\n";
|
||||
}
|
||||
|
||||
if (!ph_printers_only.empty()) {
|
||||
@ -3660,8 +3662,8 @@ void Tab::delete_preset()
|
||||
for (const std::string& printer : ph_printers_only)
|
||||
msg += "\n \"" + from_u8(printer) + "\",";
|
||||
msg.RemoveLast();
|
||||
msg += "\n" + _L_PLURAL("Note, that this printer will be deleted after deleting of the selected preset.",
|
||||
"Note, that these printers will be deleted after deleting of the selected preset.", ph_printers_only.size()) + "\n\n";
|
||||
msg += "\n" + _L_PLURAL("Note, that this printer will be deleted after deleting the selected preset.",
|
||||
"Note, that these printers will be deleted after deleting the selected preset.", ph_printers_only.size()) + "\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,7 @@ MsgUpdateSlic3r::MsgUpdateSlic3r(const Semver &ver_current, const Semver &ver_on
|
||||
content_sizer->Add(cbox);
|
||||
content_sizer->AddSpacer(VERT_SPACING);
|
||||
|
||||
Fit();
|
||||
finalize();
|
||||
}
|
||||
|
||||
MsgUpdateSlic3r::~MsgUpdateSlic3r() {}
|
||||
@ -133,12 +133,12 @@ MsgUpdateConfig::MsgUpdateConfig(const std::vector<Update> &updates, bool force_
|
||||
content_sizer->Add(versions);
|
||||
content_sizer->AddSpacer(2*VERT_SPACING);
|
||||
|
||||
add_btn(wxID_OK, true, force_before_wizard ? _L("Install") : "OK");
|
||||
add_button(wxID_OK, true, force_before_wizard ? _L("Install") : "OK");
|
||||
if (force_before_wizard) {
|
||||
add_btn(wxID_CLOSE, false, _L("Don't install"));
|
||||
static_cast<wxButton*>(FindWindowById(wxID_CLOSE, this))->Bind(wxEVT_BUTTON, [this](const wxCommandEvent&) { this->EndModal(wxID_CLOSE); });
|
||||
auto* btn = add_button(wxID_CLOSE, false, _L("Don't install"));
|
||||
btn->Bind(wxEVT_BUTTON, [this](const wxCommandEvent&) { this->EndModal(wxID_CLOSE); });
|
||||
}
|
||||
add_btn(wxID_CANCEL);
|
||||
add_button(wxID_CANCEL);
|
||||
|
||||
finalize();
|
||||
}
|
||||
@ -190,9 +190,9 @@ MsgUpdateForced::MsgUpdateForced(const std::vector<Update>& updates) :
|
||||
content_sizer->Add(versions);
|
||||
content_sizer->AddSpacer(2 * VERT_SPACING);
|
||||
|
||||
add_btn(wxID_EXIT, false, wxString::Format(_L("Exit %s"), SLIC3R_APP_NAME));
|
||||
add_button(wxID_EXIT, false, wxString::Format(_L("Exit %s"), SLIC3R_APP_NAME));
|
||||
for (auto ID : { wxID_EXIT, wxID_OK })
|
||||
static_cast<wxButton*>(FindWindowById(ID, this))->Bind(wxEVT_BUTTON, [this](const wxCommandEvent& evt) { this->EndModal(evt.GetId()); });
|
||||
get_button(ID)->Bind(wxEVT_BUTTON, [this](const wxCommandEvent& evt) { this->EndModal(evt.GetId()); });
|
||||
|
||||
finalize();
|
||||
}
|
||||
@ -236,11 +236,11 @@ MsgDataIncompatible::MsgDataIncompatible(const std::unordered_map<std::string, w
|
||||
content_sizer->Add(versions);
|
||||
content_sizer->AddSpacer(2*VERT_SPACING);
|
||||
|
||||
add_btn(wxID_REPLACE, true, _L("Re-configure"));
|
||||
add_btn(wxID_EXIT, false, wxString::Format(_L("Exit %s"), SLIC3R_APP_NAME));
|
||||
add_button(wxID_REPLACE, true, _L("Re-configure"));
|
||||
add_button(wxID_EXIT, false, wxString::Format(_L("Exit %s"), SLIC3R_APP_NAME));
|
||||
|
||||
for (auto ID : {wxID_EXIT, wxID_REPLACE})
|
||||
static_cast<wxButton*>(FindWindowById(ID, this))->Bind(wxEVT_BUTTON, [this](const wxCommandEvent& evt) { this->EndModal(evt.GetId()); });
|
||||
get_button(ID)->Bind(wxEVT_BUTTON, [this](const wxCommandEvent& evt) { this->EndModal(evt.GetId()); });
|
||||
|
||||
finalize();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user