mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	Suppress the '- default -' selection of Print/Filament/Printer settings
if there is any valid option available. This feature has been asked for by the Prusa3D customers as the '- default -' option has nothing to do with the actual printer and when selected accidentally, it could even lead to a printer damage.
This commit is contained in:
		
							parent
							
								
									4524ecf66b
								
							
						
					
					
						commit
						741a85187c
					
				
					 7 changed files with 136 additions and 38 deletions
				
			
		|  | @ -36,6 +36,7 @@ sub new_from_defaults { | |||
|     my (@opt_keys) = @_; | ||||
|      | ||||
|     my $self = $class->new; | ||||
|     # Instantiating the C++ class Slic3r::FullPrintConfig. | ||||
|     my $defaults = Slic3r::Config::Full->new; | ||||
|     if (@opt_keys) { | ||||
|         $self->set($_, $defaults->get($_)) | ||||
|  |  | |||
|  | @ -69,10 +69,12 @@ our $Settings = { | |||
|         # If set, the "Controller" tab for the control of the printer over serial line and the serial port settings are hidden. | ||||
|         # By default, Prusa has the controller hidden. | ||||
|         no_controller => 1, | ||||
|         # If set, the "- default -" selections of print/filament/printer are suppressed, if there is a valid preset available. | ||||
|         no_defaults => 1, | ||||
|     }, | ||||
| }; | ||||
| 
 | ||||
| our $have_button_icons = &Wx::wxVERSION_STRING =~ / (?:2\.9\.[1-9]|3\.)/; | ||||
| our $have_button_icons = &Wx::wxVERSION_STRING =~ m" (?:2\.9\.[1-9]|3\.)"; | ||||
| our $small_font = Wx::SystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); | ||||
| $small_font->SetPointSize(11) if !&Wx::wxMSW; | ||||
| our $small_bold_font = Wx::SystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); | ||||
|  | @ -126,6 +128,8 @@ sub OnInit { | |||
|         $Settings->{_}{background_processing} //= 1; | ||||
|         # If set, the "Controller" tab for the control of the printer over serial line and the serial port settings are hidden. | ||||
|         $Settings->{_}{no_controller} //= 1; | ||||
|         # If set, the "- default -" selections of print/filament/printer are suppressed, if there is a valid preset available. | ||||
|         $Settings->{_}{no_defaults} //= 1; | ||||
|     } | ||||
|     $Settings->{_}{version} = $Slic3r::VERSION; | ||||
|     $self->save_settings; | ||||
|  |  | |||
|  | @ -177,9 +177,14 @@ sub print_panels { | |||
|         map $_->GetWindow, $self->{sizer}->GetChildren; | ||||
| } | ||||
| 
 | ||||
| # Called by  | ||||
| #       Slic3r::GUI::Tab::Print::_on_presets_changed | ||||
| #       Slic3r::GUI::Tab::Filament::_on_presets_changed | ||||
| #       Slic3r::GUI::Tab::Printer::_on_presets_changed | ||||
| # when the presets are loaded or the user select another preset. | ||||
| sub update_presets { | ||||
|     my $self = shift; | ||||
|     my ($group, $presets, $selected, $is_dirty) = @_; | ||||
|     my ($group, $presets, $default_suppressed, $selected, $is_dirty) = @_; | ||||
|      | ||||
|     # update configs of currently loaded print panels | ||||
|     foreach my $panel ($self->print_panels) { | ||||
|  |  | |||
|  | @ -140,6 +140,8 @@ sub _init_tabpanel { | |||
|                 $self->config->save($Slic3r::GUI::autosave) if $Slic3r::GUI::autosave; | ||||
|             } | ||||
|         }); | ||||
|         # Install a callback for the tab to update the platter and print controller presets, when | ||||
|         # a preset changes at Slic3r::GUI::Tab. | ||||
|         $tab->on_presets_changed(sub { | ||||
|             if ($self->{plater}) { | ||||
|                 $self->{plater}->update_presets($tab_name, @_); | ||||
|  | @ -393,7 +395,7 @@ sub quick_slice { | |||
|             print_center    => $print_center, | ||||
|             status_cb       => sub { | ||||
|                 my ($percent, $message) = @_; | ||||
|                 return if &Wx::wxVERSION_STRING !~ / 2\.(8\.|9\.[2-9])/; | ||||
|                 return if &Wx::wxVERSION_STRING !~ m" 2\.(8\.|9\.[2-9])"; | ||||
|                 $progress_dialog->Update($percent, "$message…"); | ||||
|             }, | ||||
|         ); | ||||
|  |  | |||
|  | @ -330,12 +330,19 @@ sub new { | |||
|                 filament    => 'Filament', | ||||
|                 printer     => 'Printer', | ||||
|             ); | ||||
|             # UI Combo boxes for a print, multiple filaments, and a printer. | ||||
|             # Initially a single filament combo box is created, but the number of combo boxes for the filament selection may increase, | ||||
|             # once a printer preset with multiple extruders is activated. | ||||
|             # $self->{preset_choosers}{$group}[$idx] | ||||
|             $self->{preset_choosers} = {}; | ||||
|             # Boolean indicating whether the '- default -' preset is shown by the combo box. | ||||
|             $self->{preset_choosers_default_suppressed} = {}; | ||||
|             for my $group (qw(print filament printer)) { | ||||
|                 my $text = Wx::StaticText->new($self, -1, "$group_labels{$group}:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); | ||||
|                 $text->SetFont($Slic3r::GUI::small_font); | ||||
|                 my $choice = Wx::BitmapComboBox->new($self, -1, "", wxDefaultPosition, wxDefaultSize, [], wxCB_READONLY); | ||||
|                 $self->{preset_choosers}{$group} = [$choice]; | ||||
|                 $self->{preset_choosers_default_suppressed}{$group} = 0; | ||||
|                 # setup the listener | ||||
|                 EVT_COMBOBOX($choice, $choice, sub { | ||||
|                     my ($choice) = @_; | ||||
|  | @ -427,18 +434,22 @@ sub _on_select_preset { | |||
| 	my $self = shift; | ||||
| 	my ($group, $choice) = @_; | ||||
| 	 | ||||
| 	# if user changed filament preset, don't propagate this to the tabs | ||||
| 	# If user changed a filament preset and the selected machine is equipped with multiple extruders, | ||||
|     # there are multiple filament selection combo boxes shown at the platter. In that case | ||||
|     # don't propagate the filament selection changes to the tab. | ||||
|     my $default_suppressed = $self->{preset_choosers_default_suppressed}{$group}; | ||||
| 	if ($group eq 'filament' && @{$self->{preset_choosers}{filament}} > 1) { | ||||
|         # Indices of the filaments selected. | ||||
| 		my @filament_presets = $self->filament_presets; | ||||
| 		$Slic3r::GUI::Settings->{presets}{filament} = $choice->GetString($filament_presets[0]) . ".ini"; | ||||
| 		$Slic3r::GUI::Settings->{presets}{"filament_${_}"} = $choice->GetString($filament_presets[$_]) | ||||
| 		$Slic3r::GUI::Settings->{presets}{filament} = $choice->GetString($filament_presets[0] - $default_suppressed) . ".ini"; | ||||
| 		$Slic3r::GUI::Settings->{presets}{"filament_${_}"} = $choice->GetString($filament_presets[$_] - $default_suppressed) | ||||
| 			for 1 .. $#filament_presets; | ||||
| 		wxTheApp->save_settings; | ||||
| 		return; | ||||
| 	} | ||||
| 	 | ||||
| 	# call GetSelection() in scalar context as it's context-aware | ||||
| 	$self->{on_select_preset}->($group, scalar $choice->GetSelection) | ||||
| 	$self->{on_select_preset}->($group, scalar($choice->GetSelection) + $default_suppressed) | ||||
| 	    if $self->{on_select_preset}; | ||||
| 	 | ||||
| 	# get new config and generate on_config_change() event for updating plater and other things | ||||
|  | @ -450,20 +461,32 @@ sub GetFrame { | |||
|     return &Wx::GetTopLevelParent($self); | ||||
| } | ||||
| 
 | ||||
| # Update presets (Print settings, Filament, Printer) from their respective tabs. | ||||
| # Called by  | ||||
| #       Slic3r::GUI::Tab::Print::_on_presets_changed | ||||
| #       Slic3r::GUI::Tab::Filament::_on_presets_changed | ||||
| #       Slic3r::GUI::Tab::Printer::_on_presets_changed | ||||
| # when the presets are loaded or the user selects another preset. | ||||
| # For Print settings and Printer, synchronize the selection index with their tabs. | ||||
| # For Filament, synchronize the selection index for a single extruder printer only, otherwise keep the selection. | ||||
| sub update_presets { | ||||
|     my $self = shift; | ||||
|     my ($group, $presets, $selected, $is_dirty) = @_; | ||||
|     # $presets: one of qw(print filament printer) | ||||
|     # $selected: index of the selected preset in the array. This may not correspond | ||||
|     # with the index of selection in the UI element, where not all items are displayed. | ||||
|     my ($group, $presets, $default_suppressed, $selected, $is_dirty) = @_; | ||||
|      | ||||
|     my @choosers = @{ $self->{preset_choosers}{$group} }; | ||||
|     foreach my $choice (@choosers) { | ||||
|         if ($group eq 'filament' && @choosers > 1) { | ||||
|             # if we have more than one filament chooser, keep our selection | ||||
|             # instead of importing the one from the tab | ||||
|             $selected = $choice->GetSelection; | ||||
|             $selected = $choice->GetSelection + $self->{preset_choosers_default_suppressed}{$group}; | ||||
|             $is_dirty = 0; | ||||
|         } | ||||
|         $choice->Clear; | ||||
|         foreach my $preset (@$presets) { | ||||
|             next if ($preset->default && $default_suppressed); | ||||
|             my $bitmap; | ||||
|             if ($group eq 'filament') { | ||||
|                 my $config = $preset->config(['filament_colour']); | ||||
|  | @ -486,21 +509,26 @@ sub update_presets { | |||
|         } | ||||
|          | ||||
|         if ($selected <= $#$presets) { | ||||
|             if ($is_dirty) { | ||||
|                 $choice->SetString($selected, $choice->GetString($selected) . " (modified)"); | ||||
|             my $idx = $selected - $default_suppressed; | ||||
|             if ($idx >= 0) { | ||||
|                 if ($is_dirty) { | ||||
|                     $choice->SetString($idx, $choice->GetString($idx) . " (modified)"); | ||||
|                 } | ||||
|                 # call SetSelection() only after SetString() otherwise the new string | ||||
|                 # won't be picked up as the visible string | ||||
|                 $choice->SetSelection($idx); | ||||
|             } | ||||
|             # call SetSelection() only after SetString() otherwise the new string | ||||
|             # won't be picked up as the visible string | ||||
|             $choice->SetSelection($selected); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     $self->{preset_choosers_default_suppressed}{$group} = $default_suppressed; | ||||
| } | ||||
| 
 | ||||
| # Return a vector of indices of filaments selected by the $self->{preset_choosers}{filament} combo boxes. | ||||
| sub filament_presets { | ||||
|     my $self = shift; | ||||
|      | ||||
|     # force scalar context for GetSelection() as it's context-aware | ||||
|     return map scalar($_->GetSelection), @{ $self->{preset_choosers}{filament} }; | ||||
|     return map scalar($_->GetSelection) + $self->{preset_choosers_default_suppressed}{filament}, @{ $self->{preset_choosers}{filament} }; | ||||
| } | ||||
| 
 | ||||
| sub add { | ||||
|  | @ -1436,6 +1464,7 @@ sub update { | |||
|     $self->refresh_canvases; | ||||
| } | ||||
| 
 | ||||
| # When a number of extruders changes, the UI needs to be updated to show a single filament selection combo box per extruder. | ||||
| sub on_extruders_change { | ||||
|     my ($self, $num_extruders) = @_; | ||||
|      | ||||
|  |  | |||
|  | @ -67,6 +67,13 @@ sub new { | |||
|         tooltip     => 'Disable communication with the printer over a serial / USB cable. This simplifies the user interface in case the printer is never attached to the computer.', | ||||
|         default     => $Slic3r::GUI::Settings->{_}{no_controller}, | ||||
|     )); | ||||
|     $optgroup->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new( | ||||
|         opt_id      => 'no_defaults', | ||||
|         type        => 'bool', | ||||
|         label       => 'Suppress "- default -" presets', | ||||
|         tooltip     => 'Suppress "- default -" presets in the Print / Filament / Printer selections once there are any other valid presets available.', | ||||
|         default     => $Slic3r::GUI::Settings->{_}{no_defaults}, | ||||
|     )); | ||||
|      | ||||
|     my $sizer = Wx::BoxSizer->new(wxVERTICAL); | ||||
|     $sizer->Add($optgroup->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10); | ||||
|  |  | |||
|  | @ -1,6 +1,18 @@ | |||
| # The "Expert" tab at the right of the main tabbed window. | ||||
| # The "Expert" is enabled by File->Preferences dialog. | ||||
| 
 | ||||
| # This file implements following packages: | ||||
| #   Slic3r::GUI::Tab; | ||||
| #       Slic3r::GUI::Tab::Print; | ||||
| #       Slic3r::GUI::Tab::Filament; | ||||
| #       Slic3r::GUI::Tab::Printer; | ||||
| #   Slic3r::GUI::Tab::Page | ||||
| #       - Option page: For example, the Slic3r::GUI::Tab::Print has option pages "Layers and perimeters", "Infill", "Skirt and brim" ... | ||||
| #   Slic3r::GUI::SavePresetWindow | ||||
| #       - Dialog to select a new preset name to store the configuration. | ||||
| #   Slic3r::GUI::Tab::Preset; | ||||
| #       - Single preset item: name, file is default or external. | ||||
| 
 | ||||
| package Slic3r::GUI::Tab; | ||||
| use strict; | ||||
| use warnings; | ||||
|  | @ -13,6 +25,7 @@ use Wx qw(:bookctrl :dialog :keycode :icon :id :misc :panel :sizer :treectrl :wi | |||
| use Wx::Event qw(EVT_BUTTON EVT_CHOICE EVT_KEY_DOWN EVT_TREE_SEL_CHANGED); | ||||
| use base qw(Wx::Panel Class::Accessor); | ||||
| 
 | ||||
| # Index of the currently active preset. | ||||
| __PACKAGE__->mk_accessors(qw(current_preset)); | ||||
| 
 | ||||
| sub new { | ||||
|  | @ -30,7 +43,7 @@ sub new { | |||
|     $self->{sizer}->Add($left_sizer, 0, wxEXPAND | wxLEFT | wxTOP | wxBOTTOM, 3); | ||||
|      | ||||
|     my $left_col_width = 150; | ||||
|      | ||||
| 
 | ||||
|     # preset chooser | ||||
|     { | ||||
|          | ||||
|  | @ -96,16 +109,32 @@ sub new { | |||
|      | ||||
|     EVT_BUTTON($self, $self->{btn_delete_preset}, sub { | ||||
|         my $i = $self->current_preset; | ||||
|         return if $i == 0;  # this shouldn't happen but let's trap it anyway | ||||
|         # Don't let the user delete the '- default -' configuration. | ||||
|         # This shall not happen as the 'delete' button is disabled for the '- default -' entry, | ||||
|         # but better be safe than sorry. | ||||
|         return if ($i == 0 && $self->get_current_preset->{default}); | ||||
|         my $res = Wx::MessageDialog->new($self, "Are you sure you want to delete the selected preset?", 'Delete Preset', wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION)->ShowModal; | ||||
|         return unless $res == wxID_YES; | ||||
|         if (-e $self->{presets}[$i]->file) { | ||||
|             unlink $self->{presets}[$i]->file; | ||||
|         # Delete the file. | ||||
|         my $path = Slic3r::encode_path($self->{presets}[$i]->file); | ||||
|         if (-e $path && ! unlink $path) { | ||||
|             # Cannot delete the file, therefore the item will not be removed from the selection. | ||||
|             Slic3r::GUI::show_error($self, "Cannot delete file $path : $!"); | ||||
|             return; | ||||
|         } | ||||
|         # Delete the preset. | ||||
|         splice @{$self->{presets}}, $i, 1; | ||||
|         $self->{presets_choice}->Delete($i); | ||||
|         # Delete the item from the UI component. | ||||
|         $self->{presets_choice}->Delete($i - $self->{default_suppressed}); | ||||
|         $self->current_preset(undef); | ||||
|         $self->select_preset(0); | ||||
|         if ($self->{default_suppressed} && scalar(@{$self->{presets}}) == 1) { | ||||
|             # Empty selection. Add the '- default -' item into the drop down selection. | ||||
|             $self->{presets_choice}->Append($self->{presets}->[0]->name); | ||||
|             # and remember that the '- default -' is shown. | ||||
|             $self->{default_suppressed} = 0; | ||||
|         } | ||||
|         # Select the 0th item. If default is suppressed, select the first valid. | ||||
|         $self->select_preset($self->{default_suppressed}); | ||||
|         $self->_on_presets_changed; | ||||
|     }); | ||||
|      | ||||
|  | @ -120,11 +149,18 @@ sub new { | |||
|     return $self; | ||||
| } | ||||
| 
 | ||||
| # Are the '- default -' selections suppressed by the Slic3r GUI preferences? | ||||
| sub no_defaults { | ||||
|     return $Slic3r::GUI::Settings->{_}{no_defaults} ? 1 : 0; | ||||
| } | ||||
| 
 | ||||
| # Get a currently active preset (Perl class Slic3r::GUI::Tab::Preset). | ||||
| sub get_current_preset { | ||||
|     my $self = shift; | ||||
|     return $self->get_preset($self->current_preset); | ||||
| } | ||||
| 
 | ||||
| # Get a preset (Perl class Slic3r::GUI::Tab::Preset) with an index $i. | ||||
| sub get_preset { | ||||
|     my ($self, $i) = @_; | ||||
|     return $self->{presets}[$i]; | ||||
|  | @ -185,7 +221,8 @@ sub _on_presets_changed { | |||
|      | ||||
|     $self->{on_presets_changed}->( | ||||
|         $self->{presets}, | ||||
|         scalar($self->{presets_choice}->GetSelection), | ||||
|         $self->{default_suppressed}, | ||||
|         scalar($self->{presets_choice}->GetSelection) + $self->{default_suppressed}, | ||||
|         $self->is_dirty, | ||||
|     ) if $self->{on_presets_changed}; | ||||
| } | ||||
|  | @ -200,8 +237,18 @@ sub select_default_preset { | |||
| } | ||||
| 
 | ||||
| sub select_preset { | ||||
|     my $self = shift; | ||||
|     $self->{presets_choice}->SetSelection($_[0]); | ||||
|     my ($self, $i) = @_; | ||||
|     if ($self->{default_suppressed} && $i == 0) { | ||||
|         # Selecting the '- default -'. Add it to the combo box. | ||||
|         $self->{default_suppressed} = 0; | ||||
|         $self->{presets_choice}->Insert($self->{presets}->[0]->name, 0); | ||||
|     } elsif ($self->no_defaults && ! $self->{default_suppressed} && $i > 0) { | ||||
|         # The user wants to hide the '- default -' items and a non-default item has been added to the presets. | ||||
|         # Hide the '- default -' item. | ||||
|         $self->{presets_choice}->Delete(0); | ||||
|         $self->{default_suppressed} = 1; | ||||
|     } | ||||
|     $self->{presets_choice}->SetSelection($i - $self->{default_suppressed}); | ||||
|     $self->on_select_preset; | ||||
| } | ||||
| 
 | ||||
|  | @ -216,6 +263,7 @@ sub on_select_preset { | |||
|     my $self = shift; | ||||
|      | ||||
|     if ($self->is_dirty) { | ||||
|         # Display a dialog showing the dirty options in a human readable form. | ||||
|         my $old_preset = $self->get_current_preset; | ||||
|         my $name = $old_preset->default ? 'Default preset' : "Preset \"" . $old_preset->name . "\""; | ||||
|          | ||||
|  | @ -233,7 +281,7 @@ sub on_select_preset { | |||
|         my $confirm = Wx::MessageDialog->new($self, "$name has unsaved changes:\n$changes\n\nDiscard changes and continue anyway?", | ||||
|                                              'Unsaved Changes', wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION); | ||||
|         if ($confirm->ShowModal == wxID_NO) { | ||||
|             $self->{presets_choice}->SetSelection($self->current_preset); | ||||
|             $self->{presets_choice}->SetSelection($self->current_preset - $self->{default_suppressed}); | ||||
|              | ||||
|             # trigger the on_presets_changed event so that we also restore the previous value | ||||
|             # in the plater selector | ||||
|  | @ -242,7 +290,7 @@ sub on_select_preset { | |||
|         } | ||||
|     } | ||||
|      | ||||
|     $self->current_preset($self->{presets_choice}->GetSelection); | ||||
|     $self->current_preset($self->{presets_choice}->GetSelection + $self->{default_suppressed}); | ||||
|     my $preset = $self->get_current_preset; | ||||
|     my $preset_config = $self->get_preset_config($preset); | ||||
|     eval { | ||||
|  | @ -333,15 +381,13 @@ sub update_tree { | |||
| sub update_dirty { | ||||
|     my $self = shift; | ||||
|      | ||||
|     foreach my $i (0..$#{$self->{presets}}) { | ||||
|     foreach my $i ($self->{default_suppressed}..$#{$self->{presets}}) { | ||||
|         my $preset = $self->get_preset($i); | ||||
|         if ($i == $self->current_preset && $self->is_dirty) { | ||||
|             $self->{presets_choice}->SetString($i, $preset->name . " (modified)"); | ||||
|         } else { | ||||
|             $self->{presets_choice}->SetString($i, $preset->name); | ||||
|         } | ||||
|         $self->{presets_choice}->SetString( | ||||
|             $i - $self->{default_suppressed},  | ||||
|             ($i == $self->current_preset && $self->is_dirty) ? $preset->name . " (modified)" : $preset->name); | ||||
|     } | ||||
|     $self->{presets_choice}->SetSelection($self->current_preset);  # http://trac.wxwidgets.org/ticket/13769 | ||||
|     $self->{presets_choice}->SetSelection($self->current_preset - $self->{default_suppressed});  # http://trac.wxwidgets.org/ticket/13769 | ||||
|     $self->_on_presets_changed; | ||||
| } | ||||
| 
 | ||||
|  | @ -374,14 +420,17 @@ sub load_presets { | |||
|             file => $presets{$preset_name}, | ||||
|         ); | ||||
|     } | ||||
|      | ||||
|     $self->current_preset(undef); | ||||
|     $self->{default_suppressed} = Slic3r::GUI::Tab->no_defaults && scalar(@{$self->{presets}}) > 1; | ||||
|     $self->{presets_choice}->Clear; | ||||
|     $self->{presets_choice}->Append($_->name) for @{$self->{presets}}; | ||||
|     foreach my $preset (@{$self->{presets}}) { | ||||
|         next if ($preset->default && $self->{default_suppressed}); | ||||
|         $self->{presets_choice}->Append($preset->name); | ||||
|     } | ||||
|     { | ||||
|         # load last used preset | ||||
|         my $i = first { basename($self->{presets}[$_]->file) eq ($Slic3r::GUI::Settings->{presets}{$self->name} || '') } 1 .. $#{$self->{presets}}; | ||||
|         $self->select_preset($i || 0); | ||||
|         $self->select_preset($i || $self->{default_suppressed}); | ||||
|     } | ||||
|     $self->_on_presets_changed; | ||||
| } | ||||
|  | @ -402,7 +451,7 @@ sub load_config_file { | |||
|         $self->{presets_choice}->Append($preset_name); | ||||
|         $i = $#{$self->{presets}}; | ||||
|     } | ||||
|     $self->{presets_choice}->SetSelection($i); | ||||
|     $self->{presets_choice}->SetSelection($i - $self->{default_suppressed}); | ||||
|     $self->on_select_preset; | ||||
|     $self->_on_presets_changed; | ||||
| } | ||||
|  | @ -1584,6 +1633,7 @@ sub config { | |||
|     my ($self, $keys) = @_; | ||||
|      | ||||
|     if ($self->default) { | ||||
|         # Perl class Slic3r::Config extends the C++ class Slic3r::DynamicPrintConfig | ||||
|         return Slic3r::Config->new_from_defaults(@$keys); | ||||
|     } else { | ||||
|         if (!-e Slic3r::encode_path($self->file)) { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bubnikv
						bubnikv