Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Matena <lukasmatena@seznam.cz>2021-12-14 17:10:42 +0300
committerLukas Matena <lukasmatena@seznam.cz>2021-12-14 17:10:42 +0300
commit7f9e519baf212cbae4b9a72d40a9071aa1ddf462 (patch)
tree6857fed15a817ad9d422549309fdb29c94f5e640 /src/slic3r/GUI
parent6204d107eef946f42fdac8dcc4e2d38e700aac49 (diff)
parente2ac37e7178e994680aaf9e894619c4cfb2e92a0 (diff)
Merge branch 'master' into dev
Diffstat (limited to 'src/slic3r/GUI')
-rw-r--r--src/slic3r/GUI/BedShapeDialog.cpp4
-rw-r--r--src/slic3r/GUI/BitmapComboBox.cpp4
-rw-r--r--src/slic3r/GUI/ConfigManipulation.cpp7
-rw-r--r--src/slic3r/GUI/GCodeViewer.cpp41
-rw-r--r--src/slic3r/GUI/GUI.cpp4
-rw-r--r--src/slic3r/GUI/GUI_App.cpp68
-rw-r--r--src/slic3r/GUI/GUI_ObjectList.cpp13
-rw-r--r--src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp2
-rw-r--r--src/slic3r/GUI/MainFrame.cpp54
-rw-r--r--src/slic3r/GUI/MsgDialog.cpp28
-rw-r--r--src/slic3r/GUI/MsgDialog.hpp10
-rw-r--r--src/slic3r/GUI/OptionsGroup.hpp2
-rw-r--r--src/slic3r/GUI/Plater.cpp66
-rw-r--r--src/slic3r/GUI/Preferences.cpp4
-rw-r--r--src/slic3r/GUI/Selection.cpp3
-rw-r--r--src/slic3r/GUI/Tab.cpp15
-rw-r--r--src/slic3r/GUI/UnsavedChangesDialog.cpp16
-rw-r--r--src/slic3r/GUI/UpdateDialogs.cpp2
18 files changed, 194 insertions, 149 deletions
diff --git a/src/slic3r/GUI/BedShapeDialog.cpp b/src/slic3r/GUI/BedShapeDialog.cpp
index 2d46a5228..246c8b63e 100644
--- a/src/slic3r/GUI/BedShapeDialog.cpp
+++ b/src/slic3r/GUI/BedShapeDialog.cpp
@@ -109,7 +109,7 @@ wxString BedShape::get_full_name_with_params()
default:
// rectangle, convex, concave...
out += "\n" + _(get_option_label(Parameter::RectSize)) + ": [" + ConfigOptionPoint(to_2d(m_build_volume.bounding_volume().size())).serialize() + "]";
- out += "\n" + _(get_option_label(Parameter::RectOrigin)) + ": [" + ConfigOptionPoint(to_2d(m_build_volume.bounding_volume().min)).serialize() + "]";
+ out += "\n" + _(get_option_label(Parameter::RectOrigin)) + ": [" + ConfigOptionPoint(- to_2d(m_build_volume.bounding_volume().min)).serialize() + "]";
break;
}
return out;
@@ -124,7 +124,7 @@ void BedShape::apply_optgroup_values(ConfigOptionsGroupShp optgroup)
default:
// rectangle, convex, concave...
optgroup->set_value("rect_size" , new ConfigOptionPoints{ to_2d(m_build_volume.bounding_volume().size()) });
- optgroup->set_value("rect_origin" , new ConfigOptionPoints{ to_2d(m_build_volume.bounding_volume().min) });
+ optgroup->set_value("rect_origin" , new ConfigOptionPoints{ - to_2d(m_build_volume.bounding_volume().min) });
}
}
diff --git a/src/slic3r/GUI/BitmapComboBox.cpp b/src/slic3r/GUI/BitmapComboBox.cpp
index 24bc8dcfd..3396c627b 100644
--- a/src/slic3r/GUI/BitmapComboBox.cpp
+++ b/src/slic3r/GUI/BitmapComboBox.cpp
@@ -254,8 +254,8 @@ void BitmapComboBox::DrawBackground_(wxDC& dc, const wxRect& rect, int WXUNUSED(
dc.SetTextForeground(flags & ODCB_PAINTING_DISABLED ? wxColour(108,108,108) : wxGetApp().get_label_clr_default());
wxColour selCol = flags & ODCB_PAINTING_DISABLED ?
-#ifdef _MSW_DAEK_MODE
- wxRGBToColour(NppDarkMode::InvertLightnessSofter(NppDarkMode::GetBackgroundColor())) :
+#ifdef _MSW_DARK_MODE
+ wxRGBToColour(NppDarkMode::GetSofterBackgroundColor()) :
#else
wxGetApp().get_highlight_default_clr() :
#endif
diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp
index fe108b1a6..8defc4554 100644
--- a/src/slic3r/GUI/ConfigManipulation.cpp
+++ b/src/slic3r/GUI/ConfigManipulation.cpp
@@ -155,7 +155,8 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
apply(config, &new_conf);
}
- if (config->opt_bool("support_material")) {
+ // Check "support_material" and "overhangs" relations only on global settings level
+ if (is_global_config && config->opt_bool("support_material")) {
// Ask only once.
if (!m_support_material_overhangs_queried) {
m_support_material_overhangs_queried = true;
@@ -164,10 +165,10 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
"- Detect bridging perimeters"));
if (is_global_config)
msg_text += "\n\n" + _(L("Shall I adjust those settings for supports?"));
- MessageDialog dialog(m_msg_dlg_parent, msg_text, _L("Support Generator"), wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK));
+ MessageDialog dialog(m_msg_dlg_parent, msg_text, _L("Support Generator"), wxICON_WARNING | wxYES | wxNO);
DynamicPrintConfig new_conf = *config;
auto answer = dialog.ShowModal();
- if (!is_global_config || answer == wxID_YES) {
+ if (answer == wxID_YES) {
// Enable "detect bridging perimeters".
new_conf.set_key_value("overhangs", new ConfigOptionBool(true));
}
diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp
index 574ba6ec5..6b9ba5da9 100644
--- a/src/slic3r/GUI/GCodeViewer.cpp
+++ b/src/slic3r/GUI/GCodeViewer.cpp
@@ -581,14 +581,14 @@ void GCodeViewer::init()
case EMoveType::Retract:
case EMoveType::Unretract:
case EMoveType::Seam: {
- if (wxGetApp().is_gl_version_greater_or_equal_to(3, 3)) {
- buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::InstancedModel;
- buffer.shader = "gouraud_light_instanced";
- buffer.model.model.init_from(diamond(16));
- buffer.model.color = option_color(type);
- buffer.model.instances.format = InstanceVBuffer::EFormat::InstancedModel;
- }
- else {
+// if (wxGetApp().is_gl_version_greater_or_equal_to(3, 3)) {
+// buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::InstancedModel;
+// buffer.shader = "gouraud_light_instanced";
+// buffer.model.model.init_from(diamond(16));
+// buffer.model.color = option_color(type);
+// buffer.model.instances.format = InstanceVBuffer::EFormat::InstancedModel;
+// }
+// else {
buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::BatchedModel;
buffer.vertices.format = VBuffer::EFormat::PositionNormal3;
buffer.shader = "gouraud_light";
@@ -596,7 +596,7 @@ void GCodeViewer::init()
buffer.model.data = diamond(16);
buffer.model.color = option_color(type);
buffer.model.instances.format = InstanceVBuffer::EFormat::BatchedModel;
- }
+// }
break;
}
case EMoveType::Wipe:
@@ -608,7 +608,7 @@ void GCodeViewer::init()
}
case EMoveType::Travel: {
buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Line;
- buffer.vertices.format = VBuffer::EFormat::PositionNormal1;
+ buffer.vertices.format = VBuffer::EFormat::PositionNormal3;
buffer.shader = "toolpaths_lines";
break;
}
@@ -1140,15 +1140,19 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
// format data into the buffers to be rendered as lines
auto add_vertices_as_line = [](const GCodeProcessorResult::MoveVertex& prev, const GCodeProcessorResult::MoveVertex& curr, VertexBuffer& vertices) {
// x component of the normal to the current segment (the normal is parallel to the XY plane)
- const float normal_x = (curr.position - prev.position).normalized().y();
+ const Vec3f dir = (curr.position - prev.position).normalized();
+ Vec3f normal(dir.y(), -dir.x(), 0.0);
+ normal.normalize();
- auto add_vertex = [&vertices, normal_x](const GCodeProcessorResult::MoveVertex& vertex) {
+ auto add_vertex = [&vertices, &normal](const GCodeProcessorResult::MoveVertex& vertex) {
// add position
vertices.push_back(vertex.position.x());
vertices.push_back(vertex.position.y());
vertices.push_back(vertex.position.z());
- // add normal x component
- vertices.push_back(normal_x);
+ // add normal
+ vertices.push_back(normal.x());
+ vertices.push_back(normal.y());
+ vertices.push_back(normal.z());
};
// add previous vertex
@@ -2654,6 +2658,9 @@ void GCodeViewer::render_toolpaths()
for (auto it = it_path; it != it_end && it_path->ibuffer_id == it->ibuffer_id; ++it) {
const RenderPath& path = *it;
+ // Some OpenGL drivers crash on empty glMultiDrawElements, see GH #7415.
+ assert(! path.sizes.empty());
+ assert(! path.offsets.empty());
glsafe(::glUniform4fv(uniform_color, 1, static_cast<const GLfloat*>(path.color.data())));
glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size()));
#if ENABLE_GCODE_VIEWER_STATISTICS
@@ -2675,6 +2682,9 @@ void GCodeViewer::render_toolpaths()
](std::vector<RenderPath>::iterator it_path, std::vector<RenderPath>::iterator it_end, GLShaderProgram& shader, int uniform_color) {
for (auto it = it_path; it != it_end && it_path->ibuffer_id == it->ibuffer_id; ++it) {
const RenderPath& path = *it;
+ // Some OpenGL drivers crash on empty glMultiDrawElements, see GH #7415.
+ assert(! path.sizes.empty());
+ assert(! path.offsets.empty());
glsafe(::glUniform4fv(uniform_color, 1, static_cast<const GLfloat*>(path.color.data())));
glsafe(::glMultiDrawElements(GL_LINES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size()));
#if ENABLE_GCODE_VIEWER_STATISTICS
@@ -2690,6 +2700,9 @@ void GCodeViewer::render_toolpaths()
](std::vector<RenderPath>::iterator it_path, std::vector<RenderPath>::iterator it_end, GLShaderProgram& shader, int uniform_color) {
for (auto it = it_path; it != it_end && it_path->ibuffer_id == it->ibuffer_id; ++it) {
const RenderPath& path = *it;
+ // Some OpenGL drivers crash on empty glMultiDrawElements, see GH #7415.
+ assert(! path.sizes.empty());
+ assert(! path.offsets.empty());
glsafe(::glUniform4fv(uniform_color, 1, static_cast<const GLfloat*>(path.color.data())));
glsafe(::glMultiDrawElements(GL_TRIANGLES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size()));
#if ENABLE_GCODE_VIEWER_STATISTICS
diff --git a/src/slic3r/GUI/GUI.cpp b/src/slic3r/GUI/GUI.cpp
index 8fe951292..fb7fa00f1 100644
--- a/src/slic3r/GUI/GUI.cpp
+++ b/src/slic3r/GUI/GUI.cpp
@@ -352,7 +352,7 @@ void show_substitutions_info(const PresetsConfigSubstitutions& presets_config_su
add_config_substitutions(substitution.substitutions, changes);
}
- InfoDialog msg(nullptr, _L("Configuration bundle was loaded, however some configuration values were not recognized."), substitution_message(changes));
+ InfoDialog msg(nullptr, _L("Configuration bundle was loaded, however some configuration values were not recognized."), substitution_message(changes), true);
msg.ShowModal();
}
@@ -363,7 +363,7 @@ void show_substitutions_info(const ConfigSubstitutions& config_substitutions, co
InfoDialog msg(nullptr,
format_wxstr(_L("Configuration file \"%1%\" was loaded, however some configuration values were not recognized."), from_u8(filename)),
- substitution_message(changes));
+ substitution_message(changes), true);
msg.ShowModal();
}
diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp
index 0c40000e5..e4078c9c1 100644
--- a/src/slic3r/GUI/GUI_App.cpp
+++ b/src/slic3r/GUI/GUI_App.cpp
@@ -948,24 +948,31 @@ bool GUI_App::check_older_app_config(Semver current_version, bool backup)
return false;
BOOST_LOG_TRIVIAL(info) << "last app config file used: " << m_older_data_dir_path;
// ask about using older data folder
- RichMessageDialog msg(nullptr, backup ?
- wxString::Format(_L(
- "Current configuration folder: %s"
- "\n\n%s found another configuration for version %s."
- "\nIt is found at %s."
- "\n\nDo you wish to copy and use the configuration file for version %s (overwriting any file with the same name)? A backup of your current configuration will be created."
- "\nIf you select no, you will continue with the configuration file for version %s (may not be fully compatible).")
- , current_version.to_string(), SLIC3R_APP_NAME, last_semver.to_string(), m_older_data_dir_path, last_semver.to_string(), current_version.to_string())
- : wxString::Format(_L(
- "%s found another configuration for version %s."
- "\nIt is found at %s."
- "\nThere is no configuration file in current configuration folder."
- "\n\nDo you wish to copy and use the configuration file for version %s?"
- "\nIf you select no, you will start with clean installation with configuration wizard.")
- , SLIC3R_APP_NAME, last_semver.to_string(), m_older_data_dir_path, last_semver.to_string())
- , _L("PrusaSlicer")
- , wxYES_NO
- , wxString::Format(_L("Load configuration from version %s?"), last_semver.to_string()));
+
+ InfoDialog msg(nullptr
+ , format_wxstr(_L("You are opening %1% version %2%."), SLIC3R_APP_NAME, SLIC3R_VERSION)
+ , backup ?
+ format_wxstr(_L(
+ "The active configuration was created by <b>%1% %2%</b>,"
+ "\nwhile a newer configuration was found in <b>%3%</b>"
+ "\ncreated by <b>%1% %4%</b>."
+ "\n\nShall the newer configuration be imported?"
+ "\nIf so, your active configuration will be backed up before importing the new configuration."
+ )
+ , SLIC3R_APP_NAME, current_version.to_string(), m_older_data_dir_path, last_semver.to_string())
+ : format_wxstr(_L(
+ "An existing configuration was found in <b>%3%</b>"
+ "\ncreated by <b>%1% %2%</b>."
+ "\n\nShall this configuration be imported?"
+ )
+ , SLIC3R_APP_NAME, last_semver.to_string(), m_older_data_dir_path)
+ , true, wxYES_NO);
+
+ if (backup) {
+ msg.SetButtonLabel(wxID_YES, _L("Import"));
+ msg.SetButtonLabel(wxID_NO, _L("Don't import"));
+ }
+
if (msg.ShowModal() == wxID_YES) {
std::string snapshot_id;
if (backup) {
@@ -1033,6 +1040,9 @@ bool GUI_App::OnInit()
bool GUI_App::on_init_inner()
{
+ // Set initialization of image handlers before any UI actions - See GH issue #7469
+ wxInitAllImageHandlers();
+
#if defined(_WIN32) && ! defined(_WIN64)
// Win32 32bit build.
if (wxPlatformInfo::Get().GetArchName().substr(0, 2) == "64") {
@@ -1096,6 +1106,14 @@ bool GUI_App::on_init_inner()
}
}
+ // Set language and color mode before check_older_app_config() call
+
+ // If load_language() fails, the application closes.
+ load_language(wxString(), true);
+#ifdef _MSW_DARK_MODE
+ NppDarkMode::InitDarkMode(app_config->get("dark_color_mode") == "1", app_config->get("sys_menu_enabled") == "1");
+#endif
+
if (m_last_config_version) {
if (*m_last_config_version < *Semver::parse(SLIC3R_VERSION))
check_older_app_config(*m_last_config_version, true);
@@ -1106,14 +1124,6 @@ bool GUI_App::on_init_inner()
app_config->set("version", SLIC3R_VERSION);
app_config->save();
- // If load_language() fails, the application closes.
- load_language(wxString(), true);
-
- wxInitAllImageHandlers();
-
-#ifdef _MSW_DARK_MODE
- NppDarkMode::InitDarkMode(app_config->get("dark_color_mode") == "1", app_config->get("sys_menu_enabled") == "1");
-#endif
SplashScreen* scrn = nullptr;
if (app_config->get("show_splash_screen") == "1") {
// make a bitmap with dark grey banner on the left side
@@ -1137,8 +1147,6 @@ bool GUI_App::on_init_inner()
scrn->SetText(_L("Loading configuration")+ dots);
}
-
-
preset_bundle = new PresetBundle();
// just checking for existence of Slic3r::data_dir is not enough : it may be an empty directory
@@ -2160,9 +2168,9 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
local_menu->Append(config_id_base + ConfigMenuLanguage, _L("&Language"));
if (is_editor()) {
local_menu->AppendSeparator();
- local_menu->Append(config_id_base + ConfigMenuFlashFirmware, _L("Flash printer &firmware"), _L("Upload a firmware image into an Arduino based printer"));
+ local_menu->Append(config_id_base + ConfigMenuFlashFirmware, _L("Flash Printer &Firmware"), _L("Upload a firmware image into an Arduino based printer"));
// TODO: for when we're able to flash dictionaries
- // local_menu->Append(config_id_base + FirmwareMenuDict, _L("Flash language file"), _L("Upload a language dictionary file into a Prusa printer"));
+ // local_menu->Append(config_id_base + FirmwareMenuDict, _L("Flash Language File"), _L("Upload a language dictionary file into a Prusa printer"));
}
local_menu->Bind(wxEVT_MENU, [this, config_id_base](wxEvent &event) {
diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp
index f4d27b0b2..160999db3 100644
--- a/src/slic3r/GUI/GUI_ObjectList.cpp
+++ b/src/slic3r/GUI/GUI_ObjectList.cpp
@@ -349,7 +349,8 @@ void ObjectList::get_selection_indexes(std::vector<int>& obj_idxs, std::vector<i
{
wxDataViewItemArray sels;
GetSelections(sels);
- assert(!sels.IsEmpty());
+ if (sels.IsEmpty())
+ return;
if ( m_objects_model->GetItemType(sels[0]) & itVolume ||
(sels.Count()==1 && m_objects_model->GetItemType(m_objects_model->GetParent(sels[0])) & itVolume) ) {
@@ -424,7 +425,7 @@ MeshErrorsInfo ObjectList::get_mesh_errors_info(const int obj_idx, const int vol
if (!stats.manifold()) {
remaining_info = format_wxstr(_L_PLURAL("%1$d open edge", "%1$d open edges", stats.open_edges), stats.open_edges);
- tooltip += _L("Remaning errors") + ":\n";
+ tooltip += _L("Remaining errors") + ":\n";
tooltip += "\t" + format_wxstr(_L_PLURAL("%1$d open edge", "%1$d open edges", stats.open_edges), stats.open_edges) + "\n";
}
@@ -1556,7 +1557,7 @@ void ObjectList::load_modifier(ModelObject& model_object, std::vector<ModelVolum
for (auto object : model.objects) {
if (model_object.origin_translation != Vec3d::Zero()) {
object->center_around_origin();
- Vec3d delta = model_object.origin_translation - object->origin_translation;
+ const Vec3d delta = model_object.origin_translation - object->origin_translation;
for (auto volume : object->volumes) {
volume->translate(delta);
}
@@ -1570,6 +1571,12 @@ void ObjectList::load_modifier(ModelObject& model_object, std::vector<ModelVolum
new_volume->name = boost::filesystem::path(input_file).filename().string();
// set a default extruder value, since user can't add it manually
new_volume->config.set_key_value("extruder", new ConfigOptionInt(0));
+ // update source data
+ new_volume->source.input_file = input_file;
+ new_volume->source.object_idx = obj_idx;
+ new_volume->source.volume_idx = int(model_object.volumes.size()) - 1;
+ if (model.objects.size() == 1 && model.objects.front()->volumes.size() == 1)
+ new_volume->source.mesh_offset = model.objects.front()->volumes.front()->source.mesh_offset;
if (from_galery) {
// Transform the new modifier to be aligned with the print bed.
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp
index 260e46563..fa59d7646 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp
@@ -256,7 +256,7 @@ std::vector<std::vector<GLGizmoPainterBase::ProjectedMousePosition>> GLGizmoPain
const Camera &camera = wxGetApp().plater()->get_camera();
std::vector<ProjectedMousePosition> mesh_hit_points;
- mesh_hit_points.reserve(mouse_position.size());
+ mesh_hit_points.reserve(mouse_positions.size());
// In mesh_hit_points only the last item could have mesh_id == -1, any other items mustn't.
for (const Vec2d &mp : mouse_positions) {
diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp
index 8a9702c40..1e589e432 100644
--- a/src/slic3r/GUI/MainFrame.cpp
+++ b/src/slic3r/GUI/MainFrame.cpp
@@ -1094,7 +1094,7 @@ static wxMenu* generate_help_menu()
else
append_menu_item(helpMenu, wxID_ANY, wxString::Format(_L("&About %s"), GCODEVIEWER_APP_NAME), _L("Show about dialog"),
[](wxCommandEvent&) { Slic3r::GUI::about(); });
- append_menu_item(helpMenu, wxID_ANY, _L("Show Tip of the day"), _L("Opens Tip of the day notification in bottom right corner or shows another tip if already opened."),
+ append_menu_item(helpMenu, wxID_ANY, _L("Show Tip of the Day"), _L("Opens Tip of the day notification in bottom right corner or shows another tip if already opened."),
[](wxCommandEvent&) { wxGetApp().plater()->get_notification_manager()->push_hint_notification(false); });
helpMenu->AppendSeparator();
append_menu_item(helpMenu, wxID_ANY, _L("Keyboard Shortcuts") + sep + "&?", _L("Show the list of the keyboard shortcuts"),
@@ -1188,9 +1188,9 @@ void MainFrame::init_menubar_as_editor()
[this](wxCommandEvent&) { save_project(); }, "save", nullptr,
[this](){return m_plater != nullptr && can_save(); }, this);
#ifdef __APPLE__
- append_menu_item(fileMenu, wxID_ANY, _L("Save project &as") + dots + "\tCtrl+Shift+S", _L("Save current project file as"),
+ append_menu_item(fileMenu, wxID_ANY, _L("Save Project &as") + dots + "\tCtrl+Shift+S", _L("Save current project file as"),
#else
- append_menu_item(fileMenu, wxID_ANY, _L("Save project &as") + dots + "\tCtrl+Alt+S", _L("Save current project file as"),
+ append_menu_item(fileMenu, wxID_ANY, _L("Save Project &as") + dots + "\tCtrl+Alt+S", _L("Save current project file as"),
#endif // __APPLE__
[this](wxCommandEvent&) { save_project_as(); }, "save", nullptr,
[this](){return m_plater != nullptr && can_save_as(); }, this);
@@ -1202,11 +1202,11 @@ void MainFrame::init_menubar_as_editor()
[this](wxCommandEvent&) { if (m_plater) m_plater->add_model(); }, "import_plater", nullptr,
[this](){return m_plater != nullptr; }, this);
- append_menu_item(import_menu, wxID_ANY, _L("Import STL (imperial units)"), _L("Load an model saved with imperial units"),
+ append_menu_item(import_menu, wxID_ANY, _L("Import STL (Imperial Units)"), _L("Load an model saved with imperial units"),
[this](wxCommandEvent&) { if (m_plater) m_plater->add_model(true); }, "import_plater", nullptr,
[this](){return m_plater != nullptr; }, this);
- append_menu_item(import_menu, wxID_ANY, _L("Import SL1 / SL1S archive") + dots, _L("Load an SL1 / Sl1S archive"),
+ append_menu_item(import_menu, wxID_ANY, _L("Import SL1 / SL1S Archive") + dots, _L("Load an SL1 / Sl1S archive"),
[this](wxCommandEvent&) { if (m_plater) m_plater->import_sl1_archive(); }, "import_plater", nullptr,
[this](){return m_plater != nullptr && !m_plater->is_any_job_running(); }, this);
@@ -1214,7 +1214,7 @@ void MainFrame::init_menubar_as_editor()
append_menu_item(import_menu, wxID_ANY, _L("Import &Config") + dots + "\tCtrl+L", _L("Load exported configuration file"),
[this](wxCommandEvent&) { load_config_file(); }, "import_config", nullptr,
[]() {return true; }, this);
- append_menu_item(import_menu, wxID_ANY, _L("Import Config from &project") + dots +"\tCtrl+Alt+L", _L("Load configuration from project file"),
+ append_menu_item(import_menu, wxID_ANY, _L("Import Config from &Project") + dots +"\tCtrl+Alt+L", _L("Load configuration from project file"),
[this](wxCommandEvent&) { if (m_plater) m_plater->extract_config_from_project(); }, "import_config", nullptr,
[]() {return true; }, this);
import_menu->AppendSeparator();
@@ -1232,22 +1232,22 @@ void MainFrame::init_menubar_as_editor()
[this](wxCommandEvent&) { if (m_plater) m_plater->send_gcode(); }, "export_gcode", nullptr,
[this](){return can_send_gcode(); }, this);
m_changeable_menu_items.push_back(item_send_gcode);
- append_menu_item(export_menu, wxID_ANY, _L("Export G-code to SD card / Flash drive") + dots + "\tCtrl+U", _L("Export current plate as G-code to SD card / Flash drive"),
+ append_menu_item(export_menu, wxID_ANY, _L("Export G-code to SD Card / Flash Drive") + dots + "\tCtrl+U", _L("Export current plate as G-code to SD card / Flash drive"),
[this](wxCommandEvent&) { if (m_plater) m_plater->export_gcode(true); }, "export_to_sd", nullptr,
[this]() {return can_export_gcode_sd(); }, this);
export_menu->AppendSeparator();
- append_menu_item(export_menu, wxID_ANY, _L("Export plate as &STL") + dots, _L("Export current plate as STL"),
+ append_menu_item(export_menu, wxID_ANY, _L("Export Plate as &STL") + dots, _L("Export current plate as STL"),
[this](wxCommandEvent&) { if (m_plater) m_plater->export_stl(); }, "export_plater", nullptr,
[this](){return can_export_model(); }, this);
- append_menu_item(export_menu, wxID_ANY, _L("Export plate as STL &including supports") + dots, _L("Export current plate as STL including supports"),
+ append_menu_item(export_menu, wxID_ANY, _L("Export Plate as STL &Including Supports") + dots, _L("Export current plate as STL including supports"),
[this](wxCommandEvent&) { if (m_plater) m_plater->export_stl(true); }, "export_plater", nullptr,
[this](){return can_export_supports(); }, this);
// Deprecating AMF export. Let's wait for user feedback.
-// append_menu_item(export_menu, wxID_ANY, _L("Export plate as &AMF") + dots, _L("Export current plate as AMF"),
+// append_menu_item(export_menu, wxID_ANY, _L("Export Plate as &AMF") + dots, _L("Export current plate as AMF"),
// [this](wxCommandEvent&) { if (m_plater) m_plater->export_amf(); }, "export_plater", nullptr,
// [this](){return can_export_model(); }, this);
export_menu->AppendSeparator();
- append_menu_item(export_menu, wxID_ANY, _L("Export &toolpaths as OBJ") + dots, _L("Export toolpaths as OBJ"),
+ append_menu_item(export_menu, wxID_ANY, _L("Export &Toolpaths as OBJ") + dots, _L("Export toolpaths as OBJ"),
[this](wxCommandEvent&) { if (m_plater) m_plater->export_toolpaths_to_obj(); }, "export_plater", nullptr,
[this]() {return can_export_toolpaths(); }, this);
export_menu->AppendSeparator();
@@ -1262,7 +1262,7 @@ void MainFrame::init_menubar_as_editor()
[]() {return true; }, this);
append_submenu(fileMenu, export_menu, wxID_ANY, _L("&Export"), "");
- append_menu_item(fileMenu, wxID_ANY, _L("Ejec&t SD card / Flash drive") + dots + "\tCtrl+T", _L("Eject SD card / Flash drive after the G-code was exported to it."),
+ append_menu_item(fileMenu, wxID_ANY, _L("Ejec&t SD Card / Flash Drive") + dots + "\tCtrl+T", _L("Eject SD card / Flash drive after the G-code was exported to it."),
[this](wxCommandEvent&) { if (m_plater) m_plater->eject_drive(); }, "eject_sd", nullptr,
[this]() {return can_eject(); }, this);
@@ -1298,7 +1298,7 @@ void MainFrame::init_menubar_as_editor()
[this](wxCommandEvent&) { repair_stl(); }, "wrench", nullptr,
[]() { return true; }, this);
fileMenu->AppendSeparator();
- append_menu_item(fileMenu, wxID_ANY, _L("&G-code preview") + dots, _L("Open G-code viewer"),
+ append_menu_item(fileMenu, wxID_ANY, _L("&G-code Preview") + dots, _L("Open G-code viewer"),
[this](wxCommandEvent&) { start_new_gcodeviewer_open_file(this); }, "", nullptr);
fileMenu->AppendSeparator();
append_menu_item(fileMenu, wxID_EXIT, _L("&Quit"), wxString::Format(_L("Quit %s"), SLIC3R_APP_NAME),
@@ -1316,17 +1316,17 @@ void MainFrame::init_menubar_as_editor()
#else
wxString hotkey_delete = "Del";
#endif
- append_menu_item(editMenu, wxID_ANY, _L("&Select all") + sep + GUI::shortkey_ctrl_prefix() + sep_space + "A",
+ append_menu_item(editMenu, wxID_ANY, _L("&Select All") + sep + GUI::shortkey_ctrl_prefix() + sep_space + "A",
_L("Selects all objects"), [this](wxCommandEvent&) { m_plater->select_all(); },
"", nullptr, [this](){return can_select(); }, this);
- append_menu_item(editMenu, wxID_ANY, _L("D&eselect all") + sep + "Esc",
+ append_menu_item(editMenu, wxID_ANY, _L("D&eselect All") + sep + "Esc",
_L("Deselects all objects"), [this](wxCommandEvent&) { m_plater->deselect_all(); },
"", nullptr, [this](){return can_deselect(); }, this);
editMenu->AppendSeparator();
- append_menu_item(editMenu, wxID_ANY, _L("&Delete selected") + sep + hotkey_delete,
+ append_menu_item(editMenu, wxID_ANY, _L("&Delete Selected") + sep + hotkey_delete,
_L("Deletes the current selection"),[this](wxCommandEvent&) { m_plater->remove_selected(); },
"remove_menu", nullptr, [this](){return can_delete(); }, this);
- append_menu_item(editMenu, wxID_ANY, _L("Delete &all") + sep + GUI::shortkey_ctrl_prefix() + sep_space + hotkey_delete,
+ append_menu_item(editMenu, wxID_ANY, _L("Delete &All") + sep + GUI::shortkey_ctrl_prefix() + sep_space + hotkey_delete,
_L("Deletes all objects"), [this](wxCommandEvent&) { m_plater->reset_with_confirm(); },
"delete_all_menu", nullptr, [this](){return can_delete_all(); }, this);
@@ -1348,11 +1348,11 @@ void MainFrame::init_menubar_as_editor()
editMenu->AppendSeparator();
#ifdef __APPLE__
- append_menu_item(editMenu, wxID_ANY, _L("Re&load from disk") + dots + "\tCtrl+Shift+R",
+ append_menu_item(editMenu, wxID_ANY, _L("Re&load from Disk") + dots + "\tCtrl+Shift+R",
_L("Reload the plater from disk"), [this](wxCommandEvent&) { m_plater->reload_all_from_disk(); },
"", nullptr, [this]() {return !m_plater->model().objects.empty(); }, this);
#else
- append_menu_item(editMenu, wxID_ANY, _L("Re&load from disk") + sep + "F5",
+ append_menu_item(editMenu, wxID_ANY, _L("Re&load from Disk") + sep + "F5",
_L("Reload the plater from disk"), [this](wxCommandEvent&) { m_plater->reload_all_from_disk(); },
"", nullptr, [this]() {return !m_plater->model().objects.empty(); }, this);
#endif // __APPLE__
@@ -1410,11 +1410,11 @@ void MainFrame::init_menubar_as_editor()
[this](wxCommandEvent&) { m_printhost_queue_dlg->Show(); }, "upload_queue", nullptr, []() {return true; }, this);
windowMenu->AppendSeparator();
- append_menu_item(windowMenu, wxID_ANY, _L("Open new instance") + "\tCtrl+Shift+I", _L("Open a new PrusaSlicer instance"),
+ append_menu_item(windowMenu, wxID_ANY, _L("Open New Instance") + "\tCtrl+Shift+I", _L("Open a new PrusaSlicer instance"),
[](wxCommandEvent&) { start_new_slicer(); }, "", nullptr, [this]() {return m_plater != nullptr && wxGetApp().app_config->get("single_instance") != "1"; }, this);
windowMenu->AppendSeparator();
- append_menu_item(windowMenu, wxID_ANY, _L("Compare presets")/* + "\tCtrl+F"*/, _L("Compare presets"),
+ append_menu_item(windowMenu, wxID_ANY, _L("Compare Presets")/* + "\tCtrl+F"*/, _L("Compare presets"),
[this](wxCommandEvent&) { diff_dialog.show();}, "compare", nullptr, []() {return true; }, this);
}
@@ -1424,15 +1424,15 @@ void MainFrame::init_menubar_as_editor()
viewMenu = new wxMenu();
add_common_view_menu_items(viewMenu, this, std::bind(&MainFrame::can_change_view, this));
viewMenu->AppendSeparator();
- append_menu_check_item(viewMenu, wxID_ANY, _L("Show &labels") + sep + "E", _L("Show object/instance labels in 3D scene"),
+ append_menu_check_item(viewMenu, wxID_ANY, _L("Show &Labels") + sep + "E", _L("Show object/instance labels in 3D scene"),
[this](wxCommandEvent&) { m_plater->show_view3D_labels(!m_plater->are_view3D_labels_shown()); }, this,
[this]() { return m_plater->is_view3D_shown(); }, [this]() { return m_plater->are_view3D_labels_shown(); }, this);
- append_menu_check_item(viewMenu, wxID_ANY, _L("&Collapse sidebar") + sep + "Shift+" + sep_space + "Tab", _L("Collapse sidebar"),
+ append_menu_check_item(viewMenu, wxID_ANY, _L("&Collapse Sidebar") + sep + "Shift+" + sep_space + "Tab", _L("Collapse sidebar"),
[this](wxCommandEvent&) { m_plater->collapse_sidebar(!m_plater->is_sidebar_collapsed()); }, this,
[]() { return true; }, [this]() { return m_plater->is_sidebar_collapsed(); }, this);
#ifndef __APPLE__
// OSX adds its own menu item to toggle fullscreen.
- append_menu_check_item(viewMenu, wxID_ANY, _L("&Full screen") + "\t" + "F11", _L("Full screen"),
+ append_menu_check_item(viewMenu, wxID_ANY, _L("&Fullscreen") + "\t" + "F11", _L("Fullscreen"),
[this](wxCommandEvent&) { this->ShowFullScreen(!this->IsFullScreen(),
// wxFULLSCREEN_ALL: wxFULLSCREEN_NOMENUBAR | wxFULLSCREEN_NOTOOLBAR | wxFULLSCREEN_NOSTATUSBAR | wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION
wxFULLSCREEN_NOSTATUSBAR | wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION); },
@@ -1519,16 +1519,16 @@ void MainFrame::init_menubar_as_gcodeviewer()
[this](wxCommandEvent&) { if (m_plater != nullptr) m_plater->load_gcode(); }, "open", nullptr,
[this]() {return m_plater != nullptr; }, this);
#ifdef __APPLE__
- append_menu_item(fileMenu, wxID_ANY, _L("Re&load from disk") + dots + "\tCtrl+Shift+R",
+ append_menu_item(fileMenu, wxID_ANY, _L("Re&load from Disk") + dots + "\tCtrl+Shift+R",
_L("Reload the plater from disk"), [this](wxCommandEvent&) { m_plater->reload_gcode_from_disk(); },
"", nullptr, [this]() { return !m_plater->get_last_loaded_gcode().empty(); }, this);
#else
- append_menu_item(fileMenu, wxID_ANY, _L("Re&load from disk") + sep + "F5",
+ append_menu_item(fileMenu, wxID_ANY, _L("Re&load from Disk") + sep + "F5",
_L("Reload the plater from disk"), [this](wxCommandEvent&) { m_plater->reload_gcode_from_disk(); },
"", nullptr, [this]() { return !m_plater->get_last_loaded_gcode().empty(); }, this);
#endif // __APPLE__
fileMenu->AppendSeparator();
- append_menu_item(fileMenu, wxID_ANY, _L("Export &toolpaths as OBJ") + dots, _L("Export toolpaths as OBJ"),
+ append_menu_item(fileMenu, wxID_ANY, _L("Export &Toolpaths as OBJ") + dots, _L("Export toolpaths as OBJ"),
[this](wxCommandEvent&) { if (m_plater != nullptr) m_plater->export_toolpaths_to_obj(); }, "export_plater", nullptr,
[this]() {return can_export_toolpaths(); }, this);
append_menu_item(fileMenu, wxID_ANY, _L("Open &PrusaSlicer") + dots, _L("Open PrusaSlicer"),
diff --git a/src/slic3r/GUI/MsgDialog.cpp b/src/slic3r/GUI/MsgDialog.cpp
index 9343bb741..4e2462d4b 100644
--- a/src/slic3r/GUI/MsgDialog.cpp
+++ b/src/slic3r/GUI/MsgDialog.cpp
@@ -63,6 +63,15 @@ MsgDialog::MsgDialog(wxWindow *parent, const wxString &title, const wxString &he
SetSizerAndFit(main_sizer);
}
+void MsgDialog::SetButtonLabel(wxWindowID btn_id, const wxString& label, bool set_focus/* = false*/)
+{
+ if (wxButton* btn = get_button(btn_id)) {
+ btn->SetLabel(label);
+ if (set_focus)
+ btn->SetFocus();
+ }
+}
+
wxButton* MsgDialog::add_button(wxWindowID btn_id, bool set_focus /*= false*/, const wxString& label/* = wxString()*/)
{
wxButton* btn = new wxButton(this, btn_id, label);
@@ -98,7 +107,7 @@ void MsgDialog::finalize()
// Text shown as HTML, so that mouse selection and Ctrl-V to copy will work.
-static void add_msg_content(wxWindow* parent, wxBoxSizer* content_sizer, wxString msg, bool monospaced_font = false)
+static void add_msg_content(wxWindow* parent, wxBoxSizer* content_sizer, wxString msg, bool monospaced_font = false, bool is_marked_msg = false)
{
wxHtmlWindow* html = new wxHtmlWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO);
@@ -136,8 +145,7 @@ static void add_msg_content(wxWindow* parent, wxBoxSizer* content_sizer, wxStrin
int em = wxGetApp().em_unit();
// if message containes the table
- bool is_marked = msg.Contains("<tr>");
- if (is_marked) {
+ if (msg.Contains("<tr>")) {
int lines = msg.Freq('\n') + 1;
int pos = 0;
while (pos < (int)msg.Len() && pos != wxNOT_FOUND) {
@@ -155,7 +163,7 @@ static void add_msg_content(wxWindow* parent, wxBoxSizer* content_sizer, wxStrin
}
html->SetMinSize(page_size);
- std::string msg_escaped = xml_escape(msg.ToUTF8().data(), is_marked);
+ std::string msg_escaped = xml_escape(msg.ToUTF8().data(), is_marked_msg);
boost::replace_all(msg_escaped, "\r\n", "<br>");
boost::replace_all(msg_escaped, "\n", "<br>");
if (monospaced_font)
@@ -215,10 +223,8 @@ MessageDialog::MessageDialog(wxWindow* parent,
RichMessageDialog::RichMessageDialog(wxWindow* parent,
const wxString& message,
const wxString& caption/* = wxEmptyString*/,
- long style/* = wxOK*/,
- const wxString& headline/* = wxEmptyString*/
- )
- : MsgDialog(parent, caption.IsEmpty() ? wxString::Format(_L("%s info"), SLIC3R_APP_NAME) : caption, headline, style)
+ long style/* = wxOK*/)
+ : MsgDialog(parent, caption.IsEmpty() ? wxString::Format(_L("%s info"), SLIC3R_APP_NAME) : caption, wxEmptyString, style)
{
add_msg_content(this, content_sizer, message);
@@ -245,11 +251,11 @@ int RichMessageDialog::ShowModal()
// InfoDialog
-InfoDialog::InfoDialog(wxWindow* parent, const wxString &title, const wxString& msg)
- : MsgDialog(parent, wxString::Format(_L("%s information"), SLIC3R_APP_NAME), title, wxOK | wxICON_INFORMATION)
+InfoDialog::InfoDialog(wxWindow* parent, const wxString &title, const wxString& msg, bool is_marked_msg/* = false*/, long style/* = wxOK | wxICON_INFORMATION*/)
+ : MsgDialog(parent, wxString::Format(_L("%s information"), SLIC3R_APP_NAME), title, style)
, msg(msg)
{
- add_msg_content(this, content_sizer, msg);
+ add_msg_content(this, content_sizer, msg, false, is_marked_msg);
finalize();
}
diff --git a/src/slic3r/GUI/MsgDialog.hpp b/src/slic3r/GUI/MsgDialog.hpp
index 50651312e..17d935495 100644
--- a/src/slic3r/GUI/MsgDialog.hpp
+++ b/src/slic3r/GUI/MsgDialog.hpp
@@ -30,7 +30,7 @@ struct MsgDialog : wxDialog
MsgDialog &operator=(const MsgDialog &) = delete;
virtual ~MsgDialog() = default;
- // TODO: refactor with CreateStdDialogButtonSizer usage
+ void SetButtonLabel(wxWindowID btn_id, const wxString& label, bool set_focus = false);
protected:
enum {
@@ -111,6 +111,7 @@ public:
class MessageDialog : public MsgDialog
{
public:
+ // NOTE! Don't change a signature of contsrucor. It have to be tha same as for wxMessageDialog
MessageDialog( wxWindow *parent,
const wxString& message,
const wxString& caption = wxEmptyString,
@@ -130,12 +131,11 @@ class RichMessageDialog : public MsgDialog
bool m_checkBoxValue{ false };
public:
+ // NOTE! Don't change a signature of contsrucor. It have to be tha same as for wxRichMessageDialog
RichMessageDialog( wxWindow *parent,
const wxString& message,
const wxString& caption = wxEmptyString,
- long style = wxOK,
- const wxString& headline = wxEmptyString
- );
+ long style = wxOK);
RichMessageDialog(RichMessageDialog&&) = delete;
RichMessageDialog(const RichMessageDialog&) = delete;
RichMessageDialog &operator=(RichMessageDialog&&) = delete;
@@ -306,7 +306,7 @@ public:
class InfoDialog : public MsgDialog
{
public:
- InfoDialog(wxWindow *parent, const wxString &title, const wxString &msg);
+ InfoDialog(wxWindow *parent, const wxString &title, const wxString &msg, bool is_marked = false, long style = wxOK| wxICON_INFORMATION);
InfoDialog(InfoDialog&&) = delete;
InfoDialog(const InfoDialog&) = delete;
InfoDialog&operator=(InfoDialog&&) = delete;
diff --git a/src/slic3r/GUI/OptionsGroup.hpp b/src/slic3r/GUI/OptionsGroup.hpp
index 6647740dd..67c3fbdbd 100644
--- a/src/slic3r/GUI/OptionsGroup.hpp
+++ b/src/slic3r/GUI/OptionsGroup.hpp
@@ -181,6 +181,8 @@ public:
// we have to set same max contrtol width to all of them
void set_max_win_width(int max_win_width);
+ bool is_activated() { return sizer != nullptr; }
+
protected:
std::map<t_config_option_key, Option> m_options;
wxWindow* m_parent {nullptr};
diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp
index 0485b0075..b3ec46425 100644
--- a/src/slic3r/GUI/Plater.cpp
+++ b/src/slic3r/GUI/Plater.cpp
@@ -223,6 +223,9 @@ ObjectInfo::ObjectInfo(wxWindow *parent) :
Add(sizer_manifold, 0, wxEXPAND | wxTOP, 4);
sla_hidden_items = { label_volume, info_volume, /*label_materials, info_materials*/ };
+
+ // Fixes layout issues on plater, short BitmapComboBoxes with some Windows scaling, see GH issue #7414.
+ this->Show(false);
}
void ObjectInfo::show_sizer(bool show)
@@ -3648,12 +3651,12 @@ void Plater::priv::reload_from_disk()
if (has_source || has_name) {
int new_volume_idx = -1;
int new_object_idx = -1;
- if (has_source) {
- // take idxs from source
- new_volume_idx = old_volume->source.volume_idx;
- new_object_idx = old_volume->source.object_idx;
- }
- else {
+// if (has_source) {
+// // take idxs from source
+// new_volume_idx = old_volume->source.volume_idx;
+// new_object_idx = old_volume->source.object_idx;
+// }
+// else {
// take idxs from the 1st matching volume
for (size_t o = 0; o < new_model.objects.size(); ++o) {
ModelObject* obj = new_model.objects[o];
@@ -3669,39 +3672,40 @@ void Plater::priv::reload_from_disk()
if (found)
break;
}
- }
+// }
- if (new_object_idx < 0 && (int)new_model.objects.size() <= new_object_idx) {
+ if (new_object_idx < 0 || int(new_model.objects.size()) <= new_object_idx) {
fail_list.push_back(from_u8(has_source ? old_volume->source.input_file : old_volume->name));
continue;
}
ModelObject* new_model_object = new_model.objects[new_object_idx];
- if (new_volume_idx < 0 && (int)new_model.objects.size() <= new_volume_idx) {
+ if (new_volume_idx < 0 || int(new_model_object->volumes.size()) <= new_volume_idx) {
fail_list.push_back(from_u8(has_source ? old_volume->source.input_file : old_volume->name));
continue;
}
- if (new_volume_idx < (int)new_model_object->volumes.size()) {
- old_model_object->add_volume(*new_model_object->volumes[new_volume_idx]);
- ModelVolume* new_volume = old_model_object->volumes.back();
- new_volume->set_new_unique_id();
- new_volume->config.apply(old_volume->config);
- new_volume->set_type(old_volume->type());
- new_volume->set_material_id(old_volume->material_id());
- new_volume->set_transformation(old_volume->get_transformation());
- new_volume->translate(new_volume->get_transformation().get_matrix(true) * (new_volume->source.mesh_offset - old_volume->source.mesh_offset));
- assert(! old_volume->source.is_converted_from_inches || ! old_volume->source.is_converted_from_meters);
- if (old_volume->source.is_converted_from_inches)
- new_volume->convert_from_imperial_units();
- else if (old_volume->source.is_converted_from_meters)
- new_volume->convert_from_meters();
- std::swap(old_model_object->volumes[sel_v.volume_idx], old_model_object->volumes.back());
- old_model_object->delete_volume(old_model_object->volumes.size() - 1);
- if (!sinking)
- old_model_object->ensure_on_bed();
- old_model_object->sort_volumes(wxGetApp().app_config->get("order_volumes") == "1");
-
- sla::reproject_points_and_holes(old_model_object);
- }
+
+ old_model_object->add_volume(*new_model_object->volumes[new_volume_idx]);
+ ModelVolume* new_volume = old_model_object->volumes.back();
+ new_volume->set_new_unique_id();
+ new_volume->config.apply(old_volume->config);
+ new_volume->set_type(old_volume->type());
+ new_volume->set_material_id(old_volume->material_id());
+ new_volume->set_transformation(old_volume->get_transformation());
+ new_volume->translate(new_volume->get_transformation().get_matrix(true) * (new_volume->source.mesh_offset - old_volume->source.mesh_offset));
+ new_volume->source.object_idx = old_volume->source.object_idx;
+ new_volume->source.volume_idx = old_volume->source.volume_idx;
+ assert(! old_volume->source.is_converted_from_inches || ! old_volume->source.is_converted_from_meters);
+ if (old_volume->source.is_converted_from_inches)
+ new_volume->convert_from_imperial_units();
+ else if (old_volume->source.is_converted_from_meters)
+ new_volume->convert_from_meters();
+ std::swap(old_model_object->volumes[sel_v.volume_idx], old_model_object->volumes.back());
+ old_model_object->delete_volume(old_model_object->volumes.size() - 1);
+ if (!sinking)
+ old_model_object->ensure_on_bed();
+ old_model_object->sort_volumes(wxGetApp().app_config->get("order_volumes") == "1");
+
+ sla::reproject_points_and_holes(old_model_object);
}
}
}
diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp
index 5bc7c981e..ff89d90ad 100644
--- a/src/slic3r/GUI/Preferences.cpp
+++ b/src/slic3r/GUI/Preferences.cpp
@@ -345,7 +345,7 @@ void PreferencesDialog::build(size_t selected_tab)
def.label = L("Sequential slider applied only to top layer");
def.type = coBool;
- def.tooltip = L("If enabled, changes made using the sequential slider, in preview, apply only to gcode top layer."
+ def.tooltip = L("If enabled, changes made using the sequential slider, in preview, apply only to gcode top layer. "
"If disabled, changes made using the sequential slider, in preview, apply to the whole gcode.");
def.set_default_value(new ConfigOptionBool{ app_config->get("seq_top_layer_only") == "1" });
option = Option(def, "seq_top_layer_only");
@@ -485,7 +485,7 @@ void PreferencesDialog::build(size_t selected_tab)
{
def.label = L("Use system menu for application");
def.type = coBool;
- def.tooltip = L("If enabled, application will use the standart Windows system menu,\n"
+ def.tooltip = L("If enabled, application will use the standard Windows system menu,\n"
"but on some combination of display scales it can looks ugly. If disabled, old UI will be used.");
def.set_default_value(new ConfigOptionBool{ app_config->get("sys_menu_enabled") == "1" });
option = Option(def, "sys_menu_enabled");
diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp
index 12c26537c..406617d5a 100644
--- a/src/slic3r/GUI/Selection.cpp
+++ b/src/slic3r/GUI/Selection.cpp
@@ -954,7 +954,7 @@ void Selection::scale(const Vec3d& scale, TransformationType transformation_type
#if ENABLE_ENHANCED_PRINT_VOLUME_FIT
void Selection::scale_to_fit_print_volume(const BuildVolume& volume)
{
- auto fit = [this](double s, const Vec3d& offset) {
+ auto fit = [this](double s, Vec3d offset) {
if (s <= 0.0 || s == 1.0)
return;
@@ -972,6 +972,7 @@ void Selection::scale_to_fit_print_volume(const BuildVolume& volume)
// center selection on print bed
start_dragging();
+ offset.z() = -get_bounding_box().min.z();
translate(offset);
wxGetApp().plater()->canvas3D()->do_move(""); // avoid storing another snapshot
diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp
index 335dd6619..417ab60fa 100644
--- a/src/slic3r/GUI/Tab.cpp
+++ b/src/slic3r/GUI/Tab.cpp
@@ -289,7 +289,9 @@ void Tab::create_preset_tab()
// There is used just additional sizer for m_mode_sizer with right alignment
if (m_mode_sizer) {
auto mode_sizer = new wxBoxSizer(wxVERTICAL);
- mode_sizer->Add(m_mode_sizer, 1, wxALIGN_RIGHT);
+ // Don't set the 2nd parameter to 1, making the sizer rubbery scalable in Y axis may lead
+ // to wrong vertical size assigned to wxBitmapComboBoxes, see GH issue #7176.
+ mode_sizer->Add(m_mode_sizer, 0, wxALIGN_RIGHT);
m_hsizer->Add(mode_sizer, 1, wxALIGN_CENTER_VERTICAL | wxRIGHT, wxOSX ? 15 : 10);
}
@@ -1767,11 +1769,14 @@ void TabPrint::update()
// Note: This workaround works till "support_material" and "overhangs" is exclusive sets of mutually no-exclusive parameters.
// But it should be corrected when we will have more such sets.
// Disable check of the compatibility of the "support_material" and "overhangs" options for saved user profile
- if (!m_config_manipulation.is_initialized_support_material_overhangs_queried()) {
+ // or for profile which was loaded from 3mf
+// if (!m_config_manipulation.is_initialized_support_material_overhangs_queried())
+ if (bool support_material_overhangs_queried = m_config->opt_bool("support_material") && !m_config->opt_bool("overhangs"))
+ {
const Preset& selected_preset = m_preset_bundle->prints.get_selected_preset();
bool is_user_and_saved_preset = !selected_preset.is_system && !selected_preset.is_dirty;
- bool support_material_overhangs_queried = m_config->opt_bool("support_material") && !m_config->opt_bool("overhangs");
- m_config_manipulation.initialize_support_material_overhangs_queried(is_user_and_saved_preset && support_material_overhangs_queried);
+ bool is_saved_in_3mf_preset = selected_preset.is_dirty && !wxGetApp().plater()->is_presets_dirty();
+ m_config_manipulation.initialize_support_material_overhangs_queried((is_user_and_saved_preset || is_saved_in_3mf_preset) && support_material_overhangs_queried);
}
m_config_manipulation.update_print_fff_config(m_config, true);
@@ -3931,6 +3936,8 @@ bool Tab::validate_custom_gcodes()
bool valid = true;
for (auto opt_group : m_active_page->m_optgroups) {
assert(opt_group->opt_map().size() == 1);
+ if (!opt_group->is_activated())
+ break;
std::string key = opt_group->opt_map().begin()->first;
valid &= validate_custom_gcode(opt_group->title, boost::any_cast<std::string>(opt_group->get_value(key)));
if (!valid)
diff --git a/src/slic3r/GUI/UnsavedChangesDialog.cpp b/src/slic3r/GUI/UnsavedChangesDialog.cpp
index 037887ee6..38440b16a 100644
--- a/src/slic3r/GUI/UnsavedChangesDialog.cpp
+++ b/src/slic3r/GUI/UnsavedChangesDialog.cpp
@@ -891,18 +891,14 @@ void UnsavedChangesDialog::build(Preset::Type type, PresetCollection* dependent_
{
if (!evt.IsChecked())
return;
- wxString preferences_item = m_app_config_key == "default_action_on_new_project" ? _L("Ask for unsaved changes when creating new project") :
+ wxString preferences_item = m_app_config_key == "default_action_on_new_project" ? _L("Ask for unsaved changes when creating new project") :
m_app_config_key == "default_action_on_select_preset" ? _L("Ask for unsaved changes when selecting new preset") :
- _L("Ask for unsaved changes when ??closing application??") ;
+ _L("Ask to save unsaved changes when closing the application or when loading a new project") ;
wxString action = m_app_config_key == "default_action_on_new_project" ? _L("You will not be asked about the unsaved changes the next time you create new project") :
m_app_config_key == "default_action_on_select_preset" ? _L("You will not be asked about the unsaved changes the next time you switch a preset") :
_L("You will not be asked about the unsaved changes the next time you: \n"
- "- close the application,\n"
- "- load project,\n"
- "- process Undo / Redo with a change of print technology,\n"
- "- take/load snapshot,\n"
- "- load config file/bundle,\n"
- "- export config_bundle") ;
+ "- Closing PrusaSlicer while some presets are modified,\n"
+ "- Loading a new project while some presets are modified") ;
wxString msg = _L("PrusaSlicer will remember your action.") + "\n\n" + action + "\n\n" +
format_wxstr(_L("Visit \"Preferences\" and check \"%1%\"\nto be asked about unsaved changes again."), preferences_item);
@@ -1494,7 +1490,7 @@ DiffPresetDialog::DiffPresetDialog(MainFrame* mainframe)
});
}
- m_show_all_presets = new wxCheckBox(this, wxID_ANY, _L("Show all preset (including incompatible)"));
+ m_show_all_presets = new wxCheckBox(this, wxID_ANY, _L("Show all presets (including incompatible)"));
m_show_all_presets->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent&) {
bool show_all = m_show_all_presets->GetValue();
for (auto preset_combos : m_preset_combos) {
@@ -1555,7 +1551,7 @@ void DiffPresetDialog::update_bundles_from_app()
void DiffPresetDialog::show(Preset::Type type /* = Preset::TYPE_INVALID*/)
{
- this->SetTitle(type == Preset::TYPE_INVALID ? _L("Compare Presets") : format_wxstr(_L("Compare %1% Presets"), wxGetApp().get_tab(type)->name()));
+ this->SetTitle(_L("Compare Presets"));
m_view_type = type;
update_bundles_from_app();
diff --git a/src/slic3r/GUI/UpdateDialogs.cpp b/src/slic3r/GUI/UpdateDialogs.cpp
index c76940fd0..367c290d9 100644
--- a/src/slic3r/GUI/UpdateDialogs.cpp
+++ b/src/slic3r/GUI/UpdateDialogs.cpp
@@ -49,7 +49,7 @@ MsgUpdateSlic3r::MsgUpdateSlic3r(const Semver &ver_current, const Semver &ver_on
if (dev_version) {
const std::string url = (boost::format(URL_DEV) % ver_online.to_string()).str();
const wxString url_wx = from_u8(url);
- auto *link = new wxHyperlinkCtrl(this, wxID_ANY, _(L("Changelog && Download")), url_wx);
+ auto *link = new wxHyperlinkCtrl(this, wxID_ANY, _(L("Changelog & Download")), url_wx);
content_sizer->Add(link);
} else {
const auto lang_code = wxGetApp().current_language_code_safe().ToStdString();