2011-06-08 14:19:38 +00:00
#!/usr/bin/env python
2012-01-23 11:36:49 +00:00
# This file is part of the Printrun suite.
2012-03-20 17:57:57 +00:00
#
2012-01-23 11:36:49 +00:00
# Printrun is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
2012-03-20 17:57:57 +00:00
#
2012-01-23 11:36:49 +00:00
# Printrun is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
2012-03-20 17:57:57 +00:00
#
2012-01-23 11:36:49 +00:00
# You should have received a copy of the GNU General Public License
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
2011-08-06 23:45:52 +00:00
2012-07-31 08:51:17 +00:00
import os , Queue , re
2011-09-06 16:55:52 +00:00
2012-07-31 08:51:17 +00:00
from printrun . printrun_utils import install_locale
install_locale ( ' pronterface ' )
2011-08-06 23:45:52 +00:00
2011-06-08 14:19:38 +00:00
try :
import wx
except :
2011-08-06 23:45:52 +00:00
print _ ( " WX is not installed. This program requires WX to run. " )
2011-06-08 14:19:38 +00:00
raise
2012-08-07 11:54:07 +00:00
import sys , glob , time , datetime , threading , traceback , cStringIO , subprocess
2013-05-18 15:18:20 +00:00
import shlex
2012-07-31 20:37:00 +00:00
2012-08-04 08:35:33 +00:00
from printrun . pronterface_widgets import *
Tell the user, there was an error while connecting
Before, when there was an error while connecting, user didn't know, when
Pronterface wasn't launched from the terminal.
So you could just hit Connect button several times and all you've get was:
Connecting...
Connecting...
Connecting...
Now, when there is an exception during the connection, the user will notice:
Connecting...
Error: You are trying to connect to a non-exisiting port.
Or:
Connecting...
Error: You don't have permission to open /dev/ttyUSB0.
You might need to add yourself to the dialout group.
Unfortunately pyserial's SerialException doesn't provide errno yet, so the
message isn't so user friendly:
Connecting...
could not open port None: [Errno 2] No such file or directory: 'None'
I've filled a bug report with patch to pyserial.
Together with this I've realised, there is unnecessary UTF8 decoding of the
output. When user has UTF-8 locale, there was an exception when printing the
exception to the output (almost an exception inception). So I have dropped it,
but feel free to add it back, if I broke anything else.
2013-01-15 20:22:56 +00:00
from serial import SerialException
2012-08-04 08:35:33 +00:00
2012-08-08 07:38:48 +00:00
StringIO = cStringIO
2012-03-20 17:57:57 +00:00
2012-08-08 07:38:48 +00:00
winsize = ( 800 , 500 )
layerindex = 0
if os . name == " nt " :
winsize = ( 800 , 530 )
2011-06-08 14:19:38 +00:00
try :
import _winreg
except :
pass
2011-06-13 07:09:29 +00:00
2012-08-04 08:43:29 +00:00
import printcore
2012-07-31 09:02:06 +00:00
from printrun . printrun_utils import pixmapfile , configfile
2012-09-05 11:09:38 +00:00
from printrun . gui import MainWindow
2011-06-09 06:18:13 +00:00
import pronsole
2013-05-15 17:42:38 +00:00
from pronsole import dosify
2013-05-16 13:05:28 +00:00
from printrun import gcoder
2011-06-08 22:02:00 +00:00
2012-08-02 16:26:56 +00:00
def parse_temperature_report ( report , key ) :
2012-09-06 05:07:37 +00:00
if key in report :
return float ( filter ( lambda x : x . startswith ( key ) , report . split ( ) ) [ 0 ] . split ( " : " ) [ 1 ] . split ( " / " ) [ 0 ] )
else :
return - 1.0
2012-07-31 07:00:28 +00:00
2012-08-04 09:02:17 +00:00
def format_time ( timestamp ) :
2012-08-07 11:54:07 +00:00
return datetime . datetime . fromtimestamp ( timestamp ) . strftime ( " % H: % M: % S " )
def format_duration ( delta ) :
return str ( datetime . timedelta ( seconds = int ( delta ) ) )
2012-08-04 09:02:17 +00:00
2011-06-09 06:18:13 +00:00
class Tee ( object ) :
def __init__ ( self , target ) :
self . stdout = sys . stdout
sys . stdout = self
2012-08-08 07:38:48 +00:00
self . target = target
2011-06-09 06:18:13 +00:00
def __del__ ( self ) :
sys . stdout = self . stdout
def write ( self , data ) :
2012-07-11 18:56:15 +00:00
try :
self . target ( data )
except :
pass
2013-01-23 16:11:08 +00:00
try :
data = data . encode ( " utf-8 " )
except :
pass
self . stdout . write ( data )
2011-06-09 13:19:03 +00:00
def flush ( self ) :
self . stdout . flush ( )
2011-06-09 06:18:13 +00:00
2011-06-08 22:02:00 +00:00
2012-09-05 11:09:38 +00:00
class PronterWindow ( MainWindow , pronsole . pronsole ) :
2012-08-08 07:38:48 +00:00
def __init__ ( self , filename = None , size = winsize ) :
2011-06-18 09:54:50 +00:00
pronsole . pronsole . __init__ ( self )
2013-04-07 17:45:45 +00:00
self . settings . build_dimensions = ' 200x200x100+0+0+0+0+0+0 ' #default build dimensions are 200x200x100 with 0, 0, 0 in the corner of the bed
2011-12-20 11:48:23 +00:00
self . settings . last_bed_temperature = 0.0
2011-06-29 21:32:24 +00:00
self . settings . last_file_path = " "
2011-07-19 08:02:48 +00:00
self . settings . last_temperature = 0.0
2011-12-20 11:48:23 +00:00
self . settings . preview_extrusion_width = 0.5
2011-08-07 20:00:13 +00:00
self . settings . preview_grid_step1 = 10.
self . settings . preview_grid_step2 = 50.
2012-01-19 08:26:23 +00:00
self . settings . bgcolor = " #FFFFFF "
2013-04-07 17:45:45 +00:00
self . pauseScript = " pause.gcode "
self . endScript = " end.gcode "
self . helpdict [ " build_dimensions " ] = _ ( " Dimensions of Build Platform \n & optional offset of origin \n & optional switch position \n \n Examples: \n XXXxYYY \n XXX,YYY,ZZZ \n XXXxYYYxZZZ+OffX+OffY+OffZ \n XXXxYYYxZZZ+OffX+OffY+OffZ+HomeX+HomeY+HomeZ " )
2011-12-20 11:48:23 +00:00
self . helpdict [ " last_bed_temperature " ] = _ ( " Last Set Temperature for the Heated Print Bed " )
self . helpdict [ " last_file_path " ] = _ ( " Folder of last opened file " )
self . helpdict [ " last_temperature " ] = _ ( " Last Temperature of the Hot End " )
self . helpdict [ " preview_extrusion_width " ] = _ ( " Width of Extrusion in Preview (default: 0.5) " )
self . helpdict [ " preview_grid_step1 " ] = _ ( " Fine Grid Spacing (default: 10) " )
self . helpdict [ " preview_grid_step2 " ] = _ ( " Coarse Grid Spacing (default: 50) " )
2012-01-19 08:26:23 +00:00
self . helpdict [ " bgcolor " ] = _ ( " Pronterface background color (default: #FFFFFF) " )
2012-08-08 07:38:48 +00:00
self . filename = filename
2012-08-08 07:58:09 +00:00
os . putenv ( " UBUNTU_MENUPROXY " , " 0 " )
2012-09-05 11:09:38 +00:00
MainWindow . __init__ ( self , None , title = _ ( " Printer Interface " ) , size = size ) ;
2012-08-08 07:58:09 +00:00
self . SetIcon ( wx . Icon ( pixmapfile ( " P-face.ico " ) , wx . BITMAP_TYPE_ICO ) )
2012-08-08 07:38:48 +00:00
self . panel = wx . Panel ( self , - 1 , size = size )
2012-01-07 07:33:34 +00:00
2012-08-08 07:38:48 +00:00
self . statuscheck = False
self . status_thread = None
2012-08-08 07:58:09 +00:00
self . capture_skip = { }
2012-08-08 07:38:48 +00:00
self . capture_skip_newline = False
self . tempreport = " "
self . monitor = 0
self . f = None
self . skeinp = None
self . monitor_interval = 3
self . paused = False
2013-05-18 16:38:54 +00:00
self . sentlines = Queue . Queue ( 0 )
2012-08-08 07:58:09 +00:00
self . cpbuttons = [
2012-09-05 14:32:35 +00:00
SpecialButton ( _ ( " Motors off " ) , ( " M84 " ) , ( 250 , 250 , 250 ) , None , 0 , _ ( " Switch all motors off " ) ) ,
SpecialButton ( _ ( " Check temp " ) , ( " M105 " ) , ( 225 , 200 , 200 ) , ( 2 , 5 ) , ( 1 , 1 ) , _ ( " Check current hotend temperature " ) ) ,
SpecialButton ( _ ( " Extrude " ) , ( " extrude " ) , ( 225 , 200 , 200 ) , ( 4 , 0 ) , ( 1 , 2 ) , _ ( " Advance extruder by set length " ) ) ,
SpecialButton ( _ ( " Reverse " ) , ( " reverse " ) , ( 225 , 200 , 200 ) , ( 5 , 0 ) , ( 1 , 2 ) , _ ( " Reverse extruder by set length " ) ) ,
2011-06-09 06:18:13 +00:00
]
2012-08-08 07:58:09 +00:00
self . custombuttons = [ ]
self . btndict = { }
2011-07-04 09:02:30 +00:00
self . parse_cmdline ( sys . argv [ 1 : ] )
2011-12-11 09:11:47 +00:00
self . build_dimensions_list = self . get_build_dimensions ( self . settings . build_dimensions )
2013-04-06 16:22:56 +00:00
#initialize the code analyzer with the correct sizes. There must be a more general way to do so
2013-04-08 11:06:31 +00:00
# minimum = offset
2013-04-07 17:45:45 +00:00
self . p . analyzer . minX = self . build_dimensions_list [ 3 ]
self . p . analyzer . minY = self . build_dimensions_list [ 4 ]
self . p . analyzer . minZ = self . build_dimensions_list [ 5 ]
2013-04-06 16:22:56 +00:00
2013-04-08 11:06:31 +00:00
#max = offset + bedsize
self . p . analyzer . maxX = self . build_dimensions_list [ 3 ] + self . build_dimensions_list [ 0 ]
self . p . analyzer . maxY = self . build_dimensions_list [ 4 ] + self . build_dimensions_list [ 1 ]
self . p . analyzer . maxZ = self . build_dimensions_list [ 5 ] + self . build_dimensions_list [ 2 ]
2013-04-07 17:45:45 +00:00
self . p . analyzer . homeX = self . build_dimensions_list [ 6 ]
self . p . analyzer . homeY = self . build_dimensions_list [ 7 ]
self . p . analyzer . homeZ = self . build_dimensions_list [ 8 ]
2013-04-06 16:22:56 +00:00
#set feedrates in printcore for pause/resume
self . p . xy_feedrate = self . settings . xy_feedrate
self . p . z_feedrate = self . settings . z_feedrate
2013-04-07 17:45:45 +00:00
#make printcore aware of me
self . p . pronterface = self
2013-04-06 16:22:56 +00:00
2012-01-07 07:33:34 +00:00
self . panel . SetBackgroundColour ( self . settings . bgcolor )
2012-08-08 07:58:09 +00:00
customdict = { }
2011-06-24 23:28:36 +00:00
try :
2012-08-08 07:58:09 +00:00
execfile ( configfile ( " custombtn.txt " ) , customdict )
2012-03-20 17:57:57 +00:00
if len ( customdict [ " btns " ] ) :
2011-08-04 11:03:35 +00:00
if not len ( self . custombuttons ) :
try :
self . custombuttons = customdict [ " btns " ]
for n in xrange ( len ( self . custombuttons ) ) :
2012-08-08 07:38:48 +00:00
self . cbutton_save ( n , self . custombuttons [ n ] )
2012-08-08 07:58:09 +00:00
os . rename ( " custombtn.txt " , " custombtn.old " )
rco = open ( " custombtn.txt " , " w " )
2011-08-06 23:45:52 +00:00
rco . write ( _ ( " # I moved all your custom buttons into .pronsolerc. \n # Please don ' t add them here any more. \n # Backup of your old buttons is in custombtn.old \n " ) )
2011-08-04 11:03:35 +00:00
rco . close ( )
2012-08-08 07:38:48 +00:00
except IOError , x :
2011-08-04 11:03:35 +00:00
print str ( x )
else :
2011-08-06 23:45:52 +00:00
print _ ( " Note!!! You have specified custom buttons in both custombtn.txt and .pronsolerc " )
print _ ( " Ignoring custombtn.txt. Remove all current buttons to revert to custombtn.txt " )
2012-03-20 17:57:57 +00:00
2011-06-24 23:28:36 +00:00
except :
pass
2011-06-08 14:19:38 +00:00
self . popmenu ( )
2012-09-05 11:09:38 +00:00
self . createGui ( )
2012-08-08 07:38:48 +00:00
self . t = Tee ( self . catchprint )
self . stdout = sys . stdout
self . skeining = 0
self . mini = False
self . p . sendcb = self . sentcb
self . p . startcb = self . startcb
self . p . endcb = self . endcb
self . starttime = 0
self . extra_print_time = 0
self . curlayer = 0
self . cur_button = None
2012-08-06 17:18:45 +00:00
self . predisconnect_mainqueue = None
self . predisconnect_queueindex = None
self . predisconnect_layer = None
2012-08-08 07:38:48 +00:00
self . hsetpoint = 0.0
self . bsetpoint = 0.0
2012-09-02 09:48:31 +00:00
if self . filename is not None :
2012-09-05 08:11:48 +00:00
self . do_load ( self . filename )
2012-03-20 17:57:57 +00:00
2013-05-17 15:04:41 +00:00
def add_cmdline_arguments ( self , parser ) :
pronsole . pronsole . add_cmdline_arguments ( self , parser )
parser . add_argument ( ' -g ' , ' --gauges ' , help = _ ( " display graphical temperature gauges in addition to the temperatures graph " ) , action = " store_true " )
def process_cmdline_arguments ( self , args ) :
pronsole . pronsole . process_cmdline_arguments ( self , args )
self . display_gauges = args . gauges
2011-07-17 10:53:13 +00:00
def startcb ( self ) :
2012-08-08 07:38:48 +00:00
self . starttime = time . time ( )
2012-08-04 09:02:17 +00:00
print " Print Started at: " + format_time ( self . starttime )
2012-03-20 17:57:57 +00:00
2011-07-17 10:53:13 +00:00
def endcb ( self ) :
2012-08-08 07:58:09 +00:00
if self . p . queueindex == 0 :
2012-08-07 11:54:07 +00:00
print_duration = int ( time . time ( ) - self . starttime + self . extra_print_time )
2013-05-16 20:50:28 +00:00
print _ ( " Print ended at: %(end_time)s and took %(duration)s " ) % { " end_time " : format_time ( time . time ( ) ) ,
2013-05-16 18:47:39 +00:00
" duration " : format_duration ( print_duration ) }
2011-08-06 12:48:10 +00:00
wx . CallAfter ( self . pausebtn . Disable )
2012-08-08 07:38:48 +00:00
wx . CallAfter ( self . printbtn . SetLabel , _ ( " Print " ) )
2012-03-20 17:57:57 +00:00
2013-04-07 17:45:45 +00:00
self . p . runSmallScript ( self . endScript )
2012-05-03 20:55:41 +00:00
param = self . settings . final_command
2012-08-07 08:58:28 +00:00
if not param :
return
2012-08-08 07:58:09 +00:00
pararray = [ i . replace ( " $s " , str ( self . filename ) ) . replace ( " $t " , format_duration ( print_duration ) ) . encode ( ) for i in shlex . split ( param . replace ( " \\ " , " \\ \\ " ) . encode ( ) ) ]
2012-08-08 07:38:48 +00:00
self . finalp = subprocess . Popen ( pararray , stderr = subprocess . STDOUT , stdout = subprocess . PIPE )
2012-03-20 17:57:57 +00:00
2011-06-22 10:21:04 +00:00
def online ( self ) :
2011-10-07 16:31:23 +00:00
print _ ( " Printer is now online. " )
2012-02-26 01:08:57 +00:00
self . connectbtn . SetLabel ( _ ( " Disconnect " ) )
2012-05-08 13:53:33 +00:00
self . connectbtn . SetToolTip ( wx . ToolTip ( " Disconnect from the printer " ) )
2012-08-08 07:38:48 +00:00
self . connectbtn . Bind ( wx . EVT_BUTTON , self . disconnect )
2011-12-04 01:17:19 +00:00
2011-07-09 13:38:49 +00:00
for i in self . printerControls :
2011-07-27 15:23:28 +00:00
wx . CallAfter ( i . Enable )
2011-11-11 16:37:01 +00:00
# Enable XYButtons and ZButtons
2011-11-14 15:20:32 +00:00
wx . CallAfter ( self . xyb . enable )
wx . CallAfter ( self . zb . enable )
2011-11-11 16:37:01 +00:00
2011-07-09 13:54:59 +00:00
if self . filename :
2011-07-27 15:23:28 +00:00
wx . CallAfter ( self . printbtn . Enable )
2012-03-20 17:57:57 +00:00
2012-08-04 08:30:58 +00:00
def sentcb ( self , line ) :
if " G1 " in line :
if " Z " in line :
2011-06-22 11:40:27 +00:00
try :
2013-05-17 14:48:53 +00:00
layer = float ( line . split ( " Z " ) [ 1 ] . split ( ) [ 0 ] . split ( " * " ) [ 0 ] )
2012-08-04 08:30:58 +00:00
if layer != self . curlayer :
self . curlayer = layer
self . gviz . hilight = [ ]
threading . Thread ( target = wx . CallAfter , args = ( self . gviz . setlayer , layer ) ) . start ( )
2011-06-22 11:40:27 +00:00
except :
pass
2011-11-22 18:08:00 +00:00
try :
self . sentlines . put_nowait ( line )
2013-05-18 16:38:54 +00:00
except Queue . Full :
2011-11-22 18:08:00 +00:00
pass
2012-08-08 07:38:48 +00:00
#threading.Thread(target = self.gviz.addgcode, args = (line, 1)).start()
#self.gwindow.p.addgcode(line, hilight = 1)
2012-08-04 08:30:58 +00:00
if " M104 " in line or " M109 " in line :
if " S " in line :
2012-03-20 22:52:00 +00:00
try :
2012-08-04 08:30:58 +00:00
temp = float ( line . split ( " S " ) [ 1 ] . split ( " * " ) [ 0 ] )
2013-05-17 14:59:28 +00:00
if self . display_gauges : wx . CallAfter ( self . hottgauge . SetTarget , temp )
2012-08-04 08:30:58 +00:00
wx . CallAfter ( self . graph . SetExtruder0TargetTemperature , temp )
2012-03-20 22:52:00 +00:00
except :
pass
try :
self . sentlines . put_nowait ( line )
except :
pass
2012-08-04 08:30:58 +00:00
if " M140 " in line :
if " S " in line :
2012-03-20 22:52:00 +00:00
try :
2012-08-04 08:30:58 +00:00
temp = float ( line . split ( " S " ) [ 1 ] . split ( " * " ) [ 0 ] )
2013-05-17 14:59:28 +00:00
if self . display_gauges : wx . CallAfter ( self . bedtgauge . SetTarget , temp )
2012-08-04 08:30:58 +00:00
wx . CallAfter ( self . graph . SetBedTargetTemperature , temp )
2012-03-20 22:52:00 +00:00
except :
pass
try :
self . sentlines . put_nowait ( line )
except :
pass
2012-03-20 17:57:57 +00:00
2012-08-04 08:30:58 +00:00
def do_extrude ( self , l = " " ) :
2011-06-09 13:19:03 +00:00
try :
2012-08-04 08:30:58 +00:00
if not l . __class__ in ( str , unicode ) or not len ( l ) :
l = str ( self . edist . GetValue ( ) )
pronsole . pronsole . do_extrude ( self , l )
2011-06-09 13:19:03 +00:00
except :
raise
2012-03-20 17:57:57 +00:00
2012-08-04 08:30:58 +00:00
def do_reverse ( self , l = " " ) :
2011-06-09 13:19:03 +00:00
try :
2012-08-04 08:30:58 +00:00
if not l . __class__ in ( str , unicode ) or not len ( l ) :
l = str ( - float ( self . edist . GetValue ( ) ) )
2012-08-08 07:38:48 +00:00
pronsole . pronsole . do_extrude ( self , l )
2011-06-09 13:19:03 +00:00
except :
pass
2012-03-20 17:57:57 +00:00
2012-08-04 08:30:58 +00:00
def setbedgui ( self , f ) :
self . bsetpoint = f
2013-05-17 14:59:28 +00:00
if self . display_gauges : self . bedtgauge . SetTarget ( int ( f ) )
2012-08-04 08:30:58 +00:00
wx . CallAfter ( self . graph . SetBedTargetTemperature , int ( f ) )
2012-07-15 11:43:34 +00:00
if f > 0 :
2012-08-04 08:30:58 +00:00
wx . CallAfter ( self . btemp . SetValue , str ( f ) )
self . set ( " last_bed_temperature " , str ( f ) )
2013-03-28 00:45:30 +00:00
wx . CallAfter ( self . setboff . SetBackgroundColour , None )
wx . CallAfter ( self . setboff . SetForegroundColour , None )
2012-08-04 08:30:58 +00:00
wx . CallAfter ( self . setbbtn . SetBackgroundColour , " #FFAA66 " )
wx . CallAfter ( self . setbbtn . SetForegroundColour , " #660000 " )
wx . CallAfter ( self . btemp . SetBackgroundColour , " #FFDABB " )
2012-07-15 11:43:34 +00:00
else :
2012-08-04 08:30:58 +00:00
wx . CallAfter ( self . setboff . SetBackgroundColour , " #0044CC " )
wx . CallAfter ( self . setboff . SetForegroundColour , " white " )
2013-03-28 00:45:30 +00:00
wx . CallAfter ( self . setbbtn . SetBackgroundColour , None )
wx . CallAfter ( self . setbbtn . SetForegroundColour , None )
2012-08-04 08:30:58 +00:00
wx . CallAfter ( self . btemp . SetBackgroundColour , " white " )
2012-07-15 11:43:34 +00:00
wx . CallAfter ( self . btemp . Refresh )
2012-08-04 08:30:58 +00:00
def sethotendgui ( self , f ) :
self . hsetpoint = f
2013-05-17 14:59:28 +00:00
if self . display_gauges : self . hottgauge . SetTarget ( int ( f ) )
2012-08-04 08:30:58 +00:00
wx . CallAfter ( self . graph . SetExtruder0TargetTemperature , int ( f ) )
if f > 0 :
wx . CallAfter ( self . htemp . SetValue , str ( f ) )
self . set ( " last_temperature " , str ( f ) )
2013-03-28 00:45:30 +00:00
wx . CallAfter ( self . settoff . SetBackgroundColour , None )
wx . CallAfter ( self . settoff . SetForegroundColour , None )
2012-08-04 08:30:58 +00:00
wx . CallAfter ( self . settbtn . SetBackgroundColour , " #FFAA66 " )
wx . CallAfter ( self . settbtn . SetForegroundColour , " #660000 " )
wx . CallAfter ( self . htemp . SetBackgroundColour , " #FFDABB " )
2012-07-15 11:43:34 +00:00
else :
2012-08-04 08:30:58 +00:00
wx . CallAfter ( self . settoff . SetBackgroundColour , " #0044CC " )
wx . CallAfter ( self . settoff . SetForegroundColour , " white " )
2013-03-28 00:45:30 +00:00
wx . CallAfter ( self . settbtn . SetBackgroundColour , None )
wx . CallAfter ( self . settbtn . SetForegroundColour , None )
2012-08-04 08:30:58 +00:00
wx . CallAfter ( self . htemp . SetBackgroundColour , " white " )
2012-07-15 11:43:34 +00:00
wx . CallAfter ( self . htemp . Refresh )
2012-08-08 06:39:50 +00:00
2012-08-04 08:30:58 +00:00
def do_settemp ( self , l = " " ) :
2011-06-09 10:54:03 +00:00
try :
2012-08-04 08:30:58 +00:00
if not l . __class__ in ( str , unicode ) or not len ( l ) :
l = str ( self . htemp . GetValue ( ) . split ( ) [ 0 ] )
2012-08-08 07:58:09 +00:00
l = l . lower ( ) . replace ( " , " , " . " )
2011-06-09 10:54:03 +00:00
for i in self . temps . keys ( ) :
2012-08-04 08:30:58 +00:00
l = l . replace ( i , self . temps [ i ] )
f = float ( l )
if f > = 0 :
2011-06-09 10:54:03 +00:00
if self . p . online :
self . p . send_now ( " M104 S " + l )
2012-02-26 01:14:06 +00:00
print _ ( " Setting hotend temperature to %f degrees Celsius. " ) % f
2012-07-15 11:43:34 +00:00
self . sethotendgui ( f )
2011-06-09 10:54:03 +00:00
else :
2011-08-06 23:45:52 +00:00
print _ ( " Printer is not online. " )
2011-06-09 10:54:03 +00:00
else :
2011-08-06 23:45:52 +00:00
print _ ( " You cannot set negative temperatures. To turn the hotend off entirely, set its temperature to 0. " )
2012-08-04 08:30:58 +00:00
except Exception , x :
2012-08-04 19:51:07 +00:00
print _ ( " You must enter a temperature. ( %s ) " ) % ( repr ( x ) , )
2012-03-20 17:57:57 +00:00
2012-08-04 08:30:58 +00:00
def do_bedtemp ( self , l = " " ) :
2011-06-09 10:54:03 +00:00
try :
2012-08-04 08:30:58 +00:00
if not l . __class__ in ( str , unicode ) or not len ( l ) :
l = str ( self . btemp . GetValue ( ) . split ( ) [ 0 ] )
2012-08-08 07:58:09 +00:00
l = l . lower ( ) . replace ( " , " , " . " )
2011-06-09 10:54:03 +00:00
for i in self . bedtemps . keys ( ) :
2012-08-04 08:30:58 +00:00
l = l . replace ( i , self . bedtemps [ i ] )
f = float ( l )
if f > = 0 :
2011-06-09 10:54:03 +00:00
if self . p . online :
self . p . send_now ( " M140 S " + l )
2012-02-26 01:14:06 +00:00
print _ ( " Setting bed temperature to %f degrees Celsius. " ) % f
2012-07-15 11:43:34 +00:00
self . setbedgui ( f )
2011-06-09 10:54:03 +00:00
else :
2011-08-06 23:45:52 +00:00
print _ ( " Printer is not online. " )
2011-06-09 10:54:03 +00:00
else :
2011-08-06 23:45:52 +00:00
print _ ( " You cannot set negative temperatures. To turn the bed off entirely, set its temperature to 0. " )
2012-08-04 19:51:07 +00:00
except Exception , x :
print _ ( " You must enter a temperature. ( %s ) " ) % ( repr ( x ) , )
2012-03-20 17:57:57 +00:00
2011-07-26 14:34:55 +00:00
def end_macro ( self ) :
pronsole . pronsole . end_macro ( self )
self . update_macros_menu ( )
2012-03-20 17:57:57 +00:00
2012-08-04 08:30:58 +00:00
def delete_macro ( self , macro_name ) :
pronsole . pronsole . delete_macro ( self , macro_name )
2011-07-26 14:34:55 +00:00
self . update_macros_menu ( )
2012-03-20 17:57:57 +00:00
2012-08-08 07:38:48 +00:00
def start_macro ( self , macro_name , old_macro_definition = " " ) :
2011-07-06 21:19:45 +00:00
if not self . processing_rc :
def cb ( definition ) :
2012-08-04 08:30:58 +00:00
if len ( definition . strip ( ) ) == 0 :
if old_macro_definition != " " :
dialog = wx . MessageDialog ( self , _ ( " Do you want to erase the macro? " ) , style = wx . YES_NO | wx . YES_DEFAULT | wx . ICON_QUESTION )
if dialog . ShowModal ( ) == wx . ID_YES :
2011-07-26 14:34:55 +00:00
self . delete_macro ( macro_name )
return
2011-08-06 23:45:52 +00:00
print _ ( " Cancelled. " )
2011-07-26 14:34:55 +00:00
return
2011-08-04 11:03:35 +00:00
self . cur_macro_name = macro_name
self . cur_macro_def = definition
self . end_macro ( )
2012-09-05 15:30:28 +00:00
MacroEditor ( macro_name , old_macro_definition , cb )
2011-07-06 21:19:45 +00:00
else :
2012-08-04 08:30:58 +00:00
pronsole . pronsole . start_macro ( self , macro_name , old_macro_definition )
2012-03-20 17:57:57 +00:00
2012-08-04 08:30:58 +00:00
def catchprint ( self , l ) :
2012-02-13 07:39:10 +00:00
if self . capture_skip_newline and len ( l ) and not len ( l . strip ( " \n \r " ) ) :
self . capture_skip_newline = False
return
for pat in self . capture_skip . keys ( ) :
if self . capture_skip [ pat ] > 0 and pat . match ( l ) :
self . capture_skip [ pat ] - = 1
self . capture_skip_newline = True
2012-01-05 17:56:00 +00:00
return
2012-08-20 06:23:19 +00:00
wx . CallAfter ( self . addtexttolog , l ) ;
2012-03-20 17:57:57 +00:00
2011-06-08 14:19:38 +00:00
def scanserial ( self ) :
""" scan for available ports. return a list of device names. """
2012-08-04 08:30:58 +00:00
baselist = [ ]
if os . name == " nt " :
2011-06-08 14:19:38 +00:00
try :
2012-08-08 07:58:09 +00:00
key = _winreg . OpenKey ( _winreg . HKEY_LOCAL_MACHINE , " HARDWARE \\ DEVICEMAP \\ SERIALCOMM " )
2012-08-04 08:30:58 +00:00
i = 0
while True :
baselist + = [ _winreg . EnumValue ( key , i ) [ 1 ] ]
i + = 1
2011-06-08 14:19:38 +00:00
except :
pass
2012-08-04 08:30:58 +00:00
return baselist + glob . glob ( ' /dev/ttyUSB* ' ) + glob . glob ( ' /dev/ttyACM* ' ) + glob . glob ( " /dev/tty.* " ) + glob . glob ( " /dev/cu.* " ) + glob . glob ( " /dev/rfcomm* " )
2012-03-20 17:57:57 +00:00
2012-01-10 14:05:56 +00:00
def project ( self , event ) :
2012-09-02 09:17:08 +00:00
from printrun import projectlayer
2012-09-05 08:10:05 +00:00
if self . p . online :
2012-01-10 14:05:56 +00:00
projectlayer . setframe ( self , self . p ) . Show ( )
else :
print _ ( " Printer is not online. " )
2012-03-20 17:57:57 +00:00
2011-06-08 14:19:38 +00:00
def popmenu ( self ) :
self . menustrip = wx . MenuBar ( )
2011-09-06 15:48:16 +00:00
# File menu
2011-09-06 16:55:52 +00:00
m = wx . Menu ( )
2012-08-04 08:30:58 +00:00
self . Bind ( wx . EVT_MENU , self . loadfile , m . Append ( - 1 , _ ( " &Open... " ) , _ ( " Opens file " ) ) )
self . Bind ( wx . EVT_MENU , self . do_editgcode , m . Append ( - 1 , _ ( " &Edit... " ) , _ ( " Edit open file " ) ) )
self . Bind ( wx . EVT_MENU , self . clearOutput , m . Append ( - 1 , _ ( " Clear console " ) , _ ( " Clear output console " ) ) )
self . Bind ( wx . EVT_MENU , self . project , m . Append ( - 1 , _ ( " Projector " ) , _ ( " Project slices " ) ) )
self . Bind ( wx . EVT_MENU , self . OnExit , m . Append ( wx . ID_EXIT , _ ( " E&xit " ) , _ ( " Closes the Window " ) ) )
self . menustrip . Append ( m , _ ( " &File " ) )
2012-03-20 17:57:57 +00:00
2011-09-06 16:55:52 +00:00
# Settings menu
m = wx . Menu ( )
2011-09-06 15:48:16 +00:00
self . macros_menu = wx . Menu ( )
m . AppendSubMenu ( self . macros_menu , _ ( " &Macros " ) )
self . Bind ( wx . EVT_MENU , self . new_macro , self . macros_menu . Append ( - 1 , _ ( " <&New...> " ) ) )
2012-08-08 07:58:09 +00:00
self . Bind ( wx . EVT_MENU , lambda * e : options ( self ) , m . Append ( - 1 , _ ( " &Options " ) , _ ( " Options dialog " ) ) )
2012-03-20 17:57:57 +00:00
2012-08-04 08:30:58 +00:00
self . Bind ( wx . EVT_MENU , lambda x : threading . Thread ( target = lambda : self . do_skein ( " set " ) ) . start ( ) , m . Append ( - 1 , _ ( " Slicing Settings " ) , _ ( " Adjust slicing settings " ) ) )
2012-08-12 16:03:11 +00:00
mItem = m . AppendCheckItem ( - 1 , _ ( " Debug G-code " ) ,
_ ( " Print all G-code sent to and received from the printer. " ) )
m . Check ( mItem . GetId ( ) , self . p . loud )
self . Bind ( wx . EVT_MENU , self . setloud , mItem )
2011-11-18 08:52:16 +00:00
#try:
# from SkeinforgeQuickEditDialog import SkeinforgeQuickEditDialog
# self.Bind(wx.EVT_MENU, lambda *e:SkeinforgeQuickEditDialog(self), m.Append(-1,_("SFACT Quick Settings"),_(" Quickly adjust SFACT settings for active profile")))
#except:
# pass
2011-09-06 19:26:37 +00:00
2012-08-04 08:30:58 +00:00
self . menustrip . Append ( m , _ ( " &Settings " ) )
2011-07-26 14:34:55 +00:00
self . update_macros_menu ( )
2011-06-08 14:19:38 +00:00
self . SetMenuBar ( self . menustrip )
2012-03-20 17:57:57 +00:00
2012-08-04 08:30:58 +00:00
def doneediting ( self , gcode ) :
f = open ( self . filename , " w " )
2011-08-06 13:28:25 +00:00
f . write ( " \n " . join ( gcode ) )
f . close ( )
2012-08-04 08:30:58 +00:00
wx . CallAfter ( self . loadfile , None , self . filename )
2012-03-20 17:57:57 +00:00
2012-08-04 08:30:58 +00:00
def do_editgcode ( self , e = None ) :
if self . filename is not None :
2012-09-05 15:30:28 +00:00
MacroEditor ( self . filename , self . f , self . doneediting , 1 )
2012-03-20 17:57:57 +00:00
2012-08-04 08:30:58 +00:00
def new_macro ( self , e = None ) :
dialog = wx . Dialog ( self , - 1 , _ ( " Enter macro name " ) , size = ( 260 , 85 ) )
panel = wx . Panel ( dialog , - 1 )
2011-07-26 14:34:55 +00:00
vbox = wx . BoxSizer ( wx . VERTICAL )
2012-08-04 08:30:58 +00:00
wx . StaticText ( panel , - 1 , _ ( " Macro name: " ) , ( 8 , 14 ) )
2012-08-08 07:38:48 +00:00
dialog . namectrl = wx . TextCtrl ( panel , - 1 , ' ' , ( 110 , 8 ) , size = ( 130 , 24 ) , style = wx . TE_PROCESS_ENTER )
2011-07-26 14:34:55 +00:00
hbox = wx . BoxSizer ( wx . HORIZONTAL )
2012-08-04 08:30:58 +00:00
okb = wx . Button ( dialog , wx . ID_OK , _ ( " Ok " ) , size = ( 60 , 24 ) )
dialog . Bind ( wx . EVT_TEXT_ENTER , lambda e : dialog . EndModal ( wx . ID_OK ) , dialog . namectrl )
#dialog.Bind(wx.EVT_BUTTON, lambda e:self.new_macro_named(dialog, e), okb)
2011-07-26 14:34:55 +00:00
hbox . Add ( okb )
2012-08-04 08:30:58 +00:00
hbox . Add ( wx . Button ( dialog , wx . ID_CANCEL , _ ( " Cancel " ) , size = ( 60 , 24 ) ) )
2011-07-26 14:34:55 +00:00
vbox . Add ( panel )
2012-08-04 08:30:58 +00:00
vbox . Add ( hbox , 1 , wx . ALIGN_CENTER | wx . TOP | wx . BOTTOM , 10 )
2011-07-26 14:34:55 +00:00
dialog . SetSizer ( vbox )
dialog . Centre ( )
2011-08-04 11:03:35 +00:00
macro = " "
2012-08-04 08:30:58 +00:00
if dialog . ShowModal ( ) == wx . ID_OK :
2011-08-04 11:03:35 +00:00
macro = dialog . namectrl . GetValue ( )
if macro != " " :
2012-08-04 08:30:58 +00:00
wx . CallAfter ( self . edit_macro , macro )
2011-08-04 11:03:35 +00:00
dialog . Destroy ( )
return macro
2012-03-20 17:57:57 +00:00
2012-08-04 08:30:58 +00:00
def edit_macro ( self , macro ) :
2011-08-04 11:03:35 +00:00
if macro == " " : return self . new_macro ( )
if self . macros . has_key ( macro ) :
old_def = self . macros [ macro ]
2012-08-08 07:58:09 +00:00
elif len ( [ c for c in macro . encode ( " ascii " , " replace " ) if not c . isalnum ( ) and c != " _ " ] ) :
2012-07-23 12:48:18 +00:00
print _ ( " Macro name may contain only ASCII alphanumeric symbols and underscores " )
2011-08-04 11:03:35 +00:00
return
2012-08-08 07:58:09 +00:00
elif hasattr ( self . __class__ , " do_ " + macro ) :
2012-07-23 12:48:18 +00:00
print _ ( " Name ' %s ' is being used by built-in command " ) % macro
return
2011-08-04 11:03:35 +00:00
else :
old_def = " "
2012-08-08 07:38:48 +00:00
self . start_macro ( macro , old_def )
2011-08-04 11:03:35 +00:00
return macro
2012-03-20 17:57:57 +00:00
2011-07-26 14:34:55 +00:00
def update_macros_menu ( self ) :
2012-08-08 07:58:09 +00:00
if not hasattr ( self , " macros_menu " ) :
2011-07-26 14:34:55 +00:00
return # too early, menu not yet built
try :
while True :
item = self . macros_menu . FindItemByPosition ( 1 )
if item is None : return
self . macros_menu . DeleteItem ( item )
except :
pass
for macro in self . macros . keys ( ) :
2012-08-04 08:30:58 +00:00
self . Bind ( wx . EVT_MENU , lambda x , m = macro : self . start_macro ( m , self . macros [ m ] ) , self . macros_menu . Append ( - 1 , macro ) )
2011-07-26 14:34:55 +00:00
2011-06-08 14:19:38 +00:00
def OnExit ( self , event ) :
self . Close ( )
2012-03-20 17:57:57 +00:00
2012-08-04 08:30:58 +00:00
def rescanports ( self , event = None ) :
scan = self . scanserial ( )
portslist = list ( scan )
2011-10-07 12:11:58 +00:00
if self . settings . port != " " and self . settings . port not in portslist :
portslist + = [ self . settings . port ]
2011-11-13 20:44:45 +00:00
self . serialport . Clear ( )
self . serialport . AppendItems ( portslist )
2011-06-09 06:18:13 +00:00
try :
2011-12-28 19:08:01 +00:00
if os . path . exists ( self . settings . port ) or self . settings . port in scan :
2011-06-29 20:34:27 +00:00
self . serialport . SetValue ( self . settings . port )
2012-08-04 08:30:58 +00:00
elif len ( portslist ) > 0 :
2011-10-07 12:11:58 +00:00
self . serialport . SetValue ( portslist [ 0 ] )
2011-06-09 06:18:13 +00:00
except :
pass
2012-03-20 17:57:57 +00:00
2012-08-08 07:38:48 +00:00
def cbkey ( self , e ) :
if e . GetKeyCode ( ) == wx . WXK_UP :
if self . commandbox . histindex == len ( self . commandbox . history ) :
2012-07-15 12:27:22 +00:00
self . commandbox . history + = [ self . commandbox . GetValue ( ) ] #save current command
2012-07-15 12:22:57 +00:00
if len ( self . commandbox . history ) :
2012-08-08 07:38:48 +00:00
self . commandbox . histindex = ( self . commandbox . histindex - 1 ) % len ( self . commandbox . history )
2012-07-15 12:22:57 +00:00
self . commandbox . SetValue ( self . commandbox . history [ self . commandbox . histindex ] )
2012-08-08 07:38:48 +00:00
self . commandbox . SetSelection ( 0 , len ( self . commandbox . history [ self . commandbox . histindex ] ) )
elif e . GetKeyCode ( ) == wx . WXK_DOWN :
if self . commandbox . histindex == len ( self . commandbox . history ) :
2012-08-08 06:39:50 +00:00
self . commandbox . history + = [ self . commandbox . GetValue ( ) ] #save current command
2012-07-15 12:22:57 +00:00
if len ( self . commandbox . history ) :
2012-08-08 07:38:48 +00:00
self . commandbox . histindex = ( self . commandbox . histindex + 1 ) % len ( self . commandbox . history )
2012-07-15 12:22:57 +00:00
self . commandbox . SetValue ( self . commandbox . history [ self . commandbox . histindex ] )
2012-08-08 07:38:48 +00:00
self . commandbox . SetSelection ( 0 , len ( self . commandbox . history [ self . commandbox . histindex ] ) )
2012-07-15 12:22:57 +00:00
else :
e . Skip ( )
2012-08-08 07:38:48 +00:00
def plate ( self , e ) :
2011-11-18 08:52:16 +00:00
import plater
print " plate function activated "
2012-08-08 07:58:09 +00:00
plater . stlwin ( size = ( 800 , 580 ) , callback = self . platecb , parent = self ) . Show ( )
2012-03-20 17:57:57 +00:00
2012-08-08 07:38:48 +00:00
def platecb ( self , name ) :
2011-11-18 08:52:16 +00:00
print " plated: " + name
2012-08-08 07:38:48 +00:00
self . loadfile ( None , name )
2012-03-20 17:57:57 +00:00
2012-08-08 07:38:48 +00:00
def sdmenu ( self , e ) :
2011-11-18 08:52:16 +00:00
obj = e . GetEventObject ( )
2012-08-08 07:38:48 +00:00
popupmenu = wx . Menu ( )
item = popupmenu . Append ( - 1 , _ ( " SD Upload " ) )
2011-12-20 11:48:23 +00:00
if not self . f or not len ( self . f ) :
item . Enable ( False )
2012-08-08 07:38:48 +00:00
self . Bind ( wx . EVT_MENU , self . upload , id = item . GetId ( ) )
item = popupmenu . Append ( - 1 , _ ( " SD Print " ) )
self . Bind ( wx . EVT_MENU , self . sdprintfile , id = item . GetId ( ) )
2011-11-18 08:52:16 +00:00
self . panel . PopupMenu ( popupmenu , obj . GetPosition ( ) )
2012-03-20 17:57:57 +00:00
2012-08-08 07:38:48 +00:00
def htemp_change ( self , event ) :
2011-10-25 19:56:44 +00:00
if self . hsetpoint > 0 :
self . do_settemp ( " " )
2012-08-08 07:38:48 +00:00
wx . CallAfter ( self . htemp . SetInsertionPoint , 0 )
2011-10-25 19:56:44 +00:00
2012-08-08 07:38:48 +00:00
def btemp_change ( self , event ) :
2011-10-25 19:56:44 +00:00
if self . bsetpoint > 0 :
self . do_bedtemp ( " " )
2012-08-08 07:38:48 +00:00
wx . CallAfter ( self . btemp . SetInsertionPoint , 0 )
2012-03-20 17:57:57 +00:00
2012-08-08 07:38:48 +00:00
def showwin ( self , event ) :
2013-05-16 18:47:39 +00:00
if self . f is not None :
2011-12-03 22:05:30 +00:00
self . gwindow . Show ( True )
2012-05-08 13:53:33 +00:00
self . gwindow . SetToolTip ( wx . ToolTip ( " Mousewheel zooms the display \n Shift / Mousewheel scrolls layers " ) )
2012-01-07 19:06:46 +00:00
self . gwindow . Raise ( )
2011-12-03 22:05:30 +00:00
2012-08-08 07:38:48 +00:00
def setfeeds ( self , e ) :
2011-06-29 21:31:57 +00:00
self . feedrates_changed = True
2011-06-09 16:44:57 +00:00
try :
2012-08-08 07:58:09 +00:00
self . settings . _set ( " e_feedrate " , self . efeedc . GetValue ( ) )
2011-06-09 16:44:57 +00:00
except :
pass
try :
2012-08-08 07:58:09 +00:00
self . settings . _set ( " z_feedrate " , self . zfeedc . GetValue ( ) )
2011-06-09 16:44:57 +00:00
except :
pass
try :
2012-08-08 07:58:09 +00:00
self . settings . _set ( " xy_feedrate " , self . xyfeedc . GetValue ( ) )
2011-06-09 16:44:57 +00:00
except :
pass
2012-03-20 17:57:57 +00:00
2012-08-08 07:38:48 +00:00
def toggleview ( self , e ) :
2011-06-09 13:19:03 +00:00
if ( self . mini ) :
2012-08-08 07:38:48 +00:00
self . mini = False
2012-09-05 11:09:38 +00:00
self . mainsizer . Fit ( self )
2012-03-20 17:57:57 +00:00
2011-06-16 04:28:46 +00:00
#self.SetSize(winsize)
2011-08-06 23:45:52 +00:00
wx . CallAfter ( self . minibtn . SetLabel , _ ( " Mini mode " ) )
2012-03-20 17:57:57 +00:00
2011-06-09 13:19:03 +00:00
else :
2012-08-08 07:38:48 +00:00
self . mini = True
2011-06-16 04:28:46 +00:00
self . uppersizer . Fit ( self )
2012-03-20 17:57:57 +00:00
2011-06-16 04:28:46 +00:00
#self.SetSize(winssize)
2011-08-06 23:45:52 +00:00
wx . CallAfter ( self . minibtn . SetLabel , _ ( " Full mode " ) )
2012-03-20 17:57:57 +00:00
2011-08-03 11:26:16 +00:00
def cbuttons_reload ( self ) :
allcbs = [ ]
2012-09-05 11:09:38 +00:00
ubs = self . uppersizer
2012-08-08 07:38:48 +00:00
cs = self . centersizer
2012-04-30 17:51:03 +00:00
#for item in ubs.GetChildren():
# if hasattr(item.GetWindow(),"custombutton"):
2012-08-08 07:38:48 +00:00
# allcbs += [(ubs, item.GetWindow())]
2011-08-03 11:26:16 +00:00
for item in cs . GetChildren ( ) :
if hasattr ( item . GetWindow ( ) , " custombutton " ) :
2012-08-08 07:38:48 +00:00
allcbs + = [ ( cs , item . GetWindow ( ) ) ]
for sizer , button in allcbs :
2011-08-03 11:26:16 +00:00
#sizer.Remove(button)
button . Destroy ( )
2012-08-08 07:58:09 +00:00
self . custombuttonbuttons = [ ]
2011-11-14 19:35:18 +00:00
newbuttonbuttonindex = len ( self . custombuttons )
while newbuttonbuttonindex > 0 and self . custombuttons [ newbuttonbuttonindex - 1 ] is None :
newbuttonbuttonindex - = 1
2011-09-30 14:41:18 +00:00
while len ( self . custombuttons ) < 13 :
self . custombuttons . append ( None )
2011-08-03 11:26:16 +00:00
for i in xrange ( len ( self . custombuttons ) ) :
btndef = self . custombuttons [ i ]
try :
2012-09-05 14:32:35 +00:00
b = wx . Button ( self . panel , - 1 , btndef . label , style = wx . BU_EXACTFIT )
b . SetToolTip ( wx . ToolTip ( _ ( " Execute command: " ) + btndef . command ) )
if btndef . background :
b . SetBackgroundColour ( btndef . background )
2012-08-08 07:38:48 +00:00
rr , gg , bb = b . GetBackgroundColour ( ) . Get ( )
2011-08-03 11:26:16 +00:00
if 0.3 * rr + 0.59 * gg + 0.11 * bb < 60 :
b . SetForegroundColour ( " #ffffff " )
except :
2011-11-14 19:35:18 +00:00
if i == newbuttonbuttonindex :
2012-09-05 14:32:35 +00:00
self . newbuttonbutton = b = wx . Button ( self . panel , - 1 , " + " , size = ( 19 , 18 ) , style = wx . BU_EXACTFIT )
2012-08-08 07:38:48 +00:00
#b.SetFont(wx.Font(12, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD))
2011-11-14 19:35:18 +00:00
b . SetForegroundColour ( " #4444ff " )
2011-11-14 19:43:16 +00:00
b . SetToolTip ( wx . ToolTip ( _ ( " click to add new custom button " ) ) )
2012-08-08 07:38:48 +00:00
b . Bind ( wx . EVT_BUTTON , self . cbutton_edit )
2011-11-14 19:35:18 +00:00
else :
2012-08-08 07:58:09 +00:00
b = wx . Button ( self . panel , - 1 , " . " , size = ( 1 , 1 ) )
#b = wx.StaticText(self.panel,-1, "", size = (72, 22), style = wx.ALIGN_CENTRE+wx.ST_NO_AUTORESIZE) #+wx.SIMPLE_BORDER
2012-08-08 06:39:50 +00:00
b . Disable ( )
#continue
2012-08-08 07:38:48 +00:00
b . custombutton = i
b . properties = btndef
2011-11-08 19:05:39 +00:00
if btndef is not None :
2012-08-08 07:38:48 +00:00
b . Bind ( wx . EVT_BUTTON , self . procbutton )
b . Bind ( wx . EVT_MOUSE_EVENTS , self . editbutton )
2011-11-14 19:35:18 +00:00
#else:
2012-08-08 07:38:48 +00:00
# b.Bind(wx.EVT_BUTTON, lambda e:e.Skip())
2011-09-30 14:41:18 +00:00
self . custombuttonbuttons . append ( b )
2012-04-30 17:51:03 +00:00
#if i<4:
# ubs.Add(b)
#else:
2012-08-08 07:58:09 +00:00
cs . Add ( b , pos = ( ( i ) / 4 , ( i ) % 4 ) )
2012-09-05 11:09:38 +00:00
self . mainsizer . Layout ( )
2012-03-20 17:57:57 +00:00
2011-08-03 11:26:16 +00:00
def help_button ( self ) :
2011-08-06 23:45:52 +00:00
print _ ( ' Defines custom button. Usage: button <num> " title " [/c " colour " ] command ' )
2012-03-20 17:57:57 +00:00
2012-08-08 07:38:48 +00:00
def do_button ( self , argstr ) :
2011-08-03 11:26:16 +00:00
def nextarg ( rest ) :
2012-08-08 07:38:48 +00:00
rest = rest . lstrip ( )
2011-08-03 11:26:16 +00:00
if rest . startswith ( ' " ' ) :
2012-08-08 06:39:50 +00:00
return rest [ 1 : ] . split ( ' " ' , 1 )
2011-08-03 11:26:16 +00:00
else :
2012-08-08 07:38:48 +00:00
return rest . split ( None , 1 )
2011-08-03 11:26:16 +00:00
#try:
2012-08-08 07:38:48 +00:00
num , argstr = nextarg ( argstr )
num = int ( num )
title , argstr = nextarg ( argstr )
colour = None
2011-08-03 11:26:16 +00:00
try :
2012-08-08 07:38:48 +00:00
c1 , c2 = nextarg ( argstr )
if c1 == " /c " :
colour , argstr = nextarg ( c2 )
2011-08-03 11:26:16 +00:00
except :
pass
2012-08-08 07:38:48 +00:00
command = argstr . strip ( )
2011-08-03 11:26:16 +00:00
if num < 0 or num > = 64 :
2011-08-06 23:45:52 +00:00
print _ ( " Custom button number should be between 0 and 63 " )
2011-08-03 11:26:16 +00:00
return
while num > = len ( self . custombuttons ) :
2012-09-05 14:32:35 +00:00
self . custombuttons . append ( None )
self . custombuttons [ num ] = SpecialButton ( title , command )
2011-08-03 11:26:16 +00:00
if colour is not None :
2012-09-05 14:32:35 +00:00
self . custombuttons [ num ] . background = colour
2011-08-03 11:26:16 +00:00
if not self . processing_rc :
self . cbuttons_reload ( )
2012-08-08 07:38:48 +00:00
#except Exception, x:
2011-08-03 11:26:16 +00:00
# print "Bad syntax for button definition, see 'help button'"
# print x
2012-03-20 17:57:57 +00:00
2012-08-08 07:38:48 +00:00
def cbutton_save ( self , n , bdef , new_n = None ) :
if new_n is None : new_n = n
2011-08-03 11:26:16 +00:00
if bdef is None or bdef == " " :
self . save_in_rc ( ( " button %d " % n ) , ' ' )
2012-09-05 14:32:35 +00:00
elif bdef . background :
colour = bdef . background
2012-08-08 07:38:48 +00:00
if type ( colour ) not in ( str , unicode ) :
2012-08-08 07:58:09 +00:00
#print type(colour), map(type, colour)
2012-08-08 07:38:48 +00:00
if type ( colour ) == tuple and tuple ( map ( type , colour ) ) == ( int , int , int ) :
colour = map ( lambda x : x % 256 , colour )
2011-08-04 11:03:35 +00:00
colour = wx . Colour ( * colour ) . GetAsString ( wx . C2S_NAME | wx . C2S_HTML_SYNTAX )
else :
colour = wx . Colour ( colour ) . GetAsString ( wx . C2S_NAME | wx . C2S_HTML_SYNTAX )
2012-09-05 14:32:35 +00:00
self . save_in_rc ( ( " button %d " % n ) , ' button %d " %s " /c " %s " %s ' % ( new_n , bdef . label , colour , bdef . command ) )
2011-08-03 11:26:16 +00:00
else :
2012-09-05 14:32:35 +00:00
self . save_in_rc ( ( " button %d " % n ) , ' button %d " %s " %s ' % ( new_n , bdef . label , bdef . command ) )
2011-08-03 11:26:16 +00:00
2012-08-08 07:38:48 +00:00
def cbutton_edit ( self , e , button = None ) :
bedit = ButtonEdit ( self )
2011-08-03 11:26:16 +00:00
if button is not None :
n = button . custombutton
2012-09-06 17:32:23 +00:00
bedit . name . SetValue ( button . properties . label )
bedit . command . SetValue ( button . properties . command )
if button . properties . background :
colour = button . properties . background
2012-08-08 07:38:48 +00:00
if type ( colour ) not in ( str , unicode ) :
2011-08-04 11:03:35 +00:00
#print type(colour)
2012-08-08 07:38:48 +00:00
if type ( colour ) == tuple and tuple ( map ( type , colour ) ) == ( int , int , int ) :
colour = map ( lambda x : x % 256 , colour )
2011-08-04 11:03:35 +00:00
colour = wx . Colour ( * colour ) . GetAsString ( wx . C2S_NAME | wx . C2S_HTML_SYNTAX )
else :
colour = wx . Colour ( colour ) . GetAsString ( wx . C2S_NAME | wx . C2S_HTML_SYNTAX )
2011-08-03 11:26:16 +00:00
bedit . color . SetValue ( colour )
else :
n = len ( self . custombuttons )
2011-09-30 14:41:18 +00:00
while n > 0 and self . custombuttons [ n - 1 ] is None :
n - = 1
2012-08-08 07:38:48 +00:00
if bedit . ShowModal ( ) == wx . ID_OK :
if n == len ( self . custombuttons ) :
2012-04-22 23:33:47 +00:00
self . custombuttons + = [ None ]
2012-09-05 14:32:35 +00:00
self . custombuttons [ n ] = SpecialButton ( bedit . name . GetValue ( ) . strip ( ) , bedit . command . GetValue ( ) . strip ( ) , custom = True )
2012-04-22 23:33:47 +00:00
if bedit . color . GetValue ( ) . strip ( ) != " " :
2012-09-05 14:32:35 +00:00
self . custombuttons [ n ] . background = bedit . color . GetValue ( )
2012-08-08 07:38:48 +00:00
self . cbutton_save ( n , self . custombuttons [ n ] )
2012-04-22 23:33:47 +00:00
bedit . Destroy ( )
self . cbuttons_reload ( )
2012-08-08 07:38:48 +00:00
def cbutton_remove ( self , e , button ) :
2011-08-03 11:26:16 +00:00
n = button . custombutton
self . custombuttons [ n ] = None
2012-08-08 07:38:48 +00:00
self . cbutton_save ( n , None )
2011-09-30 14:41:18 +00:00
#while len(self.custombuttons) and self.custombuttons[-1] is None:
# del self.custombuttons[-1]
2011-11-14 19:35:18 +00:00
wx . CallAfter ( self . cbuttons_reload )
2012-03-20 17:57:57 +00:00
2012-08-08 07:38:48 +00:00
def cbutton_order ( self , e , button , dir ) :
2011-08-03 11:26:16 +00:00
n = button . custombutton
if dir < 0 :
2012-08-08 07:38:48 +00:00
n = n - 1
2011-08-03 11:26:16 +00:00
if n + 1 > = len ( self . custombuttons ) :
self . custombuttons + = [ None ] # pad
# swap
2012-08-08 07:58:09 +00:00
self . custombuttons [ n ] , self . custombuttons [ n + 1 ] = self . custombuttons [ n + 1 ] , self . custombuttons [ n ]
2012-08-08 07:38:48 +00:00
self . cbutton_save ( n , self . custombuttons [ n ] )
self . cbutton_save ( n + 1 , self . custombuttons [ n + 1 ] )
2011-09-30 14:41:18 +00:00
#if self.custombuttons[-1] is None:
# del self.custombuttons[-1]
2011-08-03 11:26:16 +00:00
self . cbuttons_reload ( )
2012-03-20 17:57:57 +00:00
2012-08-08 07:38:48 +00:00
def editbutton ( self , e ) :
2011-08-04 18:15:34 +00:00
if e . IsCommandEvent ( ) or e . ButtonUp ( wx . MOUSE_BTN_RIGHT ) :
if e . IsCommandEvent ( ) :
2012-08-08 07:38:48 +00:00
pos = ( 0 , 0 )
2011-08-04 18:15:34 +00:00
else :
pos = e . GetPosition ( )
2011-08-03 11:26:16 +00:00
popupmenu = wx . Menu ( )
obj = e . GetEventObject ( )
2012-08-08 07:58:09 +00:00
if hasattr ( obj , " custombutton " ) :
2012-08-08 07:38:48 +00:00
item = popupmenu . Append ( - 1 , _ ( " Edit custom button ' %s ' " ) % e . GetEventObject ( ) . GetLabelText ( ) )
2012-08-08 07:58:09 +00:00
self . Bind ( wx . EVT_MENU , lambda e , button = e . GetEventObject ( ) : self . cbutton_edit ( e , button ) , item )
2012-08-08 07:38:48 +00:00
item = popupmenu . Append ( - 1 , _ ( " Move left << " ) )
2012-08-08 07:58:09 +00:00
self . Bind ( wx . EVT_MENU , lambda e , button = e . GetEventObject ( ) : self . cbutton_order ( e , button , - 1 ) , item )
2011-08-03 11:26:16 +00:00
if obj . custombutton == 0 : item . Enable ( False )
2012-08-08 07:38:48 +00:00
item = popupmenu . Append ( - 1 , _ ( " Move right >> " ) )
2012-08-08 07:58:09 +00:00
self . Bind ( wx . EVT_MENU , lambda e , button = e . GetEventObject ( ) : self . cbutton_order ( e , button , 1 ) , item )
2011-08-03 11:26:16 +00:00
if obj . custombutton == 63 : item . Enable ( False )
pos = self . panel . ScreenToClient ( e . GetEventObject ( ) . ClientToScreen ( pos ) )
2012-08-08 07:38:48 +00:00
item = popupmenu . Append ( - 1 , _ ( " Remove custom button ' %s ' " ) % e . GetEventObject ( ) . GetLabelText ( ) )
2012-08-08 07:58:09 +00:00
self . Bind ( wx . EVT_MENU , lambda e , button = e . GetEventObject ( ) : self . cbutton_remove ( e , button ) , item )
2011-08-03 11:26:16 +00:00
else :
2012-08-08 07:38:48 +00:00
item = popupmenu . Append ( - 1 , _ ( " Add custom button " ) )
self . Bind ( wx . EVT_MENU , self . cbutton_edit , item )
2011-08-03 11:26:16 +00:00
self . panel . PopupMenu ( popupmenu , pos )
2011-09-30 14:41:18 +00:00
elif e . Dragging ( ) and e . ButtonIsDown ( wx . MOUSE_BTN_LEFT ) :
obj = e . GetEventObject ( )
scrpos = obj . ClientToScreen ( e . GetPosition ( ) )
2012-08-08 07:58:09 +00:00
if not hasattr ( self , " dragpos " ) :
2011-10-27 13:36:30 +00:00
self . dragpos = scrpos
e . Skip ( )
return
2012-03-20 17:57:57 +00:00
else :
2012-08-08 07:58:09 +00:00
dx , dy = self . dragpos [ 0 ] - scrpos [ 0 ] , self . dragpos [ 1 ] - scrpos [ 1 ]
2011-10-27 13:36:30 +00:00
if dx * dx + dy * dy < 5 * 5 : # threshold to detect dragging for jittery mice
e . Skip ( )
return
2012-08-08 07:58:09 +00:00
if not hasattr ( self , " dragging " ) :
2011-09-30 14:41:18 +00:00
# init dragging of the custom button
2012-08-08 07:58:09 +00:00
if hasattr ( obj , " custombutton " ) and obj . properties is not None :
2012-07-23 13:08:41 +00:00
#self.newbuttonbutton.SetLabel("")
2012-08-08 07:38:48 +00:00
#self.newbuttonbutton.SetFont(wx.Font(10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
2012-07-23 13:08:41 +00:00
#self.newbuttonbutton.SetForegroundColour("black")
#self.newbuttonbutton.SetSize(obj.GetSize())
2012-09-05 12:37:03 +00:00
#if self.uppersizer.GetItem(self.newbuttonbutton) is not None:
# self.uppersizer.SetItemMinSize(self.newbuttonbutton, obj.GetSize())
2012-09-05 11:09:38 +00:00
# self.mainsizer.Layout()
2012-07-23 13:08:41 +00:00
for b in self . custombuttonbuttons :
#if b.IsFrozen(): b.Thaw()
if b . properties is None :
b . Enable ( )
b . SetLabel ( " " )
2012-08-08 07:38:48 +00:00
b . SetFont ( wx . Font ( 10 , wx . FONTFAMILY_DEFAULT , wx . FONTSTYLE_NORMAL , wx . FONTWEIGHT_NORMAL ) )
2012-07-23 13:08:41 +00:00
b . SetForegroundColour ( " black " )
b . SetSize ( obj . GetSize ( ) )
2012-09-05 12:37:03 +00:00
if self . uppersizer . GetItem ( b ) is not None :
self . uppersizer . SetItemMinSize ( b , obj . GetSize ( ) )
2012-09-05 11:09:38 +00:00
self . mainsizer . Layout ( )
2012-07-23 13:08:41 +00:00
# b.SetStyle(wx.ALIGN_CENTRE+wx.ST_NO_AUTORESIZE+wx.SIMPLE_BORDER)
2012-08-08 07:58:09 +00:00
self . dragging = wx . Button ( self . panel , - 1 , obj . GetLabel ( ) , style = wx . BU_EXACTFIT )
2011-09-30 14:41:18 +00:00
self . dragging . SetBackgroundColour ( obj . GetBackgroundColour ( ) )
2011-11-08 19:05:39 +00:00
self . dragging . SetForegroundColour ( obj . GetForegroundColour ( ) )
2011-09-30 14:41:18 +00:00
self . dragging . sourcebutton = obj
self . dragging . Raise ( )
self . dragging . Disable ( )
self . dragging . SetPosition ( self . panel . ScreenToClient ( scrpos ) )
self . last_drag_dest = obj
self . dragging . label = obj . s_label = obj . GetLabel ( )
self . dragging . bgc = obj . s_bgc = obj . GetBackgroundColour ( )
2011-11-08 19:05:39 +00:00
self . dragging . fgc = obj . s_fgc = obj . GetForegroundColour ( )
2012-03-20 17:57:57 +00:00
else :
2011-09-30 14:41:18 +00:00
# dragging in progress
self . dragging . SetPosition ( self . panel . ScreenToClient ( scrpos ) )
2011-11-08 19:05:39 +00:00
wx . CallAfter ( self . dragging . Refresh )
2012-03-20 17:57:57 +00:00
btns = self . custombuttonbuttons
2011-09-30 14:41:18 +00:00
dst = None
src = self . dragging . sourcebutton
drg = self . dragging
for b in self . custombuttonbuttons :
if b . GetScreenRect ( ) . Contains ( scrpos ) :
dst = b
break
#if dst is None and self.panel.GetScreenRect().Contains(scrpos):
# # try to check if it is after buttons at the end
2012-09-05 12:37:03 +00:00
# tspos = self.panel.ClientToScreen(self.uppersizer.GetPosition())
2011-09-30 14:41:18 +00:00
# bspos = self.panel.ClientToScreen(self.centersizer.GetPosition())
2012-09-05 12:37:03 +00:00
# tsrect = wx.Rect(*(tspos.Get()+self.uppersizer.GetSize().Get()))
2011-09-30 14:41:18 +00:00
# bsrect = wx.Rect(*(bspos.Get()+self.centersizer.GetSize().Get()))
# lbrect = btns[-1].GetScreenRect()
# p = scrpos.Get()
# if len(btns)<4 and tsrect.Contains(scrpos):
# if lbrect.GetRight() < p[0]:
# print "Right of last button on upper cb sizer"
# if bsrect.Contains(scrpos):
# if lbrect.GetBottom() < p[1]:
# print "Below last button on lower cb sizer"
# if lbrect.GetRight() < p[0] and lbrect.GetTop() <= p[1] and lbrect.GetBottom() >= p[1]:
# print "Right to last button on lower cb sizer"
if dst is not self . last_drag_dest :
if self . last_drag_dest is not None :
self . last_drag_dest . SetBackgroundColour ( self . last_drag_dest . s_bgc )
2011-11-08 19:05:39 +00:00
self . last_drag_dest . SetForegroundColour ( self . last_drag_dest . s_fgc )
2011-09-30 14:41:18 +00:00
self . last_drag_dest . SetLabel ( self . last_drag_dest . s_label )
if dst is not None and dst is not src :
dst . s_bgc = dst . GetBackgroundColour ( )
2011-11-08 19:05:39 +00:00
dst . s_fgc = dst . GetForegroundColour ( )
2011-09-30 14:41:18 +00:00
dst . s_label = dst . GetLabel ( )
src . SetBackgroundColour ( dst . GetBackgroundColour ( ) )
2011-11-08 19:05:39 +00:00
src . SetForegroundColour ( dst . GetForegroundColour ( ) )
2011-09-30 14:41:18 +00:00
src . SetLabel ( dst . GetLabel ( ) )
dst . SetBackgroundColour ( drg . bgc )
2011-11-08 19:05:39 +00:00
dst . SetForegroundColour ( drg . fgc )
2011-09-30 14:41:18 +00:00
dst . SetLabel ( drg . label )
else :
src . SetBackgroundColour ( drg . bgc )
2011-11-08 19:05:39 +00:00
src . SetForegroundColour ( drg . fgc )
2011-09-30 14:41:18 +00:00
src . SetLabel ( drg . label )
self . last_drag_dest = dst
2012-08-08 07:58:09 +00:00
elif hasattr ( self , " dragging " ) and not e . ButtonIsDown ( wx . MOUSE_BTN_LEFT ) :
2011-09-30 14:41:18 +00:00
# dragging finished
obj = e . GetEventObject ( )
scrpos = obj . ClientToScreen ( e . GetPosition ( ) )
dst = None
src = self . dragging . sourcebutton
drg = self . dragging
for b in self . custombuttonbuttons :
if b . GetScreenRect ( ) . Contains ( scrpos ) :
dst = b
break
if dst is not None :
src_i = src . custombutton
dst_i = dst . custombutton
2012-08-08 07:58:09 +00:00
self . custombuttons [ src_i ] , self . custombuttons [ dst_i ] = self . custombuttons [ dst_i ] , self . custombuttons [ src_i ]
2012-08-08 07:38:48 +00:00
self . cbutton_save ( src_i , self . custombuttons [ src_i ] )
self . cbutton_save ( dst_i , self . custombuttons [ dst_i ] )
2011-09-30 14:41:18 +00:00
while self . custombuttons [ - 1 ] is None :
del self . custombuttons [ - 1 ]
wx . CallAfter ( self . dragging . Destroy )
del self . dragging
wx . CallAfter ( self . cbuttons_reload )
del self . last_drag_dest
2011-10-27 13:36:30 +00:00
del self . dragpos
2011-08-03 11:26:16 +00:00
else :
2011-09-30 14:41:18 +00:00
e . Skip ( )
2012-03-20 17:57:57 +00:00
2011-11-11 16:22:31 +00:00
def homeButtonClicked ( self , corner ) :
if corner == 0 : # upper-left
self . onecmd ( ' home X ' )
if corner == 1 : # upper-right
self . onecmd ( ' home Y ' )
if corner == 2 : # lower-right
self . onecmd ( ' home Z ' )
if corner == 3 : # lower-left
self . onecmd ( ' home ' )
2012-04-30 17:59:18 +00:00
# When user clicks on the XY control, the Z control no longer gets spacebar/repeat signals
self . zb . clearRepeat ( )
2012-03-20 17:57:57 +00:00
2011-11-07 19:41:14 +00:00
def moveXY ( self , x , y ) :
if x != 0 :
self . onecmd ( ' move X %s ' % x )
if y != 0 :
self . onecmd ( ' move Y %s ' % y )
2012-04-30 17:59:18 +00:00
# When user clicks on the XY control, the Z control no longer gets spacebar/repeat signals
self . zb . clearRepeat ( )
2012-03-20 17:57:57 +00:00
2011-11-07 19:41:14 +00:00
def moveZ ( self , z ) :
if z != 0 :
self . onecmd ( ' move Z %s ' % z )
2012-04-30 17:59:18 +00:00
# When user clicks on the Z control, the XY control no longer gets spacebar/repeat signals
self . xyb . clearRepeat ( )
def spacebarAction ( self ) :
self . zb . repeatLast ( )
self . xyb . repeatLast ( )
2012-03-20 17:57:57 +00:00
2012-08-08 07:38:48 +00:00
def procbutton ( self , e ) :
2011-06-09 06:18:13 +00:00
try :
2011-08-04 11:03:35 +00:00
if hasattr ( e . GetEventObject ( ) , " custombutton " ) :
2011-08-04 19:28:34 +00:00
if wx . GetKeyState ( wx . WXK_CONTROL ) or wx . GetKeyState ( wx . WXK_ALT ) :
2011-08-04 18:15:34 +00:00
return self . editbutton ( e )
2012-08-08 07:38:48 +00:00
self . cur_button = e . GetEventObject ( ) . custombutton
2012-09-06 07:02:47 +00:00
self . onecmd ( e . GetEventObject ( ) . properties . command )
2012-08-08 07:38:48 +00:00
self . cur_button = None
2011-06-09 06:18:13 +00:00
except :
2011-08-06 23:45:52 +00:00
print _ ( " event object missing " )
2012-08-08 07:38:48 +00:00
self . cur_button = None
2011-06-09 06:18:13 +00:00
raise
2012-03-20 17:57:57 +00:00
2012-08-08 07:38:48 +00:00
def kill ( self , e ) :
2012-08-04 20:24:45 +00:00
self . statuscheck = False
2012-08-04 21:18:17 +00:00
if self . status_thread :
self . status_thread . join ( )
self . status_thread = None
2012-08-08 07:38:48 +00:00
self . p . recvcb = None
2011-06-08 14:19:38 +00:00
self . p . disconnect ( )
2012-08-08 07:58:09 +00:00
if hasattr ( self , " feedrates_changed " ) :
self . save_in_rc ( " set xy_feedrate " , " set xy_feedrate %d " % self . settings . xy_feedrate )
self . save_in_rc ( " set z_feedrate " , " set z_feedrate %d " % self . settings . z_feedrate )
self . save_in_rc ( " set e_feedrate " , " set e_feedrate %d " % self . settings . e_feedrate )
2013-05-18 09:05:45 +00:00
wx . CallAfter ( self . gwindow . Destroy )
wx . CallAfter ( self . Destroy )
2012-03-20 17:57:57 +00:00
2012-08-08 07:38:48 +00:00
def do_monitor ( self , l = " " ) :
2011-07-28 09:33:39 +00:00
if l . strip ( ) == " " :
self . monitorbox . SetValue ( not self . monitorbox . GetValue ( ) )
elif l . strip ( ) == " off " :
2012-08-08 07:38:48 +00:00
wx . CallAfter ( self . monitorbox . SetValue , False )
2011-07-28 09:33:39 +00:00
else :
try :
2012-08-08 07:38:48 +00:00
self . monitor_interval = float ( l )
wx . CallAfter ( self . monitorbox . SetValue , self . monitor_interval > 0 )
2011-07-28 09:33:39 +00:00
except :
2011-08-06 23:45:52 +00:00
print _ ( " Invalid period given. " )
2011-07-28 09:33:39 +00:00
self . setmonitor ( None )
if self . monitor :
2011-08-06 23:45:52 +00:00
print _ ( " Monitoring printer. " )
2011-07-28 09:33:39 +00:00
else :
2011-08-06 23:45:52 +00:00
print _ ( " Done monitoring. " )
2012-03-20 17:57:57 +00:00
2012-08-08 07:38:48 +00:00
def setmonitor ( self , e ) :
self . monitor = self . monitorbox . GetValue ( )
2012-03-20 17:57:57 +00:00
if self . monitor :
2012-08-08 07:38:48 +00:00
wx . CallAfter ( self . graph . StartPlotting , 1000 )
2012-03-20 17:57:57 +00:00
else :
2012-05-04 04:40:19 +00:00
wx . CallAfter ( self . graph . StopPlotting )
2012-03-20 17:57:57 +00:00
2012-08-20 06:23:19 +00:00
def addtexttolog ( self , text ) :
try :
self . logbox . AppendText ( text )
except :
2013-05-16 18:47:39 +00:00
print _ ( " Attempted to write invalid text to console, which could be due to an invalid baudrate " )
2012-09-05 08:11:48 +00:00
2012-08-12 16:03:11 +00:00
def setloud ( self , e ) :
self . p . loud = e . IsChecked ( )
2012-03-20 17:57:57 +00:00
2012-09-05 08:10:05 +00:00
def sendline ( self , e ) :
command = self . commandbox . GetValue ( )
2011-06-08 15:25:01 +00:00
if not len ( command ) :
return
2012-09-05 08:10:05 +00:00
wx . CallAfter ( self . addtexttolog , " >>> " + command + " \n " ) ;
2011-06-11 21:03:01 +00:00
self . onecmd ( str ( command ) )
2012-08-08 07:38:48 +00:00
self . commandbox . SetSelection ( 0 , len ( command ) )
2013-05-18 20:37:49 +00:00
self . commandbox . history . append ( command )
2012-08-08 07:38:48 +00:00
self . commandbox . histindex = len ( self . commandbox . history )
2011-09-06 16:55:52 +00:00
2012-08-08 07:38:48 +00:00
def clearOutput ( self , e ) :
2011-09-06 16:55:52 +00:00
self . logbox . Clear ( )
2012-03-20 17:57:57 +00:00
2013-05-17 14:59:28 +00:00
def update_tempdisplay ( self ) :
try :
hotend_temp = parse_temperature_report ( self . tempreport , " T: " )
wx . CallAfter ( self . graph . SetExtruder0Temperature , hotend_temp )
if self . display_gauges : wx . CallAfter ( self . hottgauge . SetValue , hotend_temp )
bed_temp = parse_temperature_report ( self . tempreport , " B: " )
wx . CallAfter ( self . graph . SetBedTemperature , bed_temp )
if self . display_gauges : wx . CallAfter ( self . bedtgauge . SetValue , bed_temp )
except :
traceback . print_exc ( )
2011-06-08 14:19:38 +00:00
def statuschecker ( self ) :
2012-08-06 17:38:01 +00:00
while self . statuscheck :
string = " "
fractioncomplete = 0.0
if self . sdprinting :
fractioncomplete = float ( self . percentdone / 100.0 )
string + = _ ( " SD printing: %04.2f %% " ) % ( self . percentdone , )
if self . p . printing :
fractioncomplete = float ( self . p . queueindex ) / len ( self . p . mainqueue )
string + = _ ( " Printing: %04.2f %% | " ) % ( 100 * float ( self . p . queueindex ) / len ( self . p . mainqueue ) , )
string + = _ ( " Line# %d of %d lines | " ) % ( self . p . queueindex , len ( self . p . mainqueue ) )
if fractioncomplete > 0.0 :
secondselapsed = int ( time . time ( ) - self . starttime + self . extra_print_time )
secondsestimate = secondselapsed / fractioncomplete
secondsremain = secondsestimate - secondselapsed
2012-08-07 11:54:07 +00:00
string + = _ ( " Est: %s of %s remaining | " ) % ( format_duration ( secondsremain ) ,
format_duration ( secondsestimate ) )
2012-08-06 17:38:01 +00:00
string + = _ ( " Z: %0.2f mm " ) % self . curlayer
wx . CallAfter ( self . status . SetStatusText , string )
wx . CallAfter ( self . gviz . Refresh )
if ( self . monitor and self . p . online ) :
if self . sdprinting :
self . p . send_now ( " M27 " )
2012-08-08 07:58:09 +00:00
if not hasattr ( self , " auto_monitor_pattern " ) :
2012-08-06 17:38:01 +00:00
self . auto_monitor_pattern = re . compile ( r " (ok \ s+)?T:[ \ d \ .]+( \ s+B:[ \ d \ .]+)?( \ s+@:[ \ d \ .]+)? \ s* " )
self . capture_skip [ self . auto_monitor_pattern ] = self . capture_skip . setdefault ( self . auto_monitor_pattern , 0 ) + 1
self . p . send_now ( " M105 " )
2012-08-06 21:25:37 +00:00
cur_time = time . time ( )
while time . time ( ) < cur_time + self . monitor_interval :
if not self . statuscheck :
break
time . sleep ( 0.25 )
2012-08-06 17:38:01 +00:00
while not self . sentlines . empty ( ) :
2013-05-18 16:38:54 +00:00
gc = self . sentlines . get_nowait ( )
wx . CallAfter ( self . gviz . addgcode , gc , 1 )
2012-08-08 07:38:48 +00:00
wx . CallAfter ( self . status . SetStatusText , _ ( " Not connected to printer. " ) )
2012-08-08 06:39:50 +00:00
2011-06-08 14:19:38 +00:00
def capture ( self , func , * args , * * kwargs ) :
2012-08-08 07:38:48 +00:00
stdout = sys . stdout
cout = None
2011-06-08 14:19:38 +00:00
try :
2012-08-08 07:38:48 +00:00
cout = self . cout
2011-06-08 14:19:38 +00:00
except :
pass
if cout is None :
2012-08-08 07:38:48 +00:00
cout = cStringIO . StringIO ( )
2012-03-20 17:57:57 +00:00
2012-08-08 07:38:48 +00:00
sys . stdout = cout
retval = None
2011-06-08 14:19:38 +00:00
try :
2012-08-08 07:38:48 +00:00
retval = func ( * args , * * kwargs )
2011-06-08 14:19:38 +00:00
except :
traceback . print_exc ( )
2012-08-08 07:38:48 +00:00
sys . stdout = stdout
2011-06-08 14:19:38 +00:00
return retval
2012-08-08 07:38:48 +00:00
def recvcb ( self , l ) :
2011-06-08 14:19:38 +00:00
if " T: " in l :
2012-08-08 07:38:48 +00:00
self . tempreport = l
2012-08-08 07:58:09 +00:00
wx . CallAfter ( self . tempdisp . SetLabel , self . tempreport . strip ( ) . replace ( " ok " , " " ) )
2013-05-17 14:59:28 +00:00
self . update_tempdisplay ( )
2012-08-08 07:38:48 +00:00
tstring = l . rstrip ( )
2011-06-09 13:19:03 +00:00
#print tstring
2012-08-12 22:07:24 +00:00
if ( tstring != " ok " ) and ( tstring != " wait " ) and ( " ok T: " not in tstring ) and ( not self . p . loud ) :
2012-05-05 23:17:21 +00:00
# print "*"+tstring+"*"
# print "[" + time.strftime('%H:%M:%S',time.localtime(time.time())) + "] " + tstring
2012-09-05 08:10:05 +00:00
wx . CallAfter ( self . addtexttolog , tstring + " \n " ) ;
2011-06-08 14:19:38 +00:00
for i in self . recvlisteners :
i ( l )
2012-03-20 17:57:57 +00:00
2012-08-08 07:38:48 +00:00
def listfiles ( self , line ) :
2011-06-08 14:19:38 +00:00
if " Begin file list " in line :
2012-08-08 07:38:48 +00:00
self . listing = 1
2011-06-08 14:19:38 +00:00
elif " End file list " in line :
2012-08-08 07:38:48 +00:00
self . listing = 0
2011-06-08 14:19:38 +00:00
self . recvlisteners . remove ( self . listfiles )
wx . CallAfter ( self . filesloaded )
elif self . listing :
2012-08-08 07:58:09 +00:00
self . sdfiles + = [ line . replace ( " \n " , " " ) . replace ( " \r " , " " ) . lower ( ) ]
2012-03-20 17:57:57 +00:00
2012-08-08 07:38:48 +00:00
def waitforsdresponse ( self , l ) :
2011-06-08 14:19:38 +00:00
if " file.open failed " in l :
2012-08-08 07:38:48 +00:00
wx . CallAfter ( self . status . SetStatusText , _ ( " Opening file failed. " ) )
2011-06-08 14:19:38 +00:00
self . recvlisteners . remove ( self . waitforsdresponse )
return
if " File opened " in l :
2012-08-08 07:38:48 +00:00
wx . CallAfter ( self . status . SetStatusText , l )
2011-06-08 14:19:38 +00:00
if " File selected " in l :
2012-08-08 07:38:48 +00:00
wx . CallAfter ( self . status . SetStatusText , _ ( " Starting print " ) )
self . sdprinting = 1
2011-06-08 15:25:01 +00:00
self . p . send_now ( " M24 " )
2011-07-17 10:53:13 +00:00
self . startcb ( )
2011-06-08 14:19:38 +00:00
return
if " Done printing file " in l :
2012-08-08 07:38:48 +00:00
wx . CallAfter ( self . status . SetStatusText , l )
self . sdprinting = 0
2011-06-08 14:19:38 +00:00
self . recvlisteners . remove ( self . waitforsdresponse )
2011-07-17 10:53:13 +00:00
self . endcb ( )
2011-06-08 14:19:38 +00:00
return
if " SD printing byte " in l :
#M27 handler
try :
2012-08-08 07:38:48 +00:00
resp = l . split ( )
vals = resp [ - 1 ] . split ( " / " )
self . percentdone = 100.0 * int ( vals [ 0 ] ) / int ( vals [ 1 ] )
2011-06-08 14:19:38 +00:00
except :
pass
2012-03-20 17:57:57 +00:00
2011-06-08 14:19:38 +00:00
def filesloaded ( self ) :
2012-08-08 07:38:48 +00:00
dlg = wx . SingleChoiceDialog ( self , _ ( " Select the file to print " ) , _ ( " Pick SD file " ) , self . sdfiles )
if ( dlg . ShowModal ( ) == wx . ID_OK ) :
target = dlg . GetStringSelection ( )
2011-06-08 14:19:38 +00:00
if len ( target ) :
self . recvlisteners + = [ self . waitforsdresponse ]
self . p . send_now ( " M23 " + target . lower ( ) )
#print self.sdfiles
def getfiles ( self ) :
if not self . p . online :
2012-08-08 07:58:09 +00:00
self . sdfiles = [ ]
2011-06-08 14:19:38 +00:00
return
2012-08-08 07:38:48 +00:00
self . listing = 0
2012-08-08 07:58:09 +00:00
self . sdfiles = [ ]
2011-06-08 14:19:38 +00:00
self . recvlisteners + = [ self . listfiles ]
2011-11-30 13:12:59 +00:00
self . p . send_now ( " M21 " )
2011-06-08 14:19:38 +00:00
self . p . send_now ( " M20 " )
2012-03-20 17:57:57 +00:00
2011-06-08 14:19:38 +00:00
def skein_func ( self ) :
try :
2011-12-22 10:07:52 +00:00
param = self . expandcommand ( self . settings . slicecommand ) . encode ( )
2012-08-08 07:58:09 +00:00
print " Slicing: " , param
pararray = [ i . replace ( " $s " , self . filename ) . replace ( " $o " , self . filename . replace ( " .stl " , " _export.gcode " ) . replace ( " .STL " , " _export.gcode " ) ) . encode ( ) for i in shlex . split ( param . replace ( " \\ " , " \\ \\ " ) . encode ( ) ) ]
2011-12-22 10:07:52 +00:00
#print pararray
2012-08-08 07:38:48 +00:00
self . skeinp = subprocess . Popen ( pararray , stderr = subprocess . STDOUT , stdout = subprocess . PIPE )
2011-11-18 08:52:16 +00:00
while True :
o = self . skeinp . stdout . read ( 1 )
if o == ' ' and self . skeinp . poll ( ) != None : break
sys . stdout . write ( o )
self . skeinp . wait ( )
2012-08-08 07:38:48 +00:00
self . stopsf = 1
2011-06-08 14:19:38 +00:00
except :
2012-01-07 17:59:38 +00:00
print _ ( " Failed to execute slicing software: " )
2012-08-08 07:38:48 +00:00
self . stopsf = 1
traceback . print_exc ( file = sys . stdout )
2012-03-20 17:57:57 +00:00
2011-06-08 14:19:38 +00:00
def skein_monitor ( self ) :
while ( not self . stopsf ) :
try :
2012-08-08 07:38:48 +00:00
wx . CallAfter ( self . status . SetStatusText , _ ( " Slicing... " ) ) #+self.cout.getvalue().split("\n")[-1])
2011-06-08 14:19:38 +00:00
except :
pass
time . sleep ( 0.1 )
2012-08-08 07:38:48 +00:00
fn = self . filename
2011-06-08 14:19:38 +00:00
try :
2012-08-08 07:58:09 +00:00
self . filename = self . filename . replace ( " .stl " , " _export.gcode " ) . replace ( " .STL " , " _export.gcode " ) . replace ( " .obj " , " _export.gcode " ) . replace ( " .OBJ " , " _export.gcode " )
2012-08-08 07:38:48 +00:00
of = open ( self . filename )
2012-08-08 07:58:09 +00:00
self . f = [ i . replace ( " \n " , " " ) . replace ( " \r " , " " ) for i in of ]
2012-08-04 20:54:12 +00:00
of . close ( )
2011-07-15 10:11:09 +00:00
if self . p . online :
2012-08-08 06:39:50 +00:00
wx . CallAfter ( self . printbtn . Enable )
2012-03-20 17:57:57 +00:00
2012-08-08 07:38:48 +00:00
wx . CallAfter ( self . status . SetStatusText , _ ( " Loaded " ) + self . filename + _ ( " , %d lines " ) % ( len ( self . f ) , ) )
2011-08-06 12:48:10 +00:00
wx . CallAfter ( self . pausebtn . Disable )
2012-08-08 07:38:48 +00:00
wx . CallAfter ( self . printbtn . SetLabel , _ ( " Print " ) )
2011-07-17 12:28:15 +00:00
2012-08-08 07:38:48 +00:00
threading . Thread ( target = self . loadviz ) . start ( )
2011-06-08 14:19:38 +00:00
except :
2012-08-08 07:38:48 +00:00
self . filename = fn
wx . CallAfter ( self . loadbtn . SetLabel , _ ( " Load File " ) )
self . skeining = 0
self . skeinp = None
2012-03-20 17:57:57 +00:00
2012-08-08 07:38:48 +00:00
def skein ( self , filename ) :
wx . CallAfter ( self . loadbtn . SetLabel , _ ( " Cancel " ) )
2011-11-18 08:52:16 +00:00
print _ ( " Slicing " ) + filename
2012-08-08 07:38:48 +00:00
self . cout = StringIO . StringIO ( )
self . filename = filename
self . stopsf = 0
self . skeining = 1
threading . Thread ( target = self . skein_func ) . start ( )
threading . Thread ( target = self . skein_monitor ) . start ( )
2012-08-20 02:10:46 +00:00
def do_load ( self , l ) :
2012-09-05 08:10:05 +00:00
if hasattr ( self , ' skeining ' ) :
self . loadfile ( None , l )
else :
self . _do_load ( l )
2012-08-20 02:10:46 +00:00
2012-09-05 08:10:05 +00:00
def loadfile ( self , event , filename = None ) :
2011-11-18 08:52:16 +00:00
if self . skeining and self . skeinp is not None :
self . skeinp . terminate ( )
return
2012-08-08 07:38:48 +00:00
basedir = self . settings . last_file_path
2011-06-29 21:32:24 +00:00
if not os . path . exists ( basedir ) :
basedir = " . "
try :
2012-08-08 07:38:48 +00:00
basedir = os . path . split ( self . filename ) [ 0 ]
2011-06-29 21:32:24 +00:00
except :
pass
2012-08-08 07:58:09 +00:00
dlg = wx . FileDialog ( self , _ ( " Open file to print " ) , basedir , style = wx . FD_OPEN | wx . FD_FILE_MUST_EXIST )
2012-08-08 06:39:50 +00:00
dlg . SetWildcard ( _ ( " OBJ, STL, and GCODE files (*.gcode;*.gco;*.g;*.stl;*.STL;*.obj;*.OBJ)|*.gcode;*.gco;*.g;*.stl;*.STL;*.obj;*.OBJ|All Files (*.*)|*.* " ) )
2011-08-06 13:28:25 +00:00
if ( filename is not None or dlg . ShowModal ( ) == wx . ID_OK ) :
if filename is not None :
2012-08-08 07:38:48 +00:00
name = filename
2011-08-06 13:28:25 +00:00
else :
2012-08-08 07:38:48 +00:00
name = dlg . GetPath ( )
2011-06-08 14:19:38 +00:00
if not ( os . path . exists ( name ) ) :
2011-08-06 23:45:52 +00:00
self . status . SetStatusText ( _ ( " File not found! " ) )
2011-06-08 14:19:38 +00:00
return
2011-06-29 21:32:24 +00:00
path = os . path . split ( name ) [ 0 ]
if path != self . settings . last_file_path :
2012-08-08 07:58:09 +00:00
self . set ( " last_file_path " , path )
2011-06-30 04:54:45 +00:00
if name . lower ( ) . endswith ( " .stl " ) :
2011-06-08 14:19:38 +00:00
self . skein ( name )
2011-11-05 03:50:25 +00:00
elif name . lower ( ) . endswith ( " .obj " ) :
self . skein ( name )
2011-06-08 14:19:38 +00:00
else :
2012-08-08 07:38:48 +00:00
self . filename = name
of = open ( self . filename )
2012-08-08 07:58:09 +00:00
self . f = [ i . replace ( " \n " , " " ) . replace ( " \r " , " " ) for i in of ]
2012-08-06 17:19:07 +00:00
of . close ( )
2012-02-26 01:14:06 +00:00
self . status . SetStatusText ( _ ( " Loaded %s , %d lines " ) % ( name , len ( self . f ) ) )
2011-08-06 23:45:52 +00:00
wx . CallAfter ( self . printbtn . SetLabel , _ ( " Print " ) )
wx . CallAfter ( self . pausebtn . SetLabel , _ ( " Pause " ) )
2011-08-06 12:48:10 +00:00
wx . CallAfter ( self . pausebtn . Disable )
2012-08-06 17:18:45 +00:00
wx . CallAfter ( self . recoverbtn . Disable )
2011-07-09 13:54:59 +00:00
if self . p . online :
2011-07-27 15:23:28 +00:00
wx . CallAfter ( self . printbtn . Enable )
2012-08-08 07:38:48 +00:00
threading . Thread ( target = self . loadviz ) . start ( )
2012-04-22 23:33:47 +00:00
2011-06-21 16:52:11 +00:00
def loadviz ( self ) :
2013-05-15 17:42:38 +00:00
gcode = gcoder . GCode ( self . f )
2013-05-15 13:23:46 +00:00
gcode . measure ( )
print gcode . filament_length ( ) , _ ( " mm of filament used in this print \n " )
2013-05-15 19:39:08 +00:00
print _ ( " the print goes from %f mm to %f mm in X \n and is %f mm wide \n " ) % ( gcode . xmin , gcode . xmax , gcode . width )
print _ ( " the print goes from %f mm to %f mm in Y \n and is %f mm wide \n " ) % ( gcode . ymin , gcode . ymax , gcode . depth )
print _ ( " the print goes from %f mm to %f mm in Z \n and is %f mm high \n " ) % ( gcode . zmin , gcode . zmax , gcode . height )
2013-05-18 17:52:05 +00:00
print _ ( " Estimated duration: " ) , gcode . estimate_duration ( )
2011-06-21 16:52:11 +00:00
self . gviz . clear ( )
2011-06-30 04:57:40 +00:00
self . gwindow . p . clear ( )
2013-05-16 22:18:54 +00:00
self . gviz . addfile ( gcode )
self . gwindow . p . addfile ( gcode )
2012-08-08 07:38:48 +00:00
self . gviz . showall = 1
2011-06-21 16:52:11 +00:00
wx . CallAfter ( self . gviz . Refresh )
2012-03-20 17:57:57 +00:00
2012-08-08 07:38:48 +00:00
def printfile ( self , event ) :
self . extra_print_time = 0
2011-06-10 18:34:04 +00:00
if self . paused :
2012-08-08 07:38:48 +00:00
self . p . paused = 0
self . paused = 0
2011-07-09 13:54:59 +00:00
self . on_startprint ( )
2011-06-10 18:34:04 +00:00
if self . sdprinting :
self . p . send_now ( " M26 S0 " )
self . p . send_now ( " M24 " )
return
2012-03-20 17:57:57 +00:00
2011-06-08 14:19:38 +00:00
if self . f is None or not len ( self . f ) :
2011-08-06 23:45:52 +00:00
wx . CallAfter ( self . status . SetStatusText , _ ( " No file loaded. Please use load first. " ) )
2011-06-08 14:19:38 +00:00
return
if not self . p . online :
2012-08-08 07:38:48 +00:00
wx . CallAfter ( self . status . SetStatusText , _ ( " Not connected to printer. " ) )
2011-06-08 14:19:38 +00:00
return
2011-07-09 14:07:17 +00:00
self . on_startprint ( )
2011-06-08 14:19:38 +00:00
self . p . startprint ( self . f )
2012-03-20 17:57:57 +00:00
2011-07-09 13:54:59 +00:00
def on_startprint ( self ) :
2011-08-06 23:45:52 +00:00
wx . CallAfter ( self . pausebtn . SetLabel , _ ( " Pause " ) )
2011-08-04 22:32:22 +00:00
wx . CallAfter ( self . pausebtn . Enable )
2011-08-06 23:45:52 +00:00
wx . CallAfter ( self . printbtn . SetLabel , _ ( " Restart " ) )
2012-03-20 17:57:57 +00:00
2011-06-08 22:02:00 +00:00
def endupload ( self ) :
self . p . send_now ( " M29 " )
2011-08-06 23:45:52 +00:00
wx . CallAfter ( self . status . SetStatusText , _ ( " File upload complete " ) )
2011-06-08 22:02:00 +00:00
time . sleep ( 0.5 )
2012-08-08 07:38:48 +00:00
self . p . clear = True
self . uploading = False
2012-03-20 17:57:57 +00:00
2012-08-08 07:38:48 +00:00
def uploadtrigger ( self , l ) :
2011-06-08 22:02:00 +00:00
if " Writing to file " in l :
2012-08-08 07:38:48 +00:00
self . uploading = True
2011-06-08 22:02:00 +00:00
self . p . startprint ( self . f )
2012-08-08 07:38:48 +00:00
self . p . endcb = self . endupload
2011-06-08 22:02:00 +00:00
self . recvlisteners . remove ( self . uploadtrigger )
elif " open failed, File " in l :
self . recvlisteners . remove ( self . uploadtrigger )
2012-03-20 17:57:57 +00:00
2012-08-08 07:38:48 +00:00
def upload ( self , event ) :
2011-12-04 00:58:47 +00:00
if not self . f or not len ( self . f ) :
2011-06-08 22:02:00 +00:00
return
if not self . p . online :
return
2012-08-08 07:38:48 +00:00
dlg = wx . TextEntryDialog ( self , ( " Enter a target filename in 8.3 format: " ) , _ ( " Pick SD filename " ) , dosify ( self . filename ) )
if dlg . ShowModal ( ) == wx . ID_OK :
2011-11-30 13:18:12 +00:00
self . p . send_now ( " M21 " )
2011-06-11 21:03:01 +00:00
self . p . send_now ( " M28 " + str ( dlg . GetValue ( ) ) )
2011-06-08 22:02:00 +00:00
self . recvlisteners + = [ self . uploadtrigger ]
2012-03-20 17:57:57 +00:00
2012-08-08 07:38:48 +00:00
def pause ( self , event ) :
2011-10-07 16:31:23 +00:00
print _ ( " Paused. " )
2011-06-08 14:19:38 +00:00
if not self . paused :
if self . sdprinting :
self . p . send_now ( " M25 " )
else :
if ( not self . p . printing ) :
#print "Not printing, cannot pause."
return
self . p . pause ( )
2013-04-07 17:45:45 +00:00
self . p . runSmallScript ( self . pauseScript )
2012-08-08 07:38:48 +00:00
self . paused = True
2013-04-07 17:45:45 +00:00
#self.p.runSmallScript(self.pauseScript)
2012-03-16 03:37:05 +00:00
self . extra_print_time + = int ( time . time ( ) - self . starttime )
2011-08-06 23:45:52 +00:00
wx . CallAfter ( self . pausebtn . SetLabel , _ ( " Resume " ) )
2011-06-08 14:19:38 +00:00
else :
2012-08-08 07:38:48 +00:00
self . paused = False
2011-06-08 14:19:38 +00:00
if self . sdprinting :
self . p . send_now ( " M24 " )
else :
self . p . resume ( )
2011-08-06 23:45:52 +00:00
wx . CallAfter ( self . pausebtn . SetLabel , _ ( " Pause " ) )
2012-03-20 17:57:57 +00:00
2012-08-08 07:38:48 +00:00
def sdprintfile ( self , event ) :
2011-07-09 13:54:59 +00:00
self . on_startprint ( )
2012-08-08 07:38:48 +00:00
threading . Thread ( target = self . getfiles ) . start ( )
2012-03-20 17:57:57 +00:00
2012-08-08 07:38:48 +00:00
def connect ( self , event ) :
2011-10-07 16:31:23 +00:00
print _ ( " Connecting... " )
2012-08-08 07:38:48 +00:00
port = None
2011-06-08 14:19:38 +00:00
try :
2012-08-08 07:38:48 +00:00
port = self . scanserial ( ) [ 0 ]
2011-06-08 14:19:38 +00:00
except :
pass
if self . serialport . GetValue ( ) != " " :
2012-08-08 07:38:48 +00:00
port = str ( self . serialport . GetValue ( ) )
baud = 115200
2011-06-08 14:19:38 +00:00
try :
2012-08-08 07:38:48 +00:00
baud = int ( self . baud . GetValue ( ) )
2011-06-08 14:19:38 +00:00
except :
pass
2011-06-10 18:34:04 +00:00
if self . paused :
2012-08-08 07:38:48 +00:00
self . p . paused = 0
self . p . printing = 0
2011-08-06 23:45:52 +00:00
wx . CallAfter ( self . pausebtn . SetLabel , _ ( " Pause " ) )
wx . CallAfter ( self . printbtn . SetLabel , _ ( " Print " ) )
2012-08-08 07:38:48 +00:00
self . paused = 0
2011-06-10 18:34:04 +00:00
if self . sdprinting :
self . p . send_now ( " M26 S0 " )
Tell the user, there was an error while connecting
Before, when there was an error while connecting, user didn't know, when
Pronterface wasn't launched from the terminal.
So you could just hit Connect button several times and all you've get was:
Connecting...
Connecting...
Connecting...
Now, when there is an exception during the connection, the user will notice:
Connecting...
Error: You are trying to connect to a non-exisiting port.
Or:
Connecting...
Error: You don't have permission to open /dev/ttyUSB0.
You might need to add yourself to the dialout group.
Unfortunately pyserial's SerialException doesn't provide errno yet, so the
message isn't so user friendly:
Connecting...
could not open port None: [Errno 2] No such file or directory: 'None'
I've filled a bug report with patch to pyserial.
Together with this I've realised, there is unnecessary UTF8 decoding of the
output. When user has UTF-8 locale, there was an exception when printing the
exception to the output (almost an exception inception). So I have dropped it,
but feel free to add it back, if I broke anything else.
2013-01-15 20:22:56 +00:00
try :
self . p . connect ( port , baud )
except SerialException as e :
# Currently, there is no errno, but it should be there in the future
if e . errno == 2 :
print _ ( " Error: You are trying to connect to a non-exisiting port. " )
elif e . errno == 8 :
print _ ( " Error: You don ' t have permission to open %s . " ) % port
print _ ( " You might need to add yourself to the dialout group. " )
else :
print e
2013-01-23 16:12:01 +00:00
# Kill the scope anyway
return
2012-08-08 07:38:48 +00:00
self . statuscheck = True
2011-06-29 20:34:27 +00:00
if port != self . settings . port :
2012-08-08 07:58:09 +00:00
self . set ( " port " , port )
2011-06-29 20:34:27 +00:00
if baud != self . settings . baudrate :
2012-08-08 07:58:09 +00:00
self . set ( " baudrate " , str ( baud ) )
2012-08-04 20:24:45 +00:00
self . status_thread = threading . Thread ( target = self . statuschecker )
self . status_thread . start ( )
2012-08-06 17:18:45 +00:00
if self . predisconnect_mainqueue :
self . recoverbtn . Enable ( )
2012-03-20 17:57:57 +00:00
2012-08-04 21:15:50 +00:00
def recover ( self , event ) :
self . extra_print_time = 0
if not self . p . online :
2012-08-08 07:38:48 +00:00
wx . CallAfter ( self . status . SetStatusText , _ ( " Not connected to printer. " ) )
2012-08-04 21:15:50 +00:00
return
# Reset Z
2012-08-06 21:25:01 +00:00
self . p . send_now ( " G92 Z %f " % self . predisconnect_layer )
2012-08-04 21:15:50 +00:00
# Home X and Y
self . p . send_now ( " G28 X Y " )
self . on_startprint ( )
2012-08-06 21:25:01 +00:00
self . p . startprint ( self . predisconnect_mainqueue , self . p . queueindex )
2012-08-04 21:15:50 +00:00
def store_predisconnect_state ( self ) :
self . predisconnect_mainqueue = self . p . mainqueue
self . predisconnect_queueindex = self . p . queueindex
self . predisconnect_layer = self . curlayer
2012-08-08 07:38:48 +00:00
def disconnect ( self , event ) :
2011-10-07 16:31:23 +00:00
print _ ( " Disconnected. " )
2012-08-04 21:15:50 +00:00
if self . p . printing or self . p . paused or self . paused :
self . store_predisconnect_state ( )
2011-06-08 14:19:38 +00:00
self . p . disconnect ( )
2012-08-04 20:24:45 +00:00
self . statuscheck = False
2012-08-04 21:18:17 +00:00
if self . status_thread :
self . status_thread . join ( )
self . status_thread = None
2012-03-20 17:57:57 +00:00
2012-08-08 06:40:22 +00:00
self . connectbtn . SetLabel ( _ ( " Connect " ) )
2012-05-08 13:53:33 +00:00
self . connectbtn . SetToolTip ( wx . ToolTip ( " Connect to the printer " ) )
2012-08-08 07:38:48 +00:00
self . connectbtn . Bind ( wx . EVT_BUTTON , self . connect )
2011-12-04 01:17:19 +00:00
2012-08-07 11:49:58 +00:00
wx . CallAfter ( self . printbtn . Disable )
wx . CallAfter ( self . pausebtn . Disable )
wx . CallAfter ( self . recoverbtn . Disable )
2011-07-09 13:38:49 +00:00
for i in self . printerControls :
2011-07-27 15:23:28 +00:00
wx . CallAfter ( i . Disable )
2011-11-11 16:37:01 +00:00
# Disable XYButtons and ZButtons
2011-11-14 15:20:32 +00:00
wx . CallAfter ( self . xyb . disable )
wx . CallAfter ( self . zb . disable )
2012-03-20 17:57:57 +00:00
2011-06-10 18:34:04 +00:00
if self . paused :
2012-08-08 07:38:48 +00:00
self . p . paused = 0
self . p . printing = 0
2011-08-06 23:45:52 +00:00
wx . CallAfter ( self . pausebtn . SetLabel , _ ( " Pause " ) )
wx . CallAfter ( self . printbtn . SetLabel , _ ( " Print " ) )
2012-08-08 07:38:48 +00:00
self . paused = 0
2011-06-10 18:34:04 +00:00
if self . sdprinting :
self . p . send_now ( " M26 S0 " )
2012-03-20 17:57:57 +00:00
2012-08-08 07:38:48 +00:00
def reset ( self , event ) :
2011-10-07 16:31:23 +00:00
print _ ( " Reset. " )
2012-08-08 07:38:48 +00:00
dlg = wx . MessageDialog ( self , _ ( " Are you sure you want to reset the printer? " ) , _ ( " Reset? " ) , wx . YES | wx . NO )
if dlg . ShowModal ( ) == wx . ID_YES :
2011-06-08 14:19:38 +00:00
self . p . reset ( )
2012-07-15 11:43:34 +00:00
self . sethotendgui ( 0 )
self . setbedgui ( 0 )
2012-08-08 07:38:48 +00:00
self . p . printing = 0
2012-02-28 02:08:56 +00:00
wx . CallAfter ( self . printbtn . SetLabel , _ ( " Print " ) )
2011-06-10 18:34:04 +00:00
if self . paused :
2012-08-08 07:38:48 +00:00
self . p . paused = 0
2011-08-06 23:45:52 +00:00
wx . CallAfter ( self . pausebtn . SetLabel , _ ( " Pause " ) )
2012-08-08 07:38:48 +00:00
self . paused = 0
2012-03-20 17:57:57 +00:00
2012-08-08 07:38:48 +00:00
def get_build_dimensions ( self , bdim ) :
2011-12-11 09:11:47 +00:00
import re
# a string containing up to six numbers delimited by almost anything
# first 0-3 numbers specify the build volume, no sign, always positive
# remaining 0-3 numbers specify the coordinates of the "southwest" corner of the build platform
2012-08-08 08:10:14 +00:00
# "XXX,YYY"
2011-12-11 09:11:47 +00:00
# "XXXxYYY+xxx-yyy"
2012-08-08 08:10:14 +00:00
# "XXX,YYY,ZZZ+xxx+yyy-zzz"
2011-12-11 09:11:47 +00:00
# etc
bdl = re . match (
" [^ \ d+-]*( \ d+)? " + # X build size
" [^ \ d+-]*( \ d+)? " + # Y build size
" [^ \ d+-]*( \ d+)? " + # Z build size
" [^ \ d+-]*([+-] \ d+)? " + # X corner coordinate
" [^ \ d+-]*([+-] \ d+)? " + # Y corner coordinate
2013-04-07 17:45:45 +00:00
" [^ \ d+-]*([+-] \ d+)? " + # Z corner coordinate
" [^ \ d+-]*([+-] \ d+)? " + # X endstop
" [^ \ d+-]*([+-] \ d+)? " + # Y endstop
" [^ \ d+-]*([+-] \ d+)? " # Z endstop
2011-12-11 09:11:47 +00:00
, bdim ) . groups ( )
2013-04-07 17:45:45 +00:00
defaults = [ 200 , 200 , 100 , 0 , 0 , 0 , 0 , 0 , 0 ]
2011-12-11 09:17:29 +00:00
bdl_float = [ float ( value ) if value else defaults [ i ] for i , value in enumerate ( bdl ) ]
2011-12-11 09:11:47 +00:00
return bdl_float
2011-06-08 14:19:38 +00:00
if __name__ == ' __main__ ' :
app = wx . App ( False )
main = PronterWindow ( )
main . Show ( )
2011-06-16 04:28:46 +00:00
try :
app . MainLoop ( )
2013-05-16 18:47:39 +00:00
except KeyboardInterrupt :
2011-06-16 04:28:46 +00:00
pass
2013-05-18 10:50:18 +00:00
del app