Commit 28a3df5e authored by D1plo1d's avatar D1plo1d

Merge branch 'experimental' of github.com:kliment/Printrun into experimental

parents 99747933 ddf5eff7
...@@ -119,7 +119,7 @@ To use pronterface, you need: ...@@ -119,7 +119,7 @@ To use pronterface, you need:
* numpy (for 3D view) * numpy (for 3D view)
* pyreadline (not needed on Linux) and * pyreadline (not needed on Linux) and
* argparse (installed by default with python >= 2.7) * argparse (installed by default with python >= 2.7)
* wxPython * wxPython (some features such as Tabbed mode work better with wx 2.9)
* pycairo (to use Projector feature) * pycairo (to use Projector feature)
Please see specific instructions for Windows and Mac OS X below. Under Linux, you should use your package manager directly (see the "GETTING PRINTRUN" section) Please see specific instructions for Windows and Mac OS X below. Under Linux, you should use your package manager directly (see the "GETTING PRINTRUN" section)
......
* Rework gcview zooming/rotation/move behavior
* Improve stlview
* Add tool to select gcode area to ignore
* Add calibration helper
* Improve tabbed mode for wx 2.8 ? (the main toolbar is not wrapping as in 2.9)
...@@ -17,15 +17,25 @@ ...@@ -17,15 +17,25 @@
from serial import Serial, SerialException from serial import Serial, SerialException
from select import error as SelectError from select import error as SelectError
from threading import Thread from threading import Thread, Lock
from Queue import Queue, Empty as QueueEmpty
import time, getopt, sys import time, getopt, sys
import platform, os, traceback import platform, os, traceback
import socket import socket
import re import re
from functools import wraps
from collections import deque from collections import deque
from printrun.GCodeAnalyzer import GCodeAnalyzer from printrun.GCodeAnalyzer import GCodeAnalyzer
from printrun import gcoder from printrun import gcoder
def locked(f):
@wraps(f)
def inner(*args, **kw):
with inner.lock:
return f(*args, **kw)
inner.lock = Lock()
return inner
def control_ttyhup(port, disable_hup): def control_ttyhup(port, disable_hup):
"""Controls the HUPCL""" """Controls the HUPCL"""
if platform.system() == "Linux": if platform.system() == "Linux":
...@@ -52,7 +62,7 @@ class printcore(): ...@@ -52,7 +62,7 @@ class printcore():
self.online = False #The printer has responded to the initial command and is active self.online = False #The printer has responded to the initial command and is active
self.printing = False #is a print currently running, true if printing, false if paused self.printing = False #is a print currently running, true if printing, false if paused
self.mainqueue = None self.mainqueue = None
self.priqueue = [] self.priqueue = Queue(0)
self.queueindex = 0 self.queueindex = 0
self.lineno = 0 self.lineno = 0
self.resendfrom = -1 self.resendfrom = -1
...@@ -60,6 +70,7 @@ class printcore(): ...@@ -60,6 +70,7 @@ class printcore():
self.sentlines = {} self.sentlines = {}
self.log = deque(maxlen = 10000) self.log = deque(maxlen = 10000)
self.sent = [] self.sent = []
self.writefailures = 0
self.tempcb = None #impl (wholeline) self.tempcb = None #impl (wholeline)
self.recvcb = None #impl (wholeline) self.recvcb = None #impl (wholeline)
self.sendcb = None #impl (wholeline) self.sendcb = None #impl (wholeline)
...@@ -74,6 +85,8 @@ class printcore(): ...@@ -74,6 +85,8 @@ class printcore():
self.wait = 0 # default wait period for send(), send_now() self.wait = 0 # default wait period for send(), send_now()
self.read_thread = None self.read_thread = None
self.stop_read_thread = False self.stop_read_thread = False
self.send_thread = None
self.stop_send_thread = False
self.print_thread = None self.print_thread = None
if port is not None and baud is not None: if port is not None and baud is not None:
self.connect(port, baud) self.connect(port, baud)
...@@ -89,6 +102,7 @@ class printcore(): ...@@ -89,6 +102,7 @@ class printcore():
self.stop_read_thread = True self.stop_read_thread = True
self.read_thread.join() self.read_thread.join()
self.read_thread = None self.read_thread = None
self._stop_sender()
try: try:
self.printer.close() self.printer.close()
except socket.error: except socket.error:
...@@ -97,6 +111,7 @@ class printcore(): ...@@ -97,6 +111,7 @@ class printcore():
self.online = False self.online = False
self.printing = False self.printing = False
@locked
def connect(self, port = None, baud = None): def connect(self, port = None, baud = None):
"""Set port and baudrate if given, then connect to printer """Set port and baudrate if given, then connect to printer
""" """
...@@ -120,31 +135,35 @@ class printcore(): ...@@ -120,31 +135,35 @@ class printcore():
is_serial = False is_serial = False
except: except:
pass pass
self.writefailures = 0
if not is_serial: if not is_serial:
self.printer_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.printer_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.timeout = 0.25 self.timeout = 0.25
self.printer_tcp.settimeout(1.0)
try: try:
self.printer_tcp.connect((hostname, port)) self.printer_tcp.connect((hostname, port))
self.printer_tcp.settimeout(self.timeout)
self.printer = self.printer_tcp.makefile() self.printer = self.printer_tcp.makefile()
except socket.error: except socket.error as e:
print _("Could not connect to %s:%s:") % (hostname, port) print _("Could not connect to %s:%s:") % (hostname, port)
self.printer = None self.printer = None
self.printer_tcp = None self.printer_tcp = None
traceback.print_exc() print _("Socket error %s: %s") % (e.errno, e.strerror)
return return
else: else:
disable_hup(self.port) disable_hup(self.port)
self.printer_tcp = None self.printer_tcp = None
try: try:
self.printer = Serial(port = self.port, baudrate = self.baud, timeout = 0.25) self.printer = Serial(port = self.port, baudrate = self.baud, timeout = 0.25)
except SerialException: except SerialException as e:
print _("Could not connect to %s at baudrate %s:") % (self.port, self.baud) print _("Could not connect to %s at baudrate %s:") % (self.port, self.baud)
self.printer = None self.printer = None
traceback.print_exc() print _("Serial error: %s") % e
return return
self.stop_read_thread = False self.stop_read_thread = False
self.read_thread = Thread(target = self._listen) self.read_thread = Thread(target = self._listen)
self.read_thread.start() self.read_thread.start()
self._start_sender()
def reset(self): def reset(self):
"""Reset the printer """Reset the printer
...@@ -178,7 +197,7 @@ class printcore(): ...@@ -178,7 +197,7 @@ class printcore():
print "SelectError ({0}): {1}".format(e.errno, e.strerror) print "SelectError ({0}): {1}".format(e.errno, e.strerror)
raise raise
except SerialException as e: except SerialException as e:
print "Can't read from printer (disconnected?) (SerialException {0}): {1}".format(e.errno, e.strerror) print "Can't read from printer (disconnected?) (SerialException): {0}".format(e)
return None return None
except socket.error as e: except socket.error as e:
print "Can't read from printer (disconnected?) (Socket error {0}): {1}".format(e.errno, e.strerror) print "Can't read from printer (disconnected?) (Socket error {0}): {1}".format(e.errno, e.strerror)
...@@ -254,6 +273,29 @@ class printcore(): ...@@ -254,6 +273,29 @@ class printcore():
self.clear = True self.clear = True
self.clear = True self.clear = True
def _start_sender(self):
self.stop_send_thread = False
self.send_thread = Thread(target = self._sender)
self.send_thread.start()
def _stop_sender(self):
if self.send_thread:
self.stop_send_thread = True
self.send_thread.join()
self.send_thread = None
def _sender(self):
while not self.stop_send_thread:
try:
command = self.priqueue.get(True, 0.1)
except QueueEmpty:
continue
while self.printer and self.printing and not self.clear:
time.sleep(0.001)
self._send(command)
while self.printer and self.printing and not self.clear:
time.sleep(0.001)
def _checksum(self, command): def _checksum(self, command):
return reduce(lambda x, y:x^y, map(ord, command)) return reduce(lambda x, y:x^y, map(ord, command))
...@@ -302,7 +344,6 @@ class printcore(): ...@@ -302,7 +344,6 @@ class printcore():
self.printing = False self.printing = False
# try joining the print thread: enclose it in try/except because we might be calling it from the thread itself # try joining the print thread: enclose it in try/except because we might be calling it from the thread itself
try: try:
self.print_thread.join() self.print_thread.join()
except: except:
...@@ -318,8 +359,6 @@ class printcore(): ...@@ -318,8 +359,6 @@ class printcore():
self.pauseF = self.analyzer.f; self.pauseF = self.analyzer.f;
self.pauseRelative = self.analyzer.relative; self.pauseRelative = self.analyzer.relative;
def resume(self): def resume(self):
"""Resumes a paused print. """Resumes a paused print.
""" """
...@@ -343,7 +382,7 @@ class printcore(): ...@@ -343,7 +382,7 @@ class printcore():
self.paused = False self.paused = False
self.printing = True self.printing = True
self.print_thread = Thread(target = self._print) self.print_thread = Thread(target = self._print, kwargs = {"resuming": True})
self.print_thread.start() self.print_thread.start()
def send(self, command, wait = 0): def send(self, command, wait = 0):
...@@ -354,17 +393,7 @@ class printcore(): ...@@ -354,17 +393,7 @@ class printcore():
if self.printing: if self.printing:
self.mainqueue.append(command) self.mainqueue.append(command)
else: else:
while self.printer and self.printing and not self.clear: self.priqueue.put_nowait(command)
time.sleep(0.001)
if wait == 0 and self.wait > 0:
wait = self.wait
if wait > 0:
self.clear = False
self._send(command, self.lineno, True)
self.lineno += 1
while wait > 0 and self.printer and self.printing and not self.clear:
time.sleep(0.001)
wait -= 1
else: else:
print "Not connected to printer." print "Not connected to printer."
...@@ -372,40 +401,32 @@ class printcore(): ...@@ -372,40 +401,32 @@ class printcore():
"""Sends a command to the printer ahead of the command queue, without a checksum """Sends a command to the printer ahead of the command queue, without a checksum
""" """
if self.online: if self.online:
if self.printing: self.priqueue.put_nowait(command)
self.priqueue.append(command)
else:
while self.printer and self.printing and not self.clear:
time.sleep(0.001)
if wait == 0 and self.wait > 0:
wait = self.wait
if wait > 0:
self.clear = False
self._send(command)
while (wait > 0) and self.printer and self.printing and not self.clear:
time.sleep(0.001)
wait -= 1
else: else:
print "Not connected to printer." print "Not connected to printer."
def _print(self): def _print(self, resuming = False):
self._stop_sender()
try:
if self.startcb: if self.startcb:
#callback for printing started #callback for printing started
try: self.startcb() try: self.startcb(resuming)
except: pass except: pass
while self.printing and self.printer and self.online: while self.printing and self.printer and self.online:
self._sendnext() self._sendnext()
self.sentlines = {} self.sentlines = {}
self.log.clear() self.log.clear()
self.sent = [] self.sent = []
try:
self.print_thread.join()
except: pass
self.print_thread = None
if self.endcb: if self.endcb:
#callback for printing done #callback for printing done
try: self.endcb() try: self.endcb()
except: pass except: pass
except:
print "Print thread died due to the following error:"
traceback.print_exc()
finally:
self.print_thread = None
self._start_sender()
#now only "pause" is implemented as host command #now only "pause" is implemented as host command
def processHostCommand(self, command): def processHostCommand(self, command):
...@@ -430,8 +451,9 @@ class printcore(): ...@@ -430,8 +451,9 @@ class printcore():
self.resendfrom += 1 self.resendfrom += 1
return return
self.resendfrom = -1 self.resendfrom = -1
if self.priqueue: if not self.priqueue.empty():
self._send(self.priqueue.pop(0)) self._send(self.priqueue.get_nowait())
self.priqueue.task_done()
return return
if self.printing and self.queueindex < len(self.mainqueue): if self.printing and self.queueindex < len(self.mainqueue):
(layer, line) = self.mainqueue.idxs(self.queueindex) (layer, line) = self.mainqueue.idxs(self.queueindex)
...@@ -439,10 +461,10 @@ class printcore(): ...@@ -439,10 +461,10 @@ class printcore():
if self.layerchangecb and self.queueindex > 0: if self.layerchangecb and self.queueindex > 0:
(prev_layer, prev_line) = self.mainqueue.idxs(self.queueindex - 1) (prev_layer, prev_line) = self.mainqueue.idxs(self.queueindex - 1)
if prev_layer != layer: if prev_layer != layer:
self.layerchangecb(layer) try: self.layerchangecb(layer)
except: traceback.print_exc()
tline = gline.raw tline = gline.raw
#check for host command if tline.lstrip().startswith(";@"): # check for host command
if tline.lstrip().startswith(";@"):
self.processHostCommand(tline) self.processHostCommand(tline)
self.queueindex += 1 self.queueindex += 1
return return
...@@ -453,7 +475,7 @@ class printcore(): ...@@ -453,7 +475,7 @@ class printcore():
self.lineno += 1 self.lineno += 1
if self.printsendcb: if self.printsendcb:
try: self.printsendcb(gline) try: self.printsendcb(gline)
except: pass except: traceback.print_exc()
else: else:
self.clear = True self.clear = True
self.queueindex += 1 self.queueindex += 1
...@@ -482,12 +504,16 @@ class printcore(): ...@@ -482,12 +504,16 @@ class printcore():
try: try:
self.printer.write(str(command + "\n")) self.printer.write(str(command + "\n"))
self.printer.flush() self.printer.flush()
self.writefailures = 0
except socket.error as e: except socket.error as e:
print "Can't write to printer (disconnected?) (Socket error {0}): {1}".format(e.errno, e.strerror) print "Can't write to printer (disconnected?) (Socket error {0}): {1}".format(e.errno, e.strerror)
self.writefailures += 1
except SerialException as e: except SerialException as e:
print "Can't write to printer (disconnected?) (SerialException {0}): {1}".format(e.errno, e.strerror) print "Can't write to printer (disconnected?) (SerialException): {0}".format(e)
self.writefailures += 1
except RuntimeError as e: except RuntimeError as e:
print "Socket connection broken, disconnected. ({0}): {1}".format(e.errno, e.strerror) print "Socket connection broken, disconnected. ({0}): {1}".format(e.errno, e.strerror)
self.writefailures += 1
if __name__ == '__main__': if __name__ == '__main__':
baud = 115200 baud = 115200
......
...@@ -51,6 +51,7 @@ class GCodeAnalyzer(): ...@@ -51,6 +51,7 @@ class GCodeAnalyzer():
self.eOffset = 0 self.eOffset = 0
self.lastZPrint = 0 self.lastZPrint = 0
self.layerZ = 0 self.layerZ = 0
self.imperial = False
self.relative = False self.relative = False
self.eRelative = False self.eRelative = False
self.homeX = 0 self.homeX = 0
...@@ -69,6 +70,7 @@ class GCodeAnalyzer(): ...@@ -69,6 +70,7 @@ class GCodeAnalyzer():
def Analyze(self, gcode): def Analyze(self, gcode):
gline = gcoder.Line(gcode) gline = gcoder.Line(gcode)
if gline.command.startswith(";@"): return # code is a host command if gline.command.startswith(";@"): return # code is a host command
gline.parse_coordinates(self.imperial)
code_g = int(gline.command[1:]) if gline.command.startswith("G") else None code_g = int(gline.command[1:]) if gline.command.startswith("G") else None
code_m = int(gline.command[1:]) if gline.command.startswith("M") else None code_m = int(gline.command[1:]) if gline.command.startswith("M") else None
...@@ -97,7 +99,7 @@ class GCodeAnalyzer(): ...@@ -97,7 +99,7 @@ class GCodeAnalyzer():
eChanged = True eChanged = True
self.e += code_e self.e += code_e
else: else:
#absolute coordinates # absolute coordinates
if code_x != None: self.x = self.xOffset + code_x if code_x != None: self.x = self.xOffset + code_x
if code_y != None: self.y = self.yOffset + code_y if code_y != None: self.y = self.yOffset + code_y
if code_z != None: self.z = self.zOffset + code_z if code_z != None: self.z = self.zOffset + code_z
...@@ -112,6 +114,7 @@ class GCodeAnalyzer(): ...@@ -112,6 +114,7 @@ class GCodeAnalyzer():
eChanged = True eChanged = True
self.e = self.eOffset + code_e self.e = self.eOffset + code_e
#limit checking #limit checking
"""
if self.x < self.minX: self.x = self.minX if self.x < self.minX: self.x = self.minX
if self.y < self.minY: self.y = self.minY if self.y < self.minY: self.y = self.minY
if self.z < self.minZ: self.z = self.minZ if self.z < self.minZ: self.z = self.minZ
...@@ -119,7 +122,10 @@ class GCodeAnalyzer(): ...@@ -119,7 +122,10 @@ class GCodeAnalyzer():
if self.x > self.maxX: self.x = self.maxX if self.x > self.maxX: self.x = self.maxX
if self.y > self.maxY: self.y = self.maxY if self.y > self.maxY: self.y = self.maxY
if self.z > self.maxZ: self.z = self.maxZ if self.z > self.maxZ: self.z = self.maxZ
"""
#Repetier has a bunch of limit-checking code here and time calculations: we are leaving them for now #Repetier has a bunch of limit-checking code here and time calculations: we are leaving them for now
elif code_g == 20: self.imperial = True
elif code_g == 21: self.imperial = False
elif code_g == 28 or code_g == 161: elif code_g == 28 or code_g == 161:
self.lastX = self.x self.lastX = self.x
self.lastY = self.y self.lastY = self.y
...@@ -189,7 +195,6 @@ class GCodeAnalyzer(): ...@@ -189,7 +195,6 @@ class GCodeAnalyzer():
self.e = self.eOffset self.e = self.eOffset
#End code_g != None #End code_g != None
if code_m != None: if code_m != None:
code_m = int(code_m)
if code_m == 82: self.eRelative = False if code_m == 82: self.eRelative = False
elif code_m == 83: self.eRelative = True elif code_m == 83: self.eRelative = True
......
#!/usr/bin/python #!/usr/bin/env python
# This file is part of the Printrun suite. # This file is part of the Printrun suite.
# #
# Printrun is free software: you can redistribute it and/or modify # Printrun is free software: you can redistribute it and/or modify
......
#!/usr/bin/python #!/usr/bin/env python
# This file is part of the Printrun suite. # This file is part of the Printrun suite.
# #
......
#!/usr/bin/python #!/usr/bin/env python
# This file is part of the Printrun suite. # This file is part of the Printrun suite.
# #
......
...@@ -165,6 +165,7 @@ def add_extra_controls(self, root, parentpanel, extra_buttons = None): ...@@ -165,6 +165,7 @@ def add_extra_controls(self, root, parentpanel, extra_buttons = None):
else: else:
self.Add(root.tempdisp, pos = (gauges_base_line + 0, 0), span = (1, 6)) self.Add(root.tempdisp, pos = (gauges_base_line + 0, 0), span = (1, 6))
if root.display_graph:
root.graph = Graph(parentpanel, wx.ID_ANY, root) root.graph = Graph(parentpanel, wx.ID_ANY, root)
if standalone_mode: if standalone_mode:
self.Add(root.graph, pos = (base_line + 5, 0), span = (3, 6)) self.Add(root.graph, pos = (base_line + 5, 0), span = (3, 6))
...@@ -292,9 +293,7 @@ class VizPane(wx.BoxSizer): ...@@ -292,9 +293,7 @@ class VizPane(wx.BoxSizer):
extrusion_width = root.settings.preview_extrusion_width) extrusion_width = root.settings.preview_extrusion_width)
root.gwindow.Bind(wx.EVT_CLOSE, lambda x: root.gwindow.Hide()) root.gwindow.Bind(wx.EVT_CLOSE, lambda x: root.gwindow.Hide())
if not isinstance(root.gviz, NoViz): if not isinstance(root.gviz, NoViz):
self.Add(root.gviz.widget, 1, flag = wx.SHAPED) self.Add(root.gviz.widget, 1, flag = wx.SHAPED | wx.ALIGN_CENTER_HORIZONTAL)
root.centersizer = wx.GridBagSizer()
self.Add(root.centersizer, 0, flag = wx.EXPAND)
class LogPane(wx.BoxSizer): class LogPane(wx.BoxSizer):
...@@ -390,7 +389,8 @@ class MainWindow(wx.Frame): ...@@ -390,7 +389,8 @@ class MainWindow(wx.Frame):
rightsizer = wx.BoxSizer(wx.VERTICAL) rightsizer = wx.BoxSizer(wx.VERTICAL)
extracontrols = wx.GridBagSizer() extracontrols = wx.GridBagSizer()
add_extra_controls(extracontrols, self, page1panel2, left_pane.extra_buttons) add_extra_controls(extracontrols, self, page1panel2, left_pane.extra_buttons)
rightsizer.Add(extracontrols, 1, wx.ALIGN_CENTER) rightsizer.AddStretchSpacer()
rightsizer.Add(extracontrols, 0, wx.ALIGN_CENTER)
self.lowersizer.Add(leftsizer, 1, wx.ALIGN_CENTER) self.lowersizer.Add(leftsizer, 1, wx.ALIGN_CENTER)
self.lowersizer.Add(rightsizer, 1, wx.ALIGN_CENTER) self.lowersizer.Add(rightsizer, 1, wx.ALIGN_CENTER)
self.mainsizer_page1.Add(page1panel2, 1, wx.EXPAND) self.mainsizer_page1.Add(page1panel2, 1, wx.EXPAND)
...@@ -414,13 +414,17 @@ class MainWindow(wx.Frame): ...@@ -414,13 +414,17 @@ class MainWindow(wx.Frame):
self.notebook.AddPage(page1panel, _("Commands")) self.notebook.AddPage(page1panel, _("Commands"))
self.notebook.AddPage(page2panel, _("Status")) self.notebook.AddPage(page2panel, _("Status"))
self.panel.SetSizer(self.notesizer) self.panel.SetSizer(self.notesizer)
self.status = self.CreateStatusBar() self.statusbar = self.CreateStatusBar()
self.status.SetStatusText(_("Not connected to printer.")) self.statusbar.SetStatusText(_("Not connected to printer."))
self.panel.Bind(wx.EVT_MOUSE_EVENTS, self.editbutton) self.panel.Bind(wx.EVT_MOUSE_EVENTS, self.editbutton)
self.Bind(wx.EVT_CLOSE, self.kill) self.Bind(wx.EVT_CLOSE, self.kill)
vizpane.Detach(self.centersizer) # Custom buttons
rightsizer.Add(self.centersizer, 0, wx.EXPAND) self.centersizer = wx.GridBagSizer()
self.centerpanel = self.newPanel(page1panel2)
self.centerpanel.SetSizer(self.centersizer)
rightsizer.Add(self.centerpanel, 0, wx.ALIGN_CENTER)
rightsizer.AddStretchSpacer()
self.panel.SetSizerAndFit(self.notesizer) self.panel.SetSizerAndFit(self.notesizer)
...@@ -430,22 +434,42 @@ class MainWindow(wx.Frame): ...@@ -430,22 +434,42 @@ class MainWindow(wx.Frame):
for i in self.printerControls: for i in self.printerControls:
i.Disable() i.Disable()
#self.panel.Fit()
self.cbuttons_panel = page1panel
self.cbuttons_reload() self.cbuttons_reload()
def createGui(self): def createGui(self, compact = False):
self.mainsizer = wx.BoxSizer(wx.VERTICAL) self.mainsizer = wx.BoxSizer(wx.VERTICAL)
self.uppersizer = MainToolbar(self)
self.lowersizer = wx.BoxSizer(wx.HORIZONTAL) self.lowersizer = wx.BoxSizer(wx.HORIZONTAL)
self.lowersizer.Add(LeftPane(self), 0) upperpanel = self.newPanel(self.panel)
self.lowersizer.Add(VizPane(self), 1, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL) self.uppersizer = MainToolbar(self, upperpanel)
self.lowersizer.Add(LogPane(self), 1, wx.EXPAND) lowerpanel = self.newPanel(self.panel)
self.mainsizer.Add(self.uppersizer, 0) upperpanel.SetSizer(self.uppersizer)
self.mainsizer.Add(self.lowersizer, 1, wx.EXPAND) lowerpanel.SetSizer(self.lowersizer)
left_pane = LeftPane(self, lowerpanel)
left_pane.Layout() # required to get correct rows/cols counts
left_sizer = wx.BoxSizer(wx.VERTICAL)
left_sizer.Add(left_pane, 0)
self.lowersizer.Add(left_sizer, 0, wx.EXPAND)
vizpanel = self.newPanel(lowerpanel)
viz_pane = VizPane(self, vizpanel)
# Custom buttons
self.centersizer = wx.GridBagSizer()
self.centerpanel = self.newPanel(vizpanel)
self.centerpanel.SetSizer(self.centersizer)
viz_pane.Add(self.centerpanel, 0, flag = wx.ALIGN_CENTER)
vizpanel.SetSizer(viz_pane)
self.lowersizer.Add(vizpanel, 1, wx.EXPAND | wx.ALIGN_CENTER)
logpanel = self.newPanel(lowerpanel)
log_pane = LogPane(self, logpanel)
logpanel.SetSizer(log_pane)
if compact:
left_sizer.Add(logpanel, 1, wx.EXPAND)
else:
self.lowersizer.Add(logpanel, 1, wx.EXPAND)
self.mainsizer.Add(upperpanel, 0)
self.mainsizer.Add(lowerpanel, 1, wx.EXPAND)
self.panel.SetSizer(self.mainsizer) self.panel.SetSizer(self.mainsizer)
self.status = self.CreateStatusBar() self.statusbar = self.CreateStatusBar()
self.status.SetStatusText(_("Not connected to printer.")) self.statusbar.SetStatusText(_("Not connected to printer."))
self.panel.Bind(wx.EVT_MOUSE_EVENTS, self.editbutton) self.panel.Bind(wx.EVT_MOUSE_EVENTS, self.editbutton)
self.Bind(wx.EVT_CLOSE, self.kill) self.Bind(wx.EVT_CLOSE, self.kill)
...@@ -464,5 +488,4 @@ class MainWindow(wx.Frame): ...@@ -464,5 +488,4 @@ class MainWindow(wx.Frame):
for i in self.printerControls: for i in self.printerControls:
i.Disable() i.Disable()
#self.panel.Fit() self.cbuttons_reload()
self.cbuttons_panel = self.panel
...@@ -120,8 +120,7 @@ class MacroEditor(wx.Dialog): ...@@ -120,8 +120,7 @@ class MacroEditor(wx.Dialog):
reindented += self.indent_chars + line + "\n" reindented += self.indent_chars + line + "\n"
return reindented return reindented
SETTINGS_GROUPS = {"General": _("General"), SETTINGS_GROUPS = {"Printer": _("Printer settings"),
"Printer": _("Printer settings"),
"UI": _("User interface"), "UI": _("User interface"),
"External": _("External commands")} "External": _("External commands")}
...@@ -136,7 +135,7 @@ class PronterOptionsDialog(wx.Dialog): ...@@ -136,7 +135,7 @@ class PronterOptionsDialog(wx.Dialog):
all_settings = pronterface.settings._all_settings() all_settings = pronterface.settings._all_settings()
group_list = [] group_list = []
groups = {} groups = {}
for group in ["General", "UI", "Printer"]: for group in ["Printer", "UI", "External"]:
group_list.append(group) group_list.append(group)
groups[group] = [] groups[group] = []
for setting in all_settings: for setting in all_settings:
...@@ -153,8 +152,13 @@ class PronterOptionsDialog(wx.Dialog): ...@@ -153,8 +152,13 @@ class PronterOptionsDialog(wx.Dialog):
grid.AddGrowableCol(1) grid.AddGrowableCol(1)
grid.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_SPECIFIED) grid.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_SPECIFIED)
for setting in settings: for setting in settings:
grid.Add(setting.get_label(grouppanel), 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL|wx.ALIGN_RIGHT) label,widget = setting.get_label(grouppanel),setting.get_widget(grouppanel)
grid.Add(setting.get_widget(grouppanel), 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL|wx.EXPAND) grid.Add(label, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL|wx.ALIGN_RIGHT)
grid.Add(widget, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL|wx.EXPAND)
if hasattr(label,"set_default"):
label.Bind(wx.EVT_MOUSE_EVENTS, label.set_default)
if hasattr(widget,"Bind"):
widget.Bind(wx.EVT_MOUSE_EVENTS, label.set_default)
grouppanel.SetSizer(grid) grouppanel.SetSizer(grid)
sbox.Add(notebook, 1, wx.EXPAND) sbox.Add(notebook, 1, wx.EXPAND)
panel.SetSizer(sbox) panel.SetSizer(sbox)
......
#!/usr/bin/python #!/usr/bin/env python
# This file is part of the Printrun suite. # This file is part of the Printrun suite.
# #
......
...@@ -60,14 +60,28 @@ def setting_add_tooltip(func): ...@@ -60,14 +60,28 @@ def setting_add_tooltip(func):
@wraps(func) @wraps(func)
def decorator(self, *args, **kwargs): def decorator(self, *args, **kwargs):
widget = func(self, *args, **kwargs) widget = func(self, *args, **kwargs)
if self.help: helptxt = self.help or ""
widget.SetToolTipString(self.help) sep,deftxt = "",""
if len(helptxt):
sep = "\n"
if helptxt.find("\n") >= 0:
sep = "\n\n"
if self.default is not "":
deftxt = _("Default: ")
resethelp = _("(Control-doubleclick to reset to default value)")
if len(repr(self.default)) > 10:
deftxt += "\n " + repr(self.default).strip("'") + "\n" + resethelp
else:
deftxt += repr(self.default) + " " + resethelp
helptxt += sep + deftxt
if len(helptxt):
widget.SetToolTipString(helptxt)
return widget return widget
return decorator return decorator
class Setting(object): class Setting(object):
DEFAULT_GROUP = "General" DEFAULT_GROUP = "Printer"
hidden = False hidden = False
...@@ -85,10 +99,20 @@ class Setting(object): ...@@ -85,10 +99,20 @@ class Setting(object):
raise NotImplementedError raise NotImplementedError
value = property(_get_value, _set_value) value = property(_get_value, _set_value)
def set_default(self, e):
import wx
if e.CmdDown() and e.ButtonDClick() and self.default is not "":
confirmation = wx.MessageDialog(None,_("Are you sure you want to reset the setting to the default value: {0!r} ?").format(self.default),_("Confirm set default"),wx.ICON_EXCLAMATION|wx.YES_NO|wx.NO_DEFAULT)
if confirmation.ShowModal() == wx.ID_YES:
self._set_value(self.default)
else:
e.Skip()
@setting_add_tooltip @setting_add_tooltip
def get_label(self, parent): def get_label(self, parent):
import wx import wx
widget = wx.StaticText(parent, -1, self.label or self.name) widget = wx.StaticText(parent, -1, self.label or self.name)
widget.set_default = self.set_default
return widget return widget
@setting_add_tooltip @setting_add_tooltip
...@@ -98,12 +122,6 @@ class Setting(object): ...@@ -98,12 +122,6 @@ class Setting(object):
def get_specific_widget(self, parent): def get_specific_widget(self, parent):
raise NotImplementedError raise NotImplementedError
def set(self, value):
raise NotImplementedError
def get(self):
raise NotImplementedError
def update(self): def update(self):
raise NotImplementedError raise NotImplementedError
...@@ -178,6 +196,9 @@ class BooleanSetting(wxSetting): ...@@ -178,6 +196,9 @@ class BooleanSetting(wxSetting):
return bool(self._value) return bool(self._value)
def _set_value(self, value): def _set_value(self, value):
self._value = value self._value = value
if self.widget:
self.widget.SetValue(bool(value))
value = property(_get_value, _set_value) value = property(_get_value, _set_value)
def get_specific_widget(self, parent): def get_specific_widget(self, parent):
...@@ -186,6 +207,23 @@ class BooleanSetting(wxSetting): ...@@ -186,6 +207,23 @@ class BooleanSetting(wxSetting):
self.widget.SetValue(bool(self.value)) self.widget.SetValue(bool(self.value))
return self.widget return self.widget
class StaticTextSetting(wxSetting):
def __init__(self, name, label = " ", text = "", help = None, group = None):
super(StaticTextSetting, self).__init__(name, "", label, help, group)
self.text = text
def update(self):
pass
def _get_value(self):
return ""
def _set_value(self, value):
pass
def get_specific_widget(self, parent):
import wx
self.widget = wx.StaticText(parent, -1, self.text)
return self.widget
class Settings(object): class Settings(object):
#def _temperature_alias(self): return {"pla":210, "abs":230, "off":0} #def _temperature_alias(self): return {"pla":210, "abs":230, "off":0}
#def _temperature_validate(self, v): #def _temperature_validate(self, v):
...@@ -196,16 +234,16 @@ class Settings(object): ...@@ -196,16 +234,16 @@ class Settings(object):
# defaults here. # defaults here.
# the initial value determines the type # the initial value determines the type
self._add(StringSetting("port", "", _("Serial port"), _("Port used to communicate with printer"))) self._add(StringSetting("port", "", _("Serial port"), _("Port used to communicate with printer")))
self._add(ComboSetting("baudrate", 115200, self._baudrate_list(), _("Baud rate"), _("Communications Speed (default: 115200)"))) self._add(ComboSetting("baudrate", 115200, self._baudrate_list(), _("Baud rate"), _("Communications Speed")))
self._add(SpinSetting("bedtemp_abs", 110, 0, 400, _("Bed temperature for ABS"), _("Heated Build Platform temp for ABS (default: 110 deg C)"), "Printer")) self._add(SpinSetting("bedtemp_abs", 110, 0, 400, _("Bed temperature for ABS"), _("Heated Build Platform temp for ABS (deg C)"), "Printer"))
self._add(SpinSetting("bedtemp_pla", 60, 0, 400, _("Bed temperature for PLA"), _("Heated Build Platform temp for PLA (default: 60 deg C)"), "Printer")) self._add(SpinSetting("bedtemp_pla", 60, 0, 400, _("Bed temperature for PLA"), _("Heated Build Platform temp for PLA (deg C)"), "Printer"))
self._add(SpinSetting("temperature_abs", 230, 0, 400, _("Extruder temperature for ABS"), _("Extruder temp for ABS (default: 230 deg C)"), "Printer")) self._add(SpinSetting("temperature_abs", 230, 0, 400, _("Extruder temperature for ABS"), _("Extruder temp for ABS (deg C)"), "Printer"))
self._add(SpinSetting("temperature_pla", 185, 0, 400, _("Extruder temperature for PLA"), _("Extruder temp for PLA (default: 185 deg C)"), "Printer")) self._add(SpinSetting("temperature_pla", 185, 0, 400, _("Extruder temperature for PLA"), _("Extruder temp for PLA (deg C)"), "Printer"))
self._add(SpinSetting("xy_feedrate", 3000, 0, 50000, _("X && Y manual feedrate"), _("Feedrate for Control Panel Moves in X and Y (default: 3000mm/min)"), "Printer")) self._add(SpinSetting("xy_feedrate", 3000, 0, 50000, _("X && Y manual feedrate"), _("Feedrate for Control Panel Moves in X and Y (mm/min)"), "Printer"))
self._add(SpinSetting("z_feedrate", 200, 0, 50000, _("Z manual feedrate"), _("Feedrate for Control Panel Moves in Z (default: 200mm/min)"), "Printer")) self._add(SpinSetting("z_feedrate", 200, 0, 50000, _("Z manual feedrate"), _("Feedrate for Control Panel Moves in Z (mm/min)"), "Printer"))
self._add(SpinSetting("e_feedrate", 100, 0, 1000, _("E manual feedrate"), _("Feedrate for Control Panel Moves in Extrusions (default: 300mm/min)"), "Printer")) self._add(SpinSetting("e_feedrate", 100, 0, 1000, _("E manual feedrate"), _("Feedrate for Control Panel Moves in Extrusions (mm/min)"), "Printer"))
self._add(StringSetting("slicecommand", "python skeinforge/skeinforge_application/skeinforge_utilities/skeinforge_craft.py $s", _("Slice command"), _("Slice command\n default:\n python skeinforge/skeinforge_application/skeinforge_utilities/skeinforge_craft.py $s)"), "External")) self._add(StringSetting("slicecommand", "python skeinforge/skeinforge_application/skeinforge_utilities/skeinforge_craft.py $s", _("Slice command"), _("Slice command"), "External"))
self._add(StringSetting("sliceoptscommand", "python skeinforge/skeinforge_application/skeinforge.py", _("Slicer options command"), _("Slice settings command\n default:\n python skeinforge/skeinforge_application/skeinforge.py"), "External")) self._add(StringSetting("sliceoptscommand", "python skeinforge/skeinforge_application/skeinforge.py", _("Slicer options command"), _("Slice settings command"), "External"))
self._add(StringSetting("final_command", "", _("Final command"), _("Executable to run when the print is finished"), "External")) self._add(StringSetting("final_command", "", _("Final command"), _("Executable to run when the print is finished"), "External"))
self._add(HiddenSetting("project_offset_x", 0.0)) self._add(HiddenSetting("project_offset_x", 0.0))
...@@ -241,8 +279,10 @@ class Settings(object): ...@@ -241,8 +279,10 @@ class Settings(object):
return object.__getattribute__(self, name) return object.__getattribute__(self, name)
return getattr(self, "_" + name).value return getattr(self, "_" + name).value
def _add(self, setting): def _add(self, setting, callback = None):
setattr(self, setting.name, setting) setattr(self, setting.name, setting)
if callback:
setattr(self, "_" + setting.name + "_cb", callback)
def _set(self, key, value): def _set(self, key, value):
try: try:
...@@ -479,6 +519,9 @@ class pronsole(cmd.Cmd): ...@@ -479,6 +519,9 @@ class pronsole(cmd.Cmd):
self.log("Empty macro - cancelled") self.log("Empty macro - cancelled")
del self.cur_macro_name, self.cur_macro_def del self.cur_macro_name, self.cur_macro_def
def parseusercmd(self, line):
pass
def compile_macro_line(self, line): def compile_macro_line(self, line):
line = line.rstrip() line = line.rstrip()
ls = line.lstrip() ls = line.lstrip()
...@@ -487,7 +530,8 @@ class pronsole(cmd.Cmd): ...@@ -487,7 +530,8 @@ class pronsole(cmd.Cmd):
if ls.startswith('!'): if ls.startswith('!'):
return ws + ls[1:] + "\n" # python mode return ws + ls[1:] + "\n" # python mode
else: else:
return ws + 'self.onecmd("'+ls+'".format(*arg))\n' # parametric command mode ret = ws + 'self.parseusercmd("'+ls+'".format(*arg))\n' # parametric command mode
return ret + ws + 'self.onecmd("'+ls+'".format(*arg))\n'
def compile_macro(self, macro_name, macro_def): def compile_macro(self, macro_name, macro_def):
if macro_def.strip() == "": if macro_def.strip() == "":
...@@ -1157,7 +1201,7 @@ class pronsole(cmd.Cmd): ...@@ -1157,7 +1201,7 @@ class pronsole(cmd.Cmd):
self.log("Printer is not online. Unable to extrude.") self.log("Printer is not online. Unable to extrude.")
return return
if self.p.printing: if self.p.printing:
self.log("Printer is currently printing. Please pause the print before you issue manual commands.") self.log(_("Printer is currently printing. Please pause the print before you issue manual commands."))
return return
ls = l.split() ls = l.split()
if len(ls): if len(ls):
......
...@@ -46,7 +46,7 @@ import printcore ...@@ -46,7 +46,7 @@ import printcore
from printrun.printrun_utils import pixmapfile, configfile from printrun.printrun_utils import pixmapfile, configfile
from printrun.gui import MainWindow from printrun.gui import MainWindow
import pronsole import pronsole
from pronsole import dosify, wxSetting, HiddenSetting, StringSetting, SpinSetting, FloatSpinSetting, BooleanSetting from pronsole import dosify, wxSetting, HiddenSetting, StringSetting, SpinSetting, FloatSpinSetting, BooleanSetting, StaticTextSetting
from printrun import gcoder from printrun import gcoder
tempreport_exp = re.compile("([TB]\d*):([-+]?\d*\.?\d*)(?: \/)?([-+]?\d*\.?\d*)") tempreport_exp = re.compile("([TB]\d*):([-+]?\d*\.?\d*)(?: \/)?([-+]?\d*\.?\d*)")
...@@ -182,17 +182,19 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -182,17 +182,19 @@ class PronterWindow(MainWindow, pronsole.pronsole):
monitorsetting.hidden = True monitorsetting.hidden = True
self.settings._add(monitorsetting) self.settings._add(monitorsetting)
self.settings._add(BuildDimensionsSetting("build_dimensions", "200x200x100+0+0+0+0+0+0", _("Build dimensions"), _("Dimensions of Build Platform\n & optional offset of origin\n & optional switch position\n\nExamples:\n XXXxYYY\n XXX,YYY,ZZZ\n XXXxYYYxZZZ+OffX+OffY+OffZ\nXXXxYYYxZZZ+OffX+OffY+OffZ+HomeX+HomeY+HomeZ"), "Printer")) self.settings._add(BuildDimensionsSetting("build_dimensions", "200x200x100+0+0+0+0+0+0", _("Build dimensions"), _("Dimensions of Build Platform\n & optional offset of origin\n & optional switch position\n\nExamples:\n XXXxYYY\n XXX,YYY,ZZZ\n XXXxYYYxZZZ+OffX+OffY+OffZ\nXXXxYYYxZZZ+OffX+OffY+OffZ+HomeX+HomeY+HomeZ"), "Printer"))
self.settings._add(StringSetting("bgcolor", "#FFFFFF", _("Background color"), _("Pronterface background color (default: #FFFFFF)"), "UI")) self.settings._add(StringSetting("bgcolor", "#FFFFFF", _("Background color"), _("Pronterface background color"), "UI"))
self.settings._add(BooleanSetting("tabbed", False, _("Use tabbed interface"), _("Use tabbed interface instead of the single window one"), "UI")) self.settings._add(ComboSetting("uimode", "Standard", ["Standard", "Compact", "Tabbed"], _("Interface mode"), _("Standard interface is a one-page, three columns layout with controls/visualization/log\nCompact mode is a one-page, two columns layout with controls + log/visualization\nTabbed mode is a two-pages mode, where the first page shows controls and the second one shows visualization and log."), "UI"))
self.settings._add(BooleanSetting("viz3d", False, _("Enable 3D viewer (requires restarting)"), _("Use 3D visualization instead of 2D layered visualization"), "UI")) self.settings._add(BooleanSetting("viz3d", False, _("Enable 3D viewer"), _("Use 3D visualization instead of 2D layered visualization"), "UI"))
self.settings._add(ComboSetting("mainviz", "2D", ["2D", "3D", "None"], _("Main visualization"), _("Select visualization for main window."), "UI")) self.settings._add(ComboSetting("mainviz", "2D", ["2D", "3D", "None"], _("Main visualization"), _("Select visualization for main window."), "UI"))
self.settings._add(BooleanSetting("tempgraph", True, _("Display temperature graph"), _("Display time-lapse temperature graph"), "UI"))
self.settings._add(BooleanSetting("tempgauges", False, _("Display temperature gauges"), _("Display graphical gauges for temperatures visualization"), "UI")) self.settings._add(BooleanSetting("tempgauges", False, _("Display temperature gauges"), _("Display graphical gauges for temperatures visualization"), "UI"))
self.settings._add(HiddenSetting("last_bed_temperature", 0.0)) self.settings._add(HiddenSetting("last_bed_temperature", 0.0))
self.settings._add(HiddenSetting("last_file_path", "")) self.settings._add(HiddenSetting("last_file_path", ""))
self.settings._add(HiddenSetting("last_temperature", 0.0)) self.settings._add(HiddenSetting("last_temperature", 0.0))
self.settings._add(FloatSpinSetting("preview_extrusion_width", 0.5, 0, 10, _("Preview extrusion width"), _("Width of Extrusion in Preview (default: 0.5)"), "UI")) self.settings._add(FloatSpinSetting("preview_extrusion_width", 0.5, 0, 10, _("Preview extrusion width"), _("Width of Extrusion in Preview"), "UI"), self.update_gviz_params)
self.settings._add(SpinSetting("preview_grid_step1", 10., 0, 200, _("Fine grid spacing"), _("Fine Grid Spacing (default: 10)"), "UI")) self.settings._add(SpinSetting("preview_grid_step1", 10., 0, 200, _("Fine grid spacing"), _("Fine Grid Spacing"), "UI"), self.update_gviz_params)
self.settings._add(SpinSetting("preview_grid_step2", 50., 0, 200, _("Coarse grid spacing"), _("Coarse Grid Spacing (default: 50)"), "UI")) self.settings._add(SpinSetting("preview_grid_step2", 50., 0, 200, _("Coarse grid spacing"), _("Coarse Grid Spacing"), "UI"), self.update_gviz_params)
self.settings._add(StaticTextSetting("note1", _("Note:"), _("Changing most settings here will require restart to get effect"), group = "UI"))
self.pauseScript = "pause.gcode" self.pauseScript = "pause.gcode"
self.endScript = "end.gcode" self.endScript = "end.gcode"
...@@ -211,6 +213,8 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -211,6 +213,8 @@ class PronterWindow(MainWindow, pronsole.pronsole):
self.capture_skip = {} self.capture_skip = {}
self.capture_skip_newline = False self.capture_skip_newline = False
self.tempreport = "" self.tempreport = ""
self.userm114 = 0
self.userm105 = 0
self.monitor = 0 self.monitor = 0
self.fgcode = None self.fgcode = None
self.skeinp = None self.skeinp = None
...@@ -229,6 +233,7 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -229,6 +233,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
self.autoconnect = False self.autoconnect = False
self.parse_cmdline(sys.argv[1:]) self.parse_cmdline(sys.argv[1:])
self.build_dimensions_list = parse_build_dimensions(self.settings.build_dimensions) self.build_dimensions_list = parse_build_dimensions(self.settings.build_dimensions)
self.display_graph = self.settings.tempgraph
self.display_gauges = self.settings.tempgauges self.display_gauges = self.settings.tempgauges
#initialize the code analyzer with the correct sizes. There must be a more general way to do so #initialize the code analyzer with the correct sizes. There must be a more general way to do so
...@@ -277,10 +282,10 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -277,10 +282,10 @@ class PronterWindow(MainWindow, pronsole.pronsole):
except: except:
pass pass
self.popmenu() self.popmenu()
if self.settings.tabbed: if self.settings.uimode == "Tabbed":
self.createTabbedGui() self.createTabbedGui()
else: else:
self.createGui() self.createGui(self.settings.uimode == "Compact")
self.t = Tee(self.catchprint) self.t = Tee(self.catchprint)
self.stdout = sys.stdout self.stdout = sys.stdout
self.skeining = 0 self.skeining = 0
...@@ -315,10 +320,13 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -315,10 +320,13 @@ class PronterWindow(MainWindow, pronsole.pronsole):
pronsole.pronsole.process_cmdline_arguments(self, args) pronsole.pronsole.process_cmdline_arguments(self, args)
self.autoconnect = args.autoconnect self.autoconnect = args.autoconnect
def startcb(self): def startcb(self, resuming = False):
self.starttime = time.time() self.starttime = time.time()
self.compute_eta = RemainingTimeEstimator(self.p.mainqueue) if resuming:
print _("Print Started at: %s") % format_time(self.starttime) print _("Print resumed at: %s") % format_time(self.starttime)
else:
print _("Print started at: %s") % format_time(self.starttime)
self.compute_eta = RemainingTimeEstimator(self.fgcode)
def endcb(self): def endcb(self):
if self.p.queueindex == 0: if self.p.queueindex == 0:
...@@ -372,13 +380,13 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -372,13 +380,13 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if gline.s != None: if gline.s != None:
temp = gline.s temp = gline.s
if self.display_gauges: wx.CallAfter(self.hottgauge.SetTarget, temp) if self.display_gauges: wx.CallAfter(self.hottgauge.SetTarget, temp)
wx.CallAfter(self.graph.SetExtruder0TargetTemperature, temp) if self.display_graph: wx.CallAfter(self.graph.SetExtruder0TargetTemperature, temp)
elif gline.command == "M140": elif gline.command == "M140":
gline.parse_coordinates(imperial = False, force = True) gline.parse_coordinates(imperial = False, force = True)
if gline.s != None: if gline.s != None:
temp = gline.s temp = gline.s
if self.display_gauges: wx.CallAfter(self.bedtgauge.SetTarget, temp) if self.display_gauges: wx.CallAfter(self.bedtgauge.SetTarget, temp)
wx.CallAfter(self.graph.SetBedTargetTemperature, temp) if self.display_graph: wx.CallAfter(self.graph.SetBedTargetTemperature, temp)
else: else:
return return
self.sentlines.put_nowait(line) self.sentlines.put_nowait(line)
...@@ -408,7 +416,7 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -408,7 +416,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def setbedgui(self, f): def setbedgui(self, f):
self.bsetpoint = f self.bsetpoint = f
if self.display_gauges: self.bedtgauge.SetTarget(int(f)) if self.display_gauges: self.bedtgauge.SetTarget(int(f))
wx.CallAfter(self.graph.SetBedTargetTemperature, int(f)) if self.display_graph: wx.CallAfter(self.graph.SetBedTargetTemperature, int(f))
if f>0: if f>0:
wx.CallAfter(self.btemp.SetValue, str(f)) wx.CallAfter(self.btemp.SetValue, str(f))
self.set("last_bed_temperature", str(f)) self.set("last_bed_temperature", str(f))
...@@ -428,7 +436,7 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -428,7 +436,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def sethotendgui(self, f): def sethotendgui(self, f):
self.hsetpoint = f self.hsetpoint = f
if self.display_gauges: self.hottgauge.SetTarget(int(f)) if self.display_gauges: self.hottgauge.SetTarget(int(f))
wx.CallAfter(self.graph.SetExtruder0TargetTemperature, int(f)) if self.display_graph: wx.CallAfter(self.graph.SetExtruder0TargetTemperature, int(f))
if f > 0: if f > 0:
wx.CallAfter(self.htemp.SetValue, str(f)) wx.CallAfter(self.htemp.SetValue, str(f))
self.set("last_temperature", str(f)) self.set("last_temperature", str(f))
...@@ -628,7 +636,7 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -628,7 +636,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
try: try:
while True: while True:
item = self.macros_menu.FindItemByPosition(1) item = self.macros_menu.FindItemByPosition(1)
if item is None: return if item is None: break
self.macros_menu.DeleteItem(item) self.macros_menu.DeleteItem(item)
except: except:
pass pass
...@@ -707,6 +715,37 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -707,6 +715,37 @@ class PronterWindow(MainWindow, pronsole.pronsole):
self.gwindow.SetToolTip(wx.ToolTip("Mousewheel zooms the display\nShift / Mousewheel scrolls layers")) self.gwindow.SetToolTip(wx.ToolTip("Mousewheel zooms the display\nShift / Mousewheel scrolls layers"))
self.gwindow.Raise() self.gwindow.Raise()
def update_gviz_params(self, param, value):
params_map = {"preview_extrusion_width": "extrusion_width",
"preview_grid_step1": "grid",
"preview_grid_step2": "grid",}
if param not in params_map:
return
trueparam = params_map[param]
if hasattr(self.gviz, trueparam):
gviz = self.gviz
elif hasattr(self.gwindow, "p") and hasattr(self.gwindow.p, trueparam):
gviz = self.gwindow.p
else:
return
if trueparam == "grid":
try:
item = int(param[-1]) # extract list item position
grid = list(gviz.grid)
grid[item - 1] = value
value = tuple(grid)
except:
traceback.print_exc()
if hasattr(self.gviz, trueparam):
self.apply_gviz_params(self.gviz, trueparam, value)
if hasattr(self.gwindow, "p") and hasattr(self.gwindow.p, trueparam):
self.apply_gviz_params(self.gwindow.p, trueparam, value)
def apply_gviz_params(self, widget, param, value):
setattr(widget, param, value)
widget.dirty = 1
wx.CallAfter(widget.Refresh)
def setfeeds(self, e): def setfeeds(self, e):
self.feedrates_changed = True self.feedrates_changed = True
try: try:
...@@ -723,28 +762,15 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -723,28 +762,15 @@ class PronterWindow(MainWindow, pronsole.pronsole):
pass pass
def cbuttons_reload(self): def cbuttons_reload(self):
allcbs = [] allcbs = getattr(self, "custombuttonbuttons", [])
ubs = self.uppersizer for button in allcbs:
cs = self.centersizer self.centersizer.Detach(button)
#for item in ubs.GetChildren():
# if hasattr(item.GetWindow(),"custombutton"):
# allcbs += [(ubs, item.GetWindow())]
for item in cs.GetChildren():
if hasattr(item.GetWindow(),"custombutton"):
allcbs += [(cs, item.GetWindow())]
for sizer, button in allcbs:
#sizer.Remove(button)
button.Destroy() button.Destroy()
self.custombuttonbuttons = [] self.custombuttonbuttons = []
newbuttonbuttonindex = len(self.custombuttons) custombuttons = self.custombuttons[:] + [None]
while newbuttonbuttonindex>0 and self.custombuttons[newbuttonbuttonindex-1] is None: for i, btndef in enumerate(custombuttons):
newbuttonbuttonindex -= 1
while len(self.custombuttons) < 13:
self.custombuttons.append(None)
for i in xrange(len(self.custombuttons)):
btndef = self.custombuttons[i]
try: try:
b = wx.Button(self.cbuttons_panel, -1, btndef.label, style = wx.BU_EXACTFIT) b = wx.Button(self.centerpanel, -1, btndef.label, style = wx.BU_EXACTFIT)
b.SetToolTip(wx.ToolTip(_("Execute command: ")+btndef.command)) b.SetToolTip(wx.ToolTip(_("Execute command: ")+btndef.command))
if btndef.background: if btndef.background:
b.SetBackgroundColour(btndef.background) b.SetBackgroundColour(btndef.background)
...@@ -752,14 +778,14 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -752,14 +778,14 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if 0.3*rr+0.59*gg+0.11*bb < 60: if 0.3*rr+0.59*gg+0.11*bb < 60:
b.SetForegroundColour("#ffffff") b.SetForegroundColour("#ffffff")
except: except:
if i == newbuttonbuttonindex: if i == len(custombuttons) - 1:
self.newbuttonbutton = b = wx.Button(self.cbuttons_panel, -1, "+", size = (19, 18), style = wx.BU_EXACTFIT) self.newbuttonbutton = b = wx.Button(self.centerpanel, -1, "+", size = (19, 18), style = wx.BU_EXACTFIT)
#b.SetFont(wx.Font(12, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD)) #b.SetFont(wx.Font(12, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD))
b.SetForegroundColour("#4444ff") b.SetForegroundColour("#4444ff")
b.SetToolTip(wx.ToolTip(_("click to add new custom button"))) b.SetToolTip(wx.ToolTip(_("click to add new custom button")))
b.Bind(wx.EVT_BUTTON, self.cbutton_edit) b.Bind(wx.EVT_BUTTON, self.cbutton_edit)
else: else:
b = wx.Button(self.cbuttons_panel,-1, ".", size = (1, 1)) b = wx.Button(self.centerpanel,-1, ".", size = (1, 1))
#b = wx.StaticText(self.panel,-1, "", size = (72, 22), style = wx.ALIGN_CENTRE+wx.ST_NO_AUTORESIZE) #+wx.SIMPLE_BORDER #b = wx.StaticText(self.panel,-1, "", size = (72, 22), style = wx.ALIGN_CENTRE+wx.ST_NO_AUTORESIZE) #+wx.SIMPLE_BORDER
b.Disable() b.Disable()
#continue #continue
...@@ -768,14 +794,9 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -768,14 +794,9 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if btndef is not None: if btndef is not None:
b.Bind(wx.EVT_BUTTON, self.procbutton) b.Bind(wx.EVT_BUTTON, self.procbutton)
b.Bind(wx.EVT_MOUSE_EVENTS, self.editbutton) b.Bind(wx.EVT_MOUSE_EVENTS, self.editbutton)
#else:
# b.Bind(wx.EVT_BUTTON, lambda e:e.Skip())
self.custombuttonbuttons.append(b) self.custombuttonbuttons.append(b)
#if i<4: self.centersizer.Add(b, pos = (i // 4, i % 4))
# ubs.Add(b) self.panel.GetSizer().Layout()
#else:
cs.Add(b, pos = ((i)/4, (i)%4))
self.mainsizer.Layout()
def help_button(self): def help_button(self):
print _('Defines custom button. Usage: button <num> "title" [/c "colour"] command') print _('Defines custom button. Usage: button <num> "title" [/c "colour"] command')
...@@ -1063,13 +1084,21 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -1063,13 +1084,21 @@ class PronterWindow(MainWindow, pronsole.pronsole):
self.zb.repeatLast() self.zb.repeatLast()
self.xyb.repeatLast() self.xyb.repeatLast()
def parseusercmd(self, line):
if line.startswith("M114"):
self.userm114 += 1
elif line.startswith("M105"):
self.userm105 += 1
def procbutton(self, e): def procbutton(self, e):
try: try:
if hasattr(e.GetEventObject(),"custombutton"): if hasattr(e.GetEventObject(),"custombutton"):
if wx.GetKeyState(wx.WXK_CONTROL) or wx.GetKeyState(wx.WXK_ALT): if wx.GetKeyState(wx.WXK_CONTROL) or wx.GetKeyState(wx.WXK_ALT):
return self.editbutton(e) return self.editbutton(e)
self.cur_button = e.GetEventObject().custombutton self.cur_button = e.GetEventObject().custombutton
self.onecmd(e.GetEventObject().properties.command) command = e.GetEventObject().properties.command
self.parseusercmd(command)
self.onecmd(command)
self.cur_button = None self.cur_button = None
except: except:
print _("event object missing") print _("event object missing")
...@@ -1110,6 +1139,7 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -1110,6 +1139,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def setmonitor(self, e): def setmonitor(self, e):
self.monitor = self.monitorbox.GetValue() self.monitor = self.monitorbox.GetValue()
self.set("monitor", self.monitor) self.set("monitor", self.monitor)
if self.display_graph:
if self.monitor: if self.monitor:
wx.CallAfter(self.graph.StartPlotting, 1000) wx.CallAfter(self.graph.StartPlotting, 1000)
else: else:
...@@ -1129,6 +1159,7 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -1129,6 +1159,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if not len(command): if not len(command):
return return
wx.CallAfter(self.addtexttolog, ">>>" + command + "\n"); wx.CallAfter(self.addtexttolog, ">>>" + command + "\n");
self.parseusercmd(str(command))
self.onecmd(str(command)) self.onecmd(str(command))
self.commandbox.SetSelection(0, len(command)) self.commandbox.SetSelection(0, len(command))
self.commandbox.history.append(command) self.commandbox.history.append(command)
...@@ -1145,13 +1176,13 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -1145,13 +1176,13 @@ class PronterWindow(MainWindow, pronsole.pronsole):
hotend_temp = float(temps["T0"][0]) hotend_temp = float(temps["T0"][0])
else: else:
hotend_temp = float(temps["T"][0]) if "T" in temps else -1.0 hotend_temp = float(temps["T"][0]) if "T" in temps else -1.0
wx.CallAfter(self.graph.SetExtruder0Temperature, hotend_temp) if self.display_graph: wx.CallAfter(self.graph.SetExtruder0Temperature, hotend_temp)
if self.display_gauges: wx.CallAfter(self.hottgauge.SetValue, hotend_temp) if self.display_gauges: wx.CallAfter(self.hottgauge.SetValue, hotend_temp)
if "T1" in temps: if "T1" in temps:
hotend_temp = float(temps["T1"][0]) hotend_temp = float(temps["T1"][0])
wx.CallAfter(self.graph.SetExtruder1Temperature, hotend_temp) if self.display_graph: wx.CallAfter(self.graph.SetExtruder1Temperature, hotend_temp)
bed_temp = float(temps["B"][0]) if "B" in temps else -1.0 bed_temp = float(temps["B"][0]) if "B" in temps else -1.0
wx.CallAfter(self.graph.SetBedTemperature, bed_temp) if self.display_graph: wx.CallAfter(self.graph.SetBedTemperature, bed_temp)
if self.display_gauges: wx.CallAfter(self.bedtgauge.SetValue, bed_temp) if self.display_gauges: wx.CallAfter(self.bedtgauge.SetValue, bed_temp)
except: except:
traceback.print_exc() traceback.print_exc()
...@@ -1196,8 +1227,14 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -1196,8 +1227,14 @@ class PronterWindow(MainWindow, pronsole.pronsole):
string += _(" Est: %s of %s remaining | ") % (format_duration(secondsremain), string += _(" Est: %s of %s remaining | ") % (format_duration(secondsremain),
format_duration(secondsestimate)) format_duration(secondsestimate))
string += _(" Z: %.3f mm") % self.curlayer string += _(" Z: %.3f mm") % self.curlayer
wx.CallAfter(self.status.SetStatusText, string) wx.CallAfter(self.statusbar.SetStatusText, string)
wx.CallAfter(self.gviz.Refresh) wx.CallAfter(self.gviz.Refresh)
if self.p.online:
if self.p.writefailures >= 4:
print _("Disconnecting after 4 failed writes.")
self.status_thread = None
self.disconnect()
return
if self.monitor and self.p.online: if self.monitor and self.p.online:
if self.sdprinting: if self.sdprinting:
self.p.send_now("M27") self.p.send_now("M27")
...@@ -1210,10 +1247,14 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -1210,10 +1247,14 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if not self.statuscheck: if not self.statuscheck:
break break
time.sleep(0.25) time.sleep(0.25)
try:
while not self.sentlines.empty(): while not self.sentlines.empty():
gc = self.sentlines.get_nowait() gc = self.sentlines.get_nowait()
wx.CallAfter(self.gviz.addgcode, gc, 1) wx.CallAfter(self.gviz.addgcode, gc, 1)
wx.CallAfter(self.status.SetStatusText, _("Not connected to printer.")) self.sentlines.task_done()
except Queue.Empty:
pass
wx.CallAfter(self.statusbar.SetStatusText, _("Not connected to printer."))
def capture(self, func, *args, **kwargs): def capture(self, func, *args, **kwargs):
stdout = sys.stdout stdout = sys.stdout
...@@ -1239,11 +1280,17 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -1239,11 +1280,17 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if "ok C:" in l or "Count" in l: if "ok C:" in l or "Count" in l:
self.posreport = l self.posreport = l
self.update_pos(l) self.update_pos(l)
if self.userm114 > 0:
self.userm114 -= 1
else:
isreport = True isreport = True
if "ok T:" in l: if "ok T:" in l:
self.tempreport = l self.tempreport = l
wx.CallAfter(self.tempdisp.SetLabel, self.tempreport.strip().replace("ok ", "")) wx.CallAfter(self.tempdisp.SetLabel, self.tempreport.strip().replace("ok ", ""))
self.update_tempdisplay() self.update_tempdisplay()
if self.userm105 > 0:
self.userm105 -= 1
else:
isreport = True isreport = True
tstring = l.rstrip() tstring = l.rstrip()
if self.p.loud or (tstring not in ["ok", "wait"] and not isreport): if self.p.loud or (tstring not in ["ok", "wait"] and not isreport):
...@@ -1263,19 +1310,19 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -1263,19 +1310,19 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def waitforsdresponse(self, l): def waitforsdresponse(self, l):
if "file.open failed" in l: if "file.open failed" in l:
wx.CallAfter(self.status.SetStatusText, _("Opening file failed.")) wx.CallAfter(self.statusbar.SetStatusText, _("Opening file failed."))
self.recvlisteners.remove(self.waitforsdresponse) self.recvlisteners.remove(self.waitforsdresponse)
return return
if "File opened" in l: if "File opened" in l:
wx.CallAfter(self.status.SetStatusText, l) wx.CallAfter(self.statusbar.SetStatusText, l)
if "File selected" in l: if "File selected" in l:
wx.CallAfter(self.status.SetStatusText, _("Starting print")) wx.CallAfter(self.statusbar.SetStatusText, _("Starting print"))
self.sdprinting = 1 self.sdprinting = 1
self.p.send_now("M24") self.p.send_now("M24")
self.startcb() self.startcb()
return return
if "Done printing file" in l: if "Done printing file" in l:
wx.CallAfter(self.status.SetStatusText, l) wx.CallAfter(self.statusbar.SetStatusText, l)
self.sdprinting = 0 self.sdprinting = 0
self.recvlisteners.remove(self.waitforsdresponse) self.recvlisteners.remove(self.waitforsdresponse)
self.endcb() self.endcb()
...@@ -1330,7 +1377,7 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -1330,7 +1377,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def skein_monitor(self): def skein_monitor(self):
while(not self.stopsf): while(not self.stopsf):
try: try:
wx.CallAfter(self.status.SetStatusText, _("Slicing..."))#+self.cout.getvalue().split("\n")[-1]) wx.CallAfter(self.statusbar.SetStatusText, _("Slicing..."))#+self.cout.getvalue().split("\n")[-1])
except: except:
pass pass
time.sleep(0.1) time.sleep(0.1)
...@@ -1341,7 +1388,7 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -1341,7 +1388,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if self.p.online: if self.p.online:
wx.CallAfter(self.printbtn.Enable) wx.CallAfter(self.printbtn.Enable)
wx.CallAfter(self.status.SetStatusText, _("Loaded %s, %d lines") % (self.filename, len(self.fgcode),)) wx.CallAfter(self.statusbar.SetStatusText, _("Loaded %s, %d lines") % (self.filename, len(self.fgcode),))
print _("Loaded %s, %d lines") % (self.filename, len(self.fgcode),) print _("Loaded %s, %d lines") % (self.filename, len(self.fgcode),)
wx.CallAfter(self.pausebtn.Disable) wx.CallAfter(self.pausebtn.Disable)
wx.CallAfter(self.printbtn.SetLabel, _("Print")) wx.CallAfter(self.printbtn.SetLabel, _("Print"))
...@@ -1391,7 +1438,7 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -1391,7 +1438,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
name = dlg.GetPath() name = dlg.GetPath()
dlg.Destroy() dlg.Destroy()
if not os.path.exists(name): if not os.path.exists(name):
self.status.SetStatusText(_("File not found!")) self.statusbar.SetStatusText(_("File not found!"))
return return
path = os.path.split(name)[0] path = os.path.split(name)[0]
if path != self.settings.last_file_path: if path != self.settings.last_file_path:
...@@ -1403,7 +1450,7 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -1403,7 +1450,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
else: else:
self.filename = name self.filename = name
self.fgcode = gcoder.GCode(open(self.filename)) self.fgcode = gcoder.GCode(open(self.filename))
self.status.SetStatusText(_("Loaded %s, %d lines") % (name, len(self.fgcode))) self.statusbar.SetStatusText(_("Loaded %s, %d lines") % (name, len(self.fgcode)))
print _("Loaded %s, %d lines") % (name, len(self.fgcode)) print _("Loaded %s, %d lines") % (name, len(self.fgcode))
wx.CallAfter(self.printbtn.SetLabel, _("Print")) wx.CallAfter(self.printbtn.SetLabel, _("Print"))
wx.CallAfter(self.pausebtn.SetLabel, _("Pause")) wx.CallAfter(self.pausebtn.SetLabel, _("Pause"))
...@@ -1435,17 +1482,17 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -1435,17 +1482,17 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if self.paused: if self.paused:
self.p.paused = 0 self.p.paused = 0
self.paused = 0 self.paused = 0
self.on_startprint()
if self.sdprinting: if self.sdprinting:
self.on_startprint()
self.p.send_now("M26 S0") self.p.send_now("M26 S0")
self.p.send_now("M24") self.p.send_now("M24")
return return
if not self.fgcode: if not self.fgcode:
wx.CallAfter(self.status.SetStatusText, _("No file loaded. Please use load first.")) wx.CallAfter(self.statusbar.SetStatusText, _("No file loaded. Please use load first."))
return return
if not self.p.online: if not self.p.online:
wx.CallAfter(self.status.SetStatusText, _("Not connected to printer.")) wx.CallAfter(self.statusbar.SetStatusText, _("Not connected to printer."))
return return
self.on_startprint() self.on_startprint()
self.p.startprint(self.fgcode) self.p.startprint(self.fgcode)
...@@ -1457,7 +1504,7 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -1457,7 +1504,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def endupload(self): def endupload(self):
self.p.send_now("M29 ") self.p.send_now("M29 ")
wx.CallAfter(self.status.SetStatusText, _("File upload complete")) wx.CallAfter(self.statusbar.SetStatusText, _("File upload complete"))
time.sleep(0.5) time.sleep(0.5)
self.p.clear = True self.p.clear = True
self.uploading = False self.uploading = False
...@@ -1484,8 +1531,8 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -1484,8 +1531,8 @@ class PronterWindow(MainWindow, pronsole.pronsole):
dlg.Destroy() dlg.Destroy()
def pause(self, event): def pause(self, event):
print _("Paused.")
if not self.paused: if not self.paused:
print _("Print paused at: %s") % format_time(time.time())
if self.sdprinting: if self.sdprinting:
self.p.send_now("M25") self.p.send_now("M25")
else: else:
...@@ -1499,6 +1546,7 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -1499,6 +1546,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
self.extra_print_time += int(time.time() - self.starttime) self.extra_print_time += int(time.time() - self.starttime)
wx.CallAfter(self.pausebtn.SetLabel, _("Resume")) wx.CallAfter(self.pausebtn.SetLabel, _("Resume"))
else: else:
print _("Resuming.")
self.paused = False self.paused = False
if self.sdprinting: if self.sdprinting:
self.p.send_now("M24") self.p.send_now("M24")
...@@ -1537,12 +1585,12 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -1537,12 +1585,12 @@ class PronterWindow(MainWindow, pronsole.pronsole):
except SerialException as e: except SerialException as e:
# Currently, there is no errno, but it should be there in the future # Currently, there is no errno, but it should be there in the future
if e.errno == 2: if e.errno == 2:
print _("Error: You are trying to connect to a non-exisiting port.") print _("Error: You are trying to connect to a non-existing port.")
elif e.errno == 8: elif e.errno == 8:
print _("Error: You don't have permission to open %s.") % port print _("Error: You don't have permission to open %s.") % port
print _("You might need to add yourself to the dialout group.") print _("You might need to add yourself to the dialout group.")
else: else:
print e traceback.print_exc()
# Kill the scope anyway # Kill the scope anyway
return return
self.statuscheck = True self.statuscheck = True
...@@ -1558,7 +1606,7 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -1558,7 +1606,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def recover(self, event): def recover(self, event):
self.extra_print_time = 0 self.extra_print_time = 0
if not self.p.online: if not self.p.online:
wx.CallAfter(self.status.SetStatusText, _("Not connected to printer.")) wx.CallAfter(self.statusbar.SetStatusText, _("Not connected to printer."))
return return
# Reset Z # Reset Z
self.p.send_now("G92 Z%f" % self.predisconnect_layer) self.p.send_now("G92 Z%f" % self.predisconnect_layer)
...@@ -1572,7 +1620,7 @@ class PronterWindow(MainWindow, pronsole.pronsole): ...@@ -1572,7 +1620,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
self.predisconnect_queueindex = self.p.queueindex self.predisconnect_queueindex = self.p.queueindex
self.predisconnect_layer = self.curlayer self.predisconnect_layer = self.curlayer
def disconnect(self, event): def disconnect(self, event = None):
print _("Disconnected.") print _("Disconnected.")
if self.p.printing or self.p.paused or self.paused: if self.p.printing or self.p.paused or self.paused:
self.store_predisconnect_state() self.store_predisconnect_state()
......
#!/usr/bin/env python2.7 #!/usr/bin/env python
import tornado.ioloop import tornado.ioloop
import tornado.web import tornado.web
......
...@@ -144,8 +144,8 @@ setup ( ...@@ -144,8 +144,8 @@ setup (
url = "http://github.com/kliment/Printrun/", url = "http://github.com/kliment/Printrun/",
license = "GPLv3", license = "GPLv3",
data_files = data_files, data_files = data_files,
packages = ["printrun", "printrun.svg"], packages = ["printrun", "printrun.cairosvg"],
scripts = ["pronsole.py", "pronterface.py", "plater.py", "printcore.py", "pronserve.py"], scripts = ["pronsole.py", "pronterface.py", "plater.py", "printcore.py", "prontserve.py"],
cmdclass = {"uninstall" : uninstall, cmdclass = {"uninstall" : uninstall,
"install" : install, "install" : install,
"install_data" : install_data} "install_data" : install_data}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment