New commands for exporting/importing full config bundles. Useful for printer vendors. #1365

xs-model
Alessandro Ranellucci 2014-03-25 14:04:01 +01:00
parent c98c992b4d
commit fed8783e30
4 changed files with 143 additions and 16 deletions

View File

@ -77,9 +77,16 @@ sub load {
my ($file) = @_;
my $ini = __PACKAGE__->read_ini($file);
return $class->load_ini_hash($ini->{_});
}
sub load_ini_hash {
my $class = shift;
my ($ini_hash) = @_;
my $config = $class->new;
foreach my $opt_key (keys %{$ini->{_}}) {
($opt_key, my $value) = _handle_legacy($opt_key, $ini->{_}{$opt_key});
foreach my $opt_key (keys %$ini_hash) {
($opt_key, my $value) = _handle_legacy($opt_key, $ini_hash->{$opt_key});
next if !defined $opt_key;
$config->set_deserialize($opt_key, $value);
}
@ -119,7 +126,7 @@ sub _handle_legacy {
if ($opt_key eq 'gcode_flavor' && $value eq 'makerbot') {
$value = 'makerware';
}
if ($opt_key eq 'fill_density' && defined($value) && $value <= 1) {
if ($opt_key eq 'fill_density' && defined($value) && $value !~ /%/ && $value <= 1) {
# fill_density was turned into a percent value
$value *= 100;
$value = "$value"; # force update of the PV value, workaround for bug https://rt.cpan.org/Ticket/Display.html?id=94110
@ -161,16 +168,22 @@ sub set_ifndef {
}
}
sub save {
my $self = shift;
my ($file) = @_;
sub as_ini {
my ($self) = @_;
my $ini = { _ => {} };
foreach my $opt_key (sort @{$self->get_keys}) {
next if $Options->{$opt_key}{shortcut};
$ini->{_}{$opt_key} = $self->serialize($opt_key);
}
__PACKAGE__->write_ini($file, $ini);
return $ini;
}
sub save {
my $self = shift;
my ($file) = @_;
__PACKAGE__->write_ini($file, $self->as_ini);
}
sub setenv {
@ -382,7 +395,8 @@ sub write_ini {
binmode $fh, ':utf8';
my $localtime = localtime;
printf $fh "# generated by Slic3r $Slic3r::VERSION on %s\n", "$localtime";
foreach my $category (sort keys %$ini) {
# make sure the _ category is the first one written
foreach my $category (sort { ($a eq '_') ? -1 : ($a cmp $b) } keys %$ini) {
printf $fh "\n[%s]\n", $category if $category ne '_';
foreach my $key (sort keys %{$ini->{$category}}) {
printf $fh "%s = %s\n", $key, $ini->{$category}{$key};
@ -406,7 +420,7 @@ sub read_ini {
next if /^\s+/;
next if /^$/;
next if /^\s*#/;
if (/^\[(\w+)\]$/) {
if (/^\[(.+?)\]$/) {
$category = $1;
next;
}

View File

@ -3,6 +3,7 @@ use strict;
use warnings;
use utf8;
use File::Basename qw(basename);
use FindBin;
use Slic3r::GUI::AboutDialog;
use Slic3r::GUI::ConfigWizard;
@ -25,7 +26,9 @@ use Wx::Event qw(EVT_CLOSE EVT_MENU EVT_IDLE);
use base 'Wx::App';
use constant MI_LOAD_CONF => &Wx::NewId;
use constant MI_LOAD_CONFBUNDLE => &Wx::NewId;
use constant MI_EXPORT_CONF => &Wx::NewId;
use constant MI_EXPORT_CONFBUNDLE => &Wx::NewId;
use constant MI_QUICK_SLICE => &Wx::NewId;
use constant MI_REPEAT_QUICK => &Wx::NewId;
use constant MI_QUICK_SAVE_AS => &Wx::NewId;
@ -117,6 +120,8 @@ sub OnInit {
{
$fileMenu->Append(MI_LOAD_CONF, "&Load Config…\tCtrl+L", 'Load exported configuration file');
$fileMenu->Append(MI_EXPORT_CONF, "&Export Config…\tCtrl+E", 'Export current configuration to file');
$fileMenu->Append(MI_LOAD_CONFBUNDLE, "&Load Config Bundle…", 'Load presets from a bundle');
$fileMenu->Append(MI_EXPORT_CONFBUNDLE, "&Export Config Bundle…", 'Export all presets to file');
$fileMenu->AppendSeparator();
$fileMenu->Append(MI_QUICK_SLICE, "Q&uick Slice…\tCtrl+U", 'Slice file');
$fileMenu->Append(MI_QUICK_SAVE_AS, "Quick Slice and Save &As…\tCtrl+Alt+U", 'Slice file and save as');
@ -132,7 +137,9 @@ sub OnInit {
$fileMenu->AppendSeparator();
$fileMenu->Append(wxID_EXIT, "&Quit", 'Quit Slic3r');
EVT_MENU($frame, MI_LOAD_CONF, sub { $self->{skeinpanel}->load_config_file });
EVT_MENU($frame, MI_LOAD_CONFBUNDLE, sub { $self->{skeinpanel}->load_configbundle });
EVT_MENU($frame, MI_EXPORT_CONF, sub { $self->{skeinpanel}->export_config });
EVT_MENU($frame, MI_EXPORT_CONFBUNDLE, sub { $self->{skeinpanel}->export_configbundle });
EVT_MENU($frame, MI_QUICK_SLICE, sub { $self->{skeinpanel}->quick_slice;
$repeat->Enable(defined $Slic3r::GUI::SkeinPanel::last_input_file) });
EVT_MENU($frame, MI_REPEAT_QUICK, sub { $self->{skeinpanel}->quick_slice(reslice => 1) });
@ -309,6 +316,21 @@ sub save_settings {
Slic3r::Config->write_ini("$datadir/slic3r.ini", $Settings);
}
sub presets {
my ($class, $section) = @_;
my %presets = ();
opendir my $dh, "$Slic3r::GUI::datadir/$section" or die "Failed to read directory $Slic3r::GUI::datadir/$section (errno: $!)\n";
foreach my $file (grep /\.ini$/i, readdir $dh) {
my $name = basename($file);
$name =~ s/\.ini$//;
$presets{$name} = "$Slic3r::GUI::datadir/$section/$file";
}
closedir $dh;
return %presets;
}
sub have_version_check {
my $class = shift;

View File

@ -284,6 +284,100 @@ sub load_config_file {
}
}
sub export_configbundle {
my $self = shift;
eval {
# validate current configuration in case it's dirty
$self->config->validate;
};
Slic3r::GUI::catch_error($self) and return;
my $dir = $last_config ? dirname($last_config) : $Slic3r::GUI::Settings->{recent}{config_directory} || $Slic3r::GUI::Settings->{recent}{skein_directory} || '';
my $filename = "Slic3r_config_bundle.ini";
my $dlg = Wx::FileDialog->new($self, 'Save presets bundle as:', $dir, $filename,
FILE_WILDCARDS->{ini}, wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
if ($dlg->ShowModal == wxID_OK) {
my $file = $dlg->GetPath;
$Slic3r::GUI::Settings->{recent}{config_directory} = dirname($file);
Slic3r::GUI->save_settings;
# leave default category empty to prevent the bundle from being parsed as a normal config file
my $ini = { _ => {} };
$ini->{settings}{$_} = $Slic3r::GUI::Settings->{_}{$_} for qw(autocenter mode);
$ini->{presets} = $Slic3r::GUI::Settings->{presets};
if (-e "$Slic3r::GUI::datadir/simple.ini") {
my $config = Slic3r::Config->load("$Slic3r::GUI::datadir/simple.ini");
$ini->{simple} = $config->as_ini->{_};
}
foreach my $section (qw(print filament printer)) {
my %presets = Slic3r::GUI->presets($section);
foreach my $preset_name (keys %presets) {
my $config = Slic3r::Config->load($presets{$preset_name});
$ini->{"$section:$preset_name"} = $config->as_ini->{_};
}
}
Slic3r::Config->write_ini($file, $ini);
}
$dlg->Destroy;
}
sub load_configbundle {
my $self = shift;
my $dir = $last_config ? dirname($last_config) : $Slic3r::GUI::Settings->{recent}{config_directory} || $Slic3r::GUI::Settings->{recent}{skein_directory} || '';
my $dlg = Wx::FileDialog->new($self, 'Select configuration to load:', $dir, "config.ini",
FILE_WILDCARDS->{ini}, wxFD_OPEN | wxFD_FILE_MUST_EXIST);
return unless $dlg->ShowModal == wxID_OK;
my ($file) = $dlg->GetPaths;
$dlg->Destroy;
$Slic3r::GUI::Settings->{recent}{config_directory} = dirname($file);
Slic3r::GUI->save_settings;
# load .ini file
my $ini = Slic3r::Config->read_ini($file);
if ($ini->{settings}) {
$Slic3r::GUI::Settings->{_}{$_} = $ini->{settings}{$_} for keys %{$ini->{settings}};
Slic3r::GUI->save_settings;
}
if ($ini->{presets}) {
$Slic3r::GUI::Settings->{presets} = $ini->{presets};
Slic3r::GUI->save_settings;
}
if ($ini->{simple}) {
my $config = Slic3r::Config->load_ini_hash($ini->{simple});
$config->save("$Slic3r::GUI::datadir/simple.ini");
if ($self->{mode} eq 'simple') {
foreach my $tab (values %{$self->{options_tabs}}) {
$tab->load_config($config) for values %{$self->{options_tabs}};
}
}
}
my $imported = 0;
foreach my $ini_category (sort keys %$ini) {
next unless $ini_category =~ /^(print|filament|printer):(.+)$/;
my ($section, $preset_name) = ($1, $2);
my $config = Slic3r::Config->load_ini_hash($ini->{$ini_category});
$config->save(sprintf "$Slic3r::GUI::datadir/%s/%s.ini", $section, $preset_name);
$imported++;
}
if ($self->{mode} eq 'expert') {
foreach my $tab (values %{$self->{options_tabs}}) {
$tab->load_presets;
}
}
my $message = sprintf "%d presets successfully imported.", $imported;
if ($self->{mode} eq 'simple' && $Slic3r::GUI::Settings->{_}{mode} eq 'expert') {
Slic3r::GUI::show_info($self, "$message You need to restart Slic3r to make the changes effective.");
} else {
Slic3r::GUI::show_info($self, $message);
}
}
sub load_config {
my $self = shift;
my ($config) = @_;

View File

@ -345,16 +345,13 @@ sub load_presets {
name => '- default -',
}];
opendir my $dh, "$Slic3r::GUI::datadir/" . $self->name or die "Failed to read directory $Slic3r::GUI::datadir/" . $self->name . " (errno: $!)\n";
foreach my $file (sort grep /\.ini$/i, readdir $dh) {
my $name = basename($file);
$name =~ s/\.ini$//;
my %presets = Slic3r::GUI->presets($self->name);
foreach my $preset_name (keys %presets) {
push @{$self->{presets}}, {
file => "$Slic3r::GUI::datadir/" . $self->name . "/$file",
name => $name,
name => $preset_name,
file => $presets{$preset_name},
};
}
closedir $dh;
$self->{presets_choice}->Clear;
$self->{presets_choice}->Append($_->{name}) for @{$self->{presets}};