From fc1a7471cf764bddfc7250a5674da007acf19dd8 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Mon, 2 Nov 2015 01:18:05 +0100 Subject: [PATCH] Several improvements to the print job queue --- lib/Slic3r/GUI.pm | 5 +- lib/Slic3r/GUI/Controller.pm | 1 - lib/Slic3r/GUI/Controller/PrinterPanel.pm | 210 +++++++++++++++------- lib/Slic3r/GUI/OptionsGroup/Field.pm | 9 +- var/control_pause.png | Bin 0 -> 598 bytes var/control_pause_blue.png | Bin 0 -> 721 bytes var/control_play.png | Bin 0 -> 592 bytes var/control_play_blue.png | Bin 0 -> 717 bytes var/control_stop.png | Bin 0 -> 403 bytes var/control_stop_blue.png | Bin 0 -> 695 bytes xs/src/libslic3r/GCodeSender.cpp | 12 ++ xs/src/libslic3r/GCodeSender.hpp | 1 + xs/xsp/GCodeSender.xsp | 1 + 13 files changed, 174 insertions(+), 65 deletions(-) create mode 100644 var/control_pause.png create mode 100644 var/control_pause_blue.png create mode 100644 var/control_play.png create mode 100644 var/control_play_blue.png create mode 100644 var/control_stop.png create mode 100644 var/control_stop_blue.png diff --git a/lib/Slic3r/GUI.pm b/lib/Slic3r/GUI.pm index a7d8fdfe6..743493815 100644 --- a/lib/Slic3r/GUI.pm +++ b/lib/Slic3r/GUI.pm @@ -33,7 +33,7 @@ our $have_OpenGL = eval "use Slic3r::GUI::3DScene; 1"; our $have_LWP = eval "use LWP::UserAgent; 1"; use Wx 0.9901 qw(:bitmap :dialog :icon :id :misc :systemsettings :toplevelwindow - :filedialog); + :filedialog :font); use Wx::Event qw(EVT_IDLE EVT_COMMAND); use base 'Wx::App'; @@ -66,6 +66,9 @@ our $Settings = { our $have_button_icons = &Wx::wxVERSION_STRING =~ / (?: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); +$small_bold_font->SetPointSize(11) if !&Wx::wxMSW; +$small_bold_font->SetWeight(wxFONTWEIGHT_BOLD); our $medium_font = Wx::SystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); $medium_font->SetPointSize(12); our $grey = Wx::Colour->new(200,200,200); diff --git a/lib/Slic3r/GUI/Controller.pm b/lib/Slic3r/GUI/Controller.pm index be96b5fc0..aba007d9a 100644 --- a/lib/Slic3r/GUI/Controller.pm +++ b/lib/Slic3r/GUI/Controller.pm @@ -64,7 +64,6 @@ sub new { $panel->disconnect; } - undef wxTheApp->{controller_frame}; $event->Skip; }); diff --git a/lib/Slic3r/GUI/Controller/PrinterPanel.pm b/lib/Slic3r/GUI/Controller/PrinterPanel.pm index 1b7b74a5d..3566cdb5f 100644 --- a/lib/Slic3r/GUI/Controller/PrinterPanel.pm +++ b/lib/Slic3r/GUI/Controller/PrinterPanel.pm @@ -189,17 +189,18 @@ sub new { } $temp_panel->SetSizer($temp_sizer); $temp_panel->Hide; - $left_sizer->Add($temp_panel, 0, wxEXPAND | wxTOP, 4); + $left_sizer->Add($temp_panel, 0, wxEXPAND | wxTOP | wxBOTTOM, 4); } # print jobs panel - my $print_jobs_sizer = Wx::BoxSizer->new(wxVERTICAL); + $self->{print_jobs_sizer} = my $print_jobs_sizer = Wx::BoxSizer->new(wxVERTICAL); { my $text = Wx::StaticText->new($box, -1, "Queue:", wxDefaultPosition, wxDefaultSize); $text->SetFont($Slic3r::GUI::small_font); $print_jobs_sizer->Add($text, 0, wxEXPAND, 0); - $self->{jobs_panel} = Wx::ScrolledWindow->new($box, -1, wxDefaultPosition, wxDefaultSize, wxBORDER_SUNKEN); + $self->{jobs_panel} = Wx::ScrolledWindow->new($box, -1, wxDefaultPosition, wxDefaultSize, + wxVSCROLL | wxBORDER_NONE); $self->{jobs_panel}->SetScrollbars(0, 1, 0, 1); $self->{jobs_panel_sizer} = Wx::BoxSizer->new(wxVERTICAL); $self->{jobs_panel}->SetSizer($self->{jobs_panel_sizer}); @@ -212,7 +213,8 @@ sub new { $text->SetFont($Slic3r::GUI::small_font); $log_sizer->Add($text, 0, wxEXPAND, 0); - my $log = $self->{log_textctrl} = Wx::TextCtrl->new($box, -1, "", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxBORDER_SUNKEN); + my $log = $self->{log_textctrl} = Wx::TextCtrl->new($box, -1, "", wxDefaultPosition, wxDefaultSize, + wxTE_MULTILINE | wxBORDER_NONE); $log->SetBackgroundColour($box->GetBackgroundColour); $log->SetFont($Slic3r::GUI::small_font); $log->SetEditable(0); @@ -319,9 +321,11 @@ sub disconnect { sub update_serial_ports { my ($self) = @_; - $self->{serial_port_combobox}->Clear; - $self->{serial_port_combobox}->Append($_) - for wxTheApp->scan_serial_ports; + my $cb = $self->{serial_port_combobox}; + my $current = $cb->GetValue; + $cb->Clear; + $cb->Append($_) for wxTheApp->scan_serial_ports; + $cb->SetValue($current); } sub load_print_job { @@ -366,10 +370,9 @@ sub print_job { $self->Layout; $self->set_status('Printing...'); - { - my @time = localtime(time); - $self->{log_textctrl}->AppendText(sprintf "=====\nPrint started at %02d:%02d:%02d\n", @time[2,1,0]); - } + $self->{log_textctrl}->AppendText(sprintf "=====\n"); + $self->{log_textctrl}->AppendText(sprintf "Printing %s\n", $job->name); + $self->{log_textctrl}->AppendText(sprintf "Print started at %s\n", $self->_timestamp); } sub print_completed { @@ -384,10 +387,7 @@ sub print_completed { $self->Layout; $self->set_status('Print completed.'); - { - my @time = localtime(time); - $self->{log_textctrl}->AppendText(sprintf "Print completed at %02d:%02d:%02d\n", @time[2,1,0]); - } + $self->{log_textctrl}->AppendText(sprintf "Print completed at %s\n", $self->_timestamp); # reorder jobs @{$self->jobs} = sort { $a->printed <=> $b->printed } @{$self->jobs}; @@ -428,6 +428,19 @@ sub reload_jobs { $self->{gauge}->Disable; $self->set_status('Print is paused. Click on Resume to continue.'); }); + $panel->on_abort_print(sub { + my ($job) = @_; + $self->sender->purge_queue; + $self->printing(undef); + $job->printing(0); + $job->paused(0); + $self->reload_jobs; + $self->_update_connection_controls; + $self->{gauge}->Disable; + $self->{gauge}->Hide; + $self->set_status('Print was aborted.'); + $self->{log_textctrl}->AppendText(sprintf "Print aborted at %s\n", $self->_timestamp); + }); $panel->on_resume_print(sub { my ($job) = @_; $self->sender->resume_queue; @@ -447,6 +460,14 @@ sub reload_jobs { } $self->{jobs_panel}->Layout; + $self->{print_jobs_sizer}->Layout; +} + +sub _timestamp { + my ($self) = @_; + + my @time = localtime(time); + return sprintf '%02d:%02d:%02d', @time[2,1,0]; } package Slic3r::GUI::Controller::PrinterPanel::PrintJob; @@ -471,39 +492,71 @@ use strict; use warnings; use utf8; -use Wx qw(wxTheApp :panel :id :misc :sizer :button :bitmap :font :dialog :icon); -use Wx::Event qw(EVT_BUTTON); +use Wx qw(wxTheApp :panel :id :misc :sizer :button :bitmap :font :dialog :icon :timer + :colour :brush :pen); +use Wx::Event qw(EVT_BUTTON EVT_TIMER EVT_ERASE_BACKGROUND); use base qw(Wx::Panel Class::Accessor); -__PACKAGE__->mk_accessors(qw(job on_delete_job on_print_job on_pause_print on_resume_print)); +__PACKAGE__->mk_accessors(qw(job on_delete_job on_print_job on_pause_print on_resume_print + on_abort_print blink_timer)); sub new { my ($class, $parent, $job) = @_; my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, wxDefaultSize); $self->job($job); - $self->SetBackgroundColour(Wx::wxWHITE); + $self->SetBackgroundColour(wxWHITE); - my $title_and_buttons_sizer = Wx::BoxSizer->new(wxHORIZONTAL); { - my $text = Wx::StaticText->new($self, -1, $job->name, wxDefaultPosition, wxDefaultSize); + my $white_brush = Wx::Brush->new(wxWHITE, wxSOLID); + my $pen = Wx::Pen->new(Wx::Colour->new(200,200,200), 1, wxSOLID); + EVT_ERASE_BACKGROUND($self, sub { + my $dc = Wx::PaintDC->new($self); + my $size = $self->GetSize; + $dc->SetBrush($white_brush); + $dc->SetPen($pen); + $dc->DrawRoundedRectangle(0, 0, $size->GetWidth,$size->GetHeight, 6); + }); + } + + my $left_sizer = Wx::BoxSizer->new(wxVERTICAL); + { + $self->{job_name_textctrl} = my $text = Wx::StaticText->new($self, -1, $job->name, wxDefaultPosition, wxDefaultSize); my $font = $text->GetFont; $font->SetWeight(wxFONTWEIGHT_BOLD); $text->SetFont($font); - if ($job->printing) { - $text->SetForegroundColour(Wx::wxGREEN); - } elsif ($job->printed) { + if ($job->printed) { $text->SetForegroundColour($Slic3r::GUI::grey); } - $title_and_buttons_sizer->Add($text, 1, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5); + $left_sizer->Add($text, 0, wxEXPAND, 0); } { - my $btn = $self->{btn_delete} = Wx::BitmapButton->new($self, -1, Wx::Bitmap->new("$Slic3r::var/delete.png", wxBITMAP_TYPE_PNG), - wxDefaultPosition, wxDefaultSize, Wx::wxBORDER_NONE); + my $filament_stats = join "\n", + map "$_ (" . sprintf("%.2f", $job->filament_stats->{$_}/100) . "m)", + sort keys %{$job->filament_stats}; + my $text = Wx::StaticText->new($self, -1, $filament_stats, wxDefaultPosition, wxDefaultSize); + $text->SetFont($Slic3r::GUI::small_font); + if ($job->printed && !$job->printing) { + $text->SetForegroundColour($Slic3r::GUI::grey); + } + $left_sizer->Add($text, 0, wxEXPAND | wxTOP, 6); + } + + my $buttons_sizer = Wx::BoxSizer->new(wxVERTICAL); + my $button_style = Wx::wxBORDER_NONE | wxBU_EXACTFIT; + { + my $btn = $self->{btn_delete} = Wx::Button->new($self, -1, 'Delete', + wxDefaultPosition, wxDefaultSize, $button_style); $btn->SetToolTipString("Delete this job from print queue") if $btn->can('SetToolTipString'); $btn->SetFont($Slic3r::GUI::small_font); - $title_and_buttons_sizer->Add($btn, 0, wxEXPAND | wxBOTTOM, 0); + if ($Slic3r::GUI::have_button_icons) { + $btn->SetBitmap(Wx::Bitmap->new("$Slic3r::var/delete.png", wxBITMAP_TYPE_PNG)); + } + if ($job->printing) { + $btn->Hide; + } + $buttons_sizer->Add($btn, 0, wxBOTTOM, 2); EVT_BUTTON($self, $btn, sub { my $res = Wx::MessageDialog->new($self, "Are you sure you want to delete this print job?", 'Delete Job', wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION)->ShowModal; @@ -514,30 +567,18 @@ sub new { }); }); } - - my $left_sizer = Wx::BoxSizer->new(wxVERTICAL); - { - my $filament_stats = join "\n", - map "$_ (" . sprintf("%.2f", $job->filament_stats->{$_}/100) . "m)", - sort keys %{$job->filament_stats}; - my $text = Wx::StaticText->new($self, -1, $filament_stats, wxDefaultPosition, wxDefaultSize); - $text->SetFont($Slic3r::GUI::small_font); - if ($job->printed && !$job->printing) { - $text->SetForegroundColour($Slic3r::GUI::grey); - } - $left_sizer->Add($text, 1, wxEXPAND | wxTOP | wxBOTTOM, 7); - } - - - my $right_sizer = Wx::BoxSizer->new(wxVERTICAL); { my $label = $job->printed ? 'Print Again' : 'Print This'; - my $btn = $self->{btn_print} = Wx::Button->new($self, -1, $label, wxDefaultPosition, wxDefaultSize); - $btn->Hide; + my $btn = $self->{btn_print} = Wx::Button->new($self, -1, $label, wxDefaultPosition, wxDefaultSize, + $button_style); + $btn->SetFont($Slic3r::GUI::small_bold_font); if ($Slic3r::GUI::have_button_icons) { - $self->{btn_print}->SetBitmap(Wx::Bitmap->new("$Slic3r::var/arrow_up.png", wxBITMAP_TYPE_PNG)); + $btn->SetBitmap(Wx::Bitmap->new("$Slic3r::var/control_play.png", wxBITMAP_TYPE_PNG)); + $btn->SetBitmapCurrent(Wx::Bitmap->new("$Slic3r::var/control_play_blue.png", wxBITMAP_TYPE_PNG)); + #$btn->SetBitmapPosition(wxRIGHT); } - $right_sizer->Add($btn, 0, wxEXPAND | wxBOTTOM, 7); + $btn->Hide; + $buttons_sizer->Add($btn, 0, wxBOTTOM, 2); EVT_BUTTON($self, $btn, sub { wxTheApp->CallAfter(sub { @@ -546,14 +587,17 @@ sub new { }); } { - my $btn = $self->{btn_pause} = Wx::Button->new($self, -1, "Pause", wxDefaultPosition, wxDefaultSize); + my $btn = $self->{btn_pause} = Wx::Button->new($self, -1, "Pause", wxDefaultPosition, wxDefaultSize, + $button_style); + $btn->SetFont($Slic3r::GUI::small_font); if (!$job->printing || $job->paused) { $btn->Hide; } if ($Slic3r::GUI::have_button_icons) { - $self->{btn_print}->SetBitmap(Wx::Bitmap->new("$Slic3r::var/arrow_up.png", wxBITMAP_TYPE_PNG)); + $btn->SetBitmap(Wx::Bitmap->new("$Slic3r::var/control_pause.png", wxBITMAP_TYPE_PNG)); + $btn->SetBitmapCurrent(Wx::Bitmap->new("$Slic3r::var/control_pause_blue.png", wxBITMAP_TYPE_PNG)); } - $right_sizer->Add($btn, 0, wxEXPAND | wxBOTTOM, 7); + $buttons_sizer->Add($btn, 0, wxBOTTOM, 2); EVT_BUTTON($self, $btn, sub { wxTheApp->CallAfter(sub { @@ -562,14 +606,17 @@ sub new { }); } { - my $btn = $self->{btn_resume} = Wx::Button->new($self, -1, "Resume", wxDefaultPosition, wxDefaultSize); + my $btn = $self->{btn_resume} = Wx::Button->new($self, -1, "Resume", wxDefaultPosition, wxDefaultSize, + $button_style); + $btn->SetFont($Slic3r::GUI::small_font); if (!$job->printing || !$job->paused) { $btn->Hide; } if ($Slic3r::GUI::have_button_icons) { - $self->{btn_print}->SetBitmap(Wx::Bitmap->new("$Slic3r::var/arrow_up.png", wxBITMAP_TYPE_PNG)); + $btn->SetBitmap(Wx::Bitmap->new("$Slic3r::var/control_play.png", wxBITMAP_TYPE_PNG)); + $btn->SetBitmapCurrent(Wx::Bitmap->new("$Slic3r::var/control_play_blue.png", wxBITMAP_TYPE_PNG)); } - $right_sizer->Add($btn, 0, wxEXPAND | wxBOTTOM, 7); + $buttons_sizer->Add($btn, 0, wxBOTTOM, 2); EVT_BUTTON($self, $btn, sub { wxTheApp->CallAfter(sub { @@ -577,16 +624,46 @@ sub new { }); }); } + { + my $btn = $self->{btn_abort} = Wx::Button->new($self, -1, "Abort", wxDefaultPosition, wxDefaultSize, + $button_style); + $btn->SetFont($Slic3r::GUI::small_font); + if (!$job->printing) { + $btn->Hide; + } + if ($Slic3r::GUI::have_button_icons) { + $btn->SetBitmap(Wx::Bitmap->new("$Slic3r::var/control_stop.png", wxBITMAP_TYPE_PNG)); + $btn->SetBitmapCurrent(Wx::Bitmap->new("$Slic3r::var/control_stop_blue.png", wxBITMAP_TYPE_PNG)); + } + $buttons_sizer->Add($btn, 0, wxBOTTOM, 2); + + EVT_BUTTON($self, $btn, sub { + wxTheApp->CallAfter(sub { + $self->on_abort_print->($job); + }); + }); + } - my $middle_sizer = Wx::BoxSizer->new(wxHORIZONTAL); - $middle_sizer->Add($left_sizer, 1, wxEXPAND, 0); - $middle_sizer->Add($right_sizer, 0, wxEXPAND, 0); - - my $sizer = Wx::BoxSizer->new(wxVERTICAL); - $sizer->Add($title_and_buttons_sizer, 0, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, 3); - $sizer->Add($middle_sizer, 1, wxEXPAND, 0); + my $sizer = Wx::BoxSizer->new(wxHORIZONTAL); + $sizer->Add($left_sizer, 1, wxEXPAND | wxALL, 6); + $sizer->Add($buttons_sizer, 0, wxEXPAND | wxALL, 6); $self->SetSizer($sizer); + # set-up the timer that changes the job name color while printing + if ($self->job->printing && !$self->job->paused) { + my $timer_id = &Wx::NewId(); + $self->blink_timer(Wx::Timer->new($self, $timer_id)); + my $blink = 0; # closure + my $colour = Wx::Colour->new(0, 190, 0); + EVT_TIMER($self, $timer_id, sub { + my ($self, $event) = @_; + + $self->{job_name_textctrl}->SetForegroundColour($blink ? Wx::wxBLACK : $colour); + $blink = !$blink; + }); + $self->blink_timer->Start(1000, wxTIMER_CONTINUOUS); + } + return $self; } @@ -599,4 +676,15 @@ sub enable_print { $self->Layout; } +sub Destroy { + my ($self) = @_; + + # There's a gap between the time Perl destroys the wxPanel object and + # the blink_timer member, so the wxTimer might still fire an event which + # isn't handled properly, causing a crash. So we ensure that blink_timer + # is stopped before we destroy the wxPanel. + $self->blink_timer->Stop if $self->blink_timer; + return $self->SUPER::Destroy; +} + 1; diff --git a/lib/Slic3r/GUI/OptionsGroup/Field.pm b/lib/Slic3r/GUI/OptionsGroup/Field.pm index a0d2cfae0..3a7d184db 100644 --- a/lib/Slic3r/GUI/OptionsGroup/Field.pm +++ b/lib/Slic3r/GUI/OptionsGroup/Field.pm @@ -254,8 +254,13 @@ sub set_values { $self->disable_change_event(1); - $self->wxWindow->Clear; - $self->wxWindow->Append($_) for @$values; + # it looks that Clear() also clears the text field in recent wxWidgets versions, + # but we want to preserve it + my $ww = $self->wxWindow; + my $value = $ww->GetValue; + $ww->Clear; + $ww->Append($_) for @$values; + $ww->SetValue($value); $self->disable_change_event(0); } diff --git a/var/control_pause.png b/var/control_pause.png new file mode 100644 index 0000000000000000000000000000000000000000..2d9ce9c4ec4b787b77e2407809c8887b6252dc6e GIT binary patch literal 598 zcmV-c0;&CpP)U3VE{tZoOXQ3gborPd)C!*bfsFfgUA%b`K z{k54{z0H}ACRrHvW^d-rdyicUV+{VYtX~gCqfs0|(-=vN2o1PiuPW{>+#Atov}dlj zm>FQRf_YAoB-!b7g57TC=llI0*6TIQX0twmlwz@1Su_y<#c()O27`fy#f%p1x~?-# z)7Wme<7b=AhIKj}t=(=bMjvNzr~MuZg=Ct#TCD`Id5F*FgY9+;-ENndyrfd8-V+sI zk|x?lbD>axN~J2Ai^W%{R^I>_0Z9u6gEF#73lqsO`axO|3~qzj{hRS`0}LC%>-AD? zlFkeU5t@ED93Che0EA(j5rE6(g7f(t5ddbb)O7oPG}&BpJRae6I)RyiO6J&XwmSe5 z5%qypxm=P~KCwUk1<-E^%&v%&sfQfOPbAd^dMUz$2)JWFR zn(5E_apM_H=DRN?Tj1j{9obJa2Z=)=&L)N3y%h6eCr3~F>o%;x+TQ>p^I2c0Y>yvi zIld-=tn@%V9S}8IT_{!R5Z+_Ch0UxTYjubYFr%4GeU;lC74TEKeW=Sl5HvMAeX=Gi zUD%DrWY78$Ld*n!b75@ktedM+7b-uxz>7nb#SWC}9Rsqt73OZQ@HmbM0hR#sjmFrz z`Qn2R+;S%k^W^LfTz4f%8vIhZ??Cw@GT3qQ2$+f;Bm~?nEIi6bESWz7m0cmx39em$$Y&@l88-}q`@)p_|Tj# z*1_TN$urdYuZuK(mFK)s`?7zHi^MWe;3cvrICC;Dz(yzzbJPMi?R@k1RUUs#H=pHg zvrjkZN3JD?ns*D2owV@K;bCSR0s0c1`uAh{pXdA&89xkjaU%7W00000NkvXXu0mjf DW6MO* literal 0 HcmV?d00001 diff --git a/var/control_play.png b/var/control_play.png new file mode 100644 index 0000000000000000000000000000000000000000..0846555d0ca84cb99d4c70dad80144a232604041 GIT binary patch literal 592 zcmV-W0k7R5;6} zlgp~&KoEw{L*wq6jM9+RMU)_iNO6K~b@$|K=nj zb2!5=4Mjq_zrU*f>U2#vSVnMZ9ja4cY`AdOM*t}k^goWqfa3Iq(>2kSH;P81hAqIyBm_{t1>+!KRdtb~{1AK7>C~ zD-Nov`UX!X6ET_La7f{B_|*cRuZGR%^C`gjd@jmW6h*+;8;{2{8ja|Fzf-YTq+l@k zGLg?!DijI~9$+CG0*bxx-)TO!p6i!Q&%N5)kR|pVJuNho7M&@5o@ZpsgYXg z6pCpqAEgW*0v6~{n89ISU>M4A&V?DNy7MOQX68Ka`MBqf0l?U(ZY+X9l}VLZ)#Om- z;Wxvd@uT21RmKNz1dH$Bj0zp6>Db9B7mX*l{i7uPYA;7kd3g)QVC)rxA$;8vC|jea zS%$3%AWB_OF8f4{mJFo|55c22v$T`7VytGO85j|cC%=pBjskcjxd*)11x{77(<9$R zNrwG!M09PX(8Nd#urDkdGiz{FkfHKZhPUAguyq;A^$wKyj&8EE8)WXSvDl6Q4NN}z z2Zd#i!U*1a7=Vq#3W3jRZ6Z9$+&MVBAqrVEFbBV-XzUqFMNrFnb9RsDb%-T!q1pza zrNBj9g5~vhG_q(g8Ht^6IILQuOJK}cdY)autaf$;u_Hxz{;liNSF+ zP7JVo4aPtM&mF+{jGz3=veK}ME-bIS)D6sEz9#6p*nx(m=)Gd##2kGE&YZW%&7_NU zaJbxh3nsTeLlsIj==Xtu`3s4ZJ3jM?zzC+xEl8DG(CzhM_b>rg=Lda=hWnnX#UBVW zoG_R&W`Q?ax-3JI?gr8ns1oY(%Y_9|I!G4+85=MXv^z2{WgQJlI?w zaoVxP)O;^z5vZ zY!uIB*x&E}vNJj4{?GTJBigE^o7UKdzE#&EBXnfjM2N9qUNJ=7T*(!I*v$dVF@wV! zPcbfCO)dpCHwm6#49koVc}1IZ;f0opGWdxBx;Rl@XzG}46S&UgQ6wI6lQE987w+r= zQ{sp)?}bM^PSu zImdUlKjSCCE4u7+Z)8{a(f*WH^6Vt$sa4Pdn>Gm|hqxOd&DgzL7wR=Ny zr>K3{Pb3xpRu)a{!~pxkvN5v>H{?FlfAoQu4ArC_RK=cUva=WC?yvFKjtvbQVdguH zW&aC4ZFY(9WQu1%h2k`_XyA-}%`(_CmTH1G9&H+WxB<7lEP>07F324X&LtI=*Ebks z(O^1xbS&VonymqWF(ZPe(4cg#Lb0wAqrP?lYk_qESz>U=ricNSk8nlkTJZI`2;B0p zP~cS}qly76ue`DhoFBiW8A<6uOVzAiF)Myh40}1zPD8j{)c_{NT znF;osE(x$5WnrFL;%2<>{$AzD&vfr)$@TcfHvM#Qg`uALgat1xJn{IMSx=b0LuW4k dO#kzpe*)_`5%$M*g6RMN002ovPDHLkV1l_FIQ#$r literal 0 HcmV?d00001 diff --git a/xs/src/libslic3r/GCodeSender.cpp b/xs/src/libslic3r/GCodeSender.cpp index e0a6873e9..65b4fbfd3 100644 --- a/xs/src/libslic3r/GCodeSender.cpp +++ b/xs/src/libslic3r/GCodeSender.cpp @@ -158,6 +158,18 @@ GCodeSender::resume_queue() this->send(); } +void +GCodeSender::purge_queue() +{ + boost::lock_guard l(this->queue_mutex); + { + // clear queue + std::queue empty; + std::swap(this->queue, empty); + } + this->queue_paused = false; +} + // purge log and return its contents std::vector GCodeSender::purge_log() diff --git a/xs/src/libslic3r/GCodeSender.hpp b/xs/src/libslic3r/GCodeSender.hpp index a09e7e5fe..29a53c50d 100644 --- a/xs/src/libslic3r/GCodeSender.hpp +++ b/xs/src/libslic3r/GCodeSender.hpp @@ -27,6 +27,7 @@ class GCodeSender : private boost::noncopyable { size_t queue_size() const; void pause_queue(); void resume_queue(); + void purge_queue(); std::vector purge_log(); std::string getT() const; std::string getB() const; diff --git a/xs/xsp/GCodeSender.xsp b/xs/xsp/GCodeSender.xsp index dc33284a8..104b9b70c 100644 --- a/xs/xsp/GCodeSender.xsp +++ b/xs/xsp/GCodeSender.xsp @@ -18,6 +18,7 @@ void send(std::string s, bool priority = false); void pause_queue(); void resume_queue(); + void purge_queue(); std::vector purge_log(); std::string getT(); std::string getB();