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:
* numpy (for 3D view)
* pyreadline (not needed on Linux) and
* 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)
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 @@
from serial import Serial, SerialException
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 platform, os, traceback
import socket
import re
from functools import wraps
from collections import deque
from printrun.GCodeAnalyzer import GCodeAnalyzer
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):
"""Controls the HUPCL"""
if platform.system() == "Linux":
......@@ -52,7 +62,7 @@ class printcore():
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.mainqueue = None
self.priqueue = []
self.priqueue = Queue(0)
self.queueindex = 0
self.lineno = 0
self.resendfrom = -1
......@@ -60,6 +70,7 @@ class printcore():
self.sentlines = {}
self.log = deque(maxlen = 10000)
self.sent = []
self.writefailures = 0
self.tempcb = None #impl (wholeline)
self.recvcb = None #impl (wholeline)
self.sendcb = None #impl (wholeline)
......@@ -74,6 +85,8 @@ class printcore():
self.wait = 0 # default wait period for send(), send_now()
self.read_thread = None
self.stop_read_thread = False
self.send_thread = None
self.stop_send_thread = False
self.print_thread = None
if port is not None and baud is not None:
self.connect(port, baud)
......@@ -89,6 +102,7 @@ class printcore():
self.stop_read_thread = True
self.read_thread.join()
self.read_thread = None
self._stop_sender()
try:
self.printer.close()
except socket.error:
......@@ -97,6 +111,7 @@ class printcore():
self.online = False
self.printing = False
@locked
def connect(self, port = None, baud = None):
"""Set port and baudrate if given, then connect to printer
"""
......@@ -120,31 +135,35 @@ class printcore():
is_serial = False
except:
pass
self.writefailures = 0
if not is_serial:
self.printer_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.timeout = 0.25
self.printer_tcp.settimeout(1.0)
try:
self.printer_tcp.connect((hostname, port))
self.printer_tcp.settimeout(self.timeout)
self.printer = self.printer_tcp.makefile()
except socket.error:
except socket.error as e:
print _("Could not connect to %s:%s:") % (hostname, port)
self.printer = None
self.printer_tcp = None
traceback.print_exc()
print _("Socket error %s: %s") % (e.errno, e.strerror)
return
else:
disable_hup(self.port)
self.printer_tcp = None
try:
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)
self.printer = None
traceback.print_exc()
print _("Serial error: %s") % e
return
self.stop_read_thread = False
self.read_thread = Thread(target = self._listen)
self.read_thread.start()
self._start_sender()
def reset(self):
"""Reset the printer
......@@ -178,7 +197,7 @@ class printcore():
print "SelectError ({0}): {1}".format(e.errno, e.strerror)
raise
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
except socket.error as e:
print "Can't read from printer (disconnected?) (Socket error {0}): {1}".format(e.errno, e.strerror)
......@@ -254,6 +273,29 @@ class printcore():
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):
return reduce(lambda x, y:x^y, map(ord, command))
......@@ -302,7 +344,6 @@ class printcore():
self.printing = False
# try joining the print thread: enclose it in try/except because we might be calling it from the thread itself
try:
self.print_thread.join()
except:
......@@ -318,8 +359,6 @@ class printcore():
self.pauseF = self.analyzer.f;
self.pauseRelative = self.analyzer.relative;
def resume(self):
"""Resumes a paused print.
"""
......@@ -343,7 +382,7 @@ class printcore():
self.paused = False
self.printing = True
self.print_thread = Thread(target = self._print)
self.print_thread = Thread(target = self._print, kwargs = {"resuming": True})
self.print_thread.start()
def send(self, command, wait = 0):
......@@ -354,17 +393,7 @@ class printcore():
if self.printing:
self.mainqueue.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, 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
self.priqueue.put_nowait(command)
else:
print "Not connected to printer."
......@@ -372,40 +401,32 @@ class printcore():
"""Sends a command to the printer ahead of the command queue, without a checksum
"""
if self.online:
if self.printing:
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
self.priqueue.put_nowait(command)
else:
print "Not connected to printer."
def _print(self):
def _print(self, resuming = False):
self._stop_sender()
try:
if self.startcb:
#callback for printing started
try: self.startcb()
try: self.startcb(resuming)
except: pass
while self.printing and self.printer and self.online:
self._sendnext()
self.sentlines = {}
self.log.clear()
self.sent = []
try:
self.print_thread.join()
except: pass
self.print_thread = None
if self.endcb:
#callback for printing done
try: self.endcb()
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
def processHostCommand(self, command):
......@@ -430,8 +451,9 @@ class printcore():
self.resendfrom += 1
return
self.resendfrom = -1
if self.priqueue:
self._send(self.priqueue.pop(0))
if not self.priqueue.empty():
self._send(self.priqueue.get_nowait())
self.priqueue.task_done()
return
if self.printing and self.queueindex < len(self.mainqueue):
(layer, line) = self.mainqueue.idxs(self.queueindex)
......@@ -439,10 +461,10 @@ class printcore():
if self.layerchangecb and self.queueindex > 0:
(prev_layer, prev_line) = self.mainqueue.idxs(self.queueindex - 1)
if prev_layer != layer:
self.layerchangecb(layer)
try: self.layerchangecb(layer)
except: traceback.print_exc()
tline = gline.raw
#check for host command
if tline.lstrip().startswith(";@"):
if tline.lstrip().startswith(";@"): # check for host command
self.processHostCommand(tline)
self.queueindex += 1
return
......@@ -453,7 +475,7 @@ class printcore():
self.lineno += 1
if self.printsendcb:
try: self.printsendcb(gline)
except: pass
except: traceback.print_exc()
else:
self.clear = True
self.queueindex += 1
......@@ -482,12 +504,16 @@ class printcore():
try:
self.printer.write(str(command + "\n"))
self.printer.flush()
self.writefailures = 0
except socket.error as e:
print "Can't write to printer (disconnected?) (Socket error {0}): {1}".format(e.errno, e.strerror)
self.writefailures += 1
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:
print "Socket connection broken, disconnected. ({0}): {1}".format(e.errno, e.strerror)
self.writefailures += 1
if __name__ == '__main__':
baud = 115200
......
......@@ -51,6 +51,7 @@ class GCodeAnalyzer():
self.eOffset = 0
self.lastZPrint = 0
self.layerZ = 0
self.imperial = False
self.relative = False
self.eRelative = False
self.homeX = 0
......@@ -69,6 +70,7 @@ class GCodeAnalyzer():
def Analyze(self, gcode):
gline = gcoder.Line(gcode)
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_m = int(gline.command[1:]) if gline.command.startswith("M") else None
......@@ -97,7 +99,7 @@ class GCodeAnalyzer():
eChanged = True
self.e += code_e
else:
#absolute coordinates
# absolute coordinates
if code_x != None: self.x = self.xOffset + code_x
if code_y != None: self.y = self.yOffset + code_y
if code_z != None: self.z = self.zOffset + code_z
......@@ -112,6 +114,7 @@ class GCodeAnalyzer():
eChanged = True
self.e = self.eOffset + code_e
#limit checking
"""
if self.x < self.minX: self.x = self.minX
if self.y < self.minY: self.y = self.minY
if self.z < self.minZ: self.z = self.minZ
......@@ -119,7 +122,10 @@ class GCodeAnalyzer():
if self.x > self.maxX: self.x = self.maxX
if self.y > self.maxY: self.y = self.maxY
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
elif code_g == 20: self.imperial = True
elif code_g == 21: self.imperial = False
elif code_g == 28 or code_g == 161:
self.lastX = self.x
self.lastY = self.y
......@@ -189,7 +195,6 @@ class GCodeAnalyzer():
self.e = self.eOffset
#End code_g != None
if code_m != None:
code_m = int(code_m)
if code_m == 82: self.eRelative = False
elif code_m == 83: self.eRelative = True
......
#!/usr/bin/python
#!/usr/bin/env python
# This file is part of the Printrun suite.
#
# 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.
#
......
#!/usr/bin/python
#!/usr/bin/env python
# This file is part of the Printrun suite.
#
......
......@@ -165,6 +165,7 @@ def add_extra_controls(self, root, parentpanel, extra_buttons = None):
else:
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)
if standalone_mode:
self.Add(root.graph, pos = (base_line + 5, 0), span = (3, 6))
......@@ -292,9 +293,7 @@ class VizPane(wx.BoxSizer):
extrusion_width = root.settings.preview_extrusion_width)
root.gwindow.Bind(wx.EVT_CLOSE, lambda x: root.gwindow.Hide())
if not isinstance(root.gviz, NoViz):
self.Add(root.gviz.widget, 1, flag = wx.SHAPED)
root.centersizer = wx.GridBagSizer()
self.Add(root.centersizer, 0, flag = wx.EXPAND)
self.Add(root.gviz.widget, 1, flag = wx.SHAPED | wx.ALIGN_CENTER_HORIZONTAL)
class LogPane(wx.BoxSizer):
......@@ -390,7 +389,8 @@ class MainWindow(wx.Frame):
rightsizer = wx.BoxSizer(wx.VERTICAL)
extracontrols = wx.GridBagSizer()
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(rightsizer, 1, wx.ALIGN_CENTER)
self.mainsizer_page1.Add(page1panel2, 1, wx.EXPAND)
......@@ -414,13 +414,17 @@ class MainWindow(wx.Frame):
self.notebook.AddPage(page1panel, _("Commands"))
self.notebook.AddPage(page2panel, _("Status"))
self.panel.SetSizer(self.notesizer)
self.status = self.CreateStatusBar()
self.status.SetStatusText(_("Not connected to printer."))
self.statusbar = self.CreateStatusBar()
self.statusbar.SetStatusText(_("Not connected to printer."))
self.panel.Bind(wx.EVT_MOUSE_EVENTS, self.editbutton)
self.Bind(wx.EVT_CLOSE, self.kill)
vizpane.Detach(self.centersizer)
rightsizer.Add(self.centersizer, 0, wx.EXPAND)
# Custom buttons
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)
......@@ -430,22 +434,42 @@ class MainWindow(wx.Frame):
for i in self.printerControls:
i.Disable()
#self.panel.Fit()
self.cbuttons_panel = page1panel
self.cbuttons_reload()
def createGui(self):
def createGui(self, compact = False):
self.mainsizer = wx.BoxSizer(wx.VERTICAL)
self.uppersizer = MainToolbar(self)
self.lowersizer = wx.BoxSizer(wx.HORIZONTAL)
self.lowersizer.Add(LeftPane(self), 0)
self.lowersizer.Add(VizPane(self), 1, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL)
self.lowersizer.Add(LogPane(self), 1, wx.EXPAND)
self.mainsizer.Add(self.uppersizer, 0)
self.mainsizer.Add(self.lowersizer, 1, wx.EXPAND)
upperpanel = self.newPanel(self.panel)
self.uppersizer = MainToolbar(self, upperpanel)
lowerpanel = self.newPanel(self.panel)
upperpanel.SetSizer(self.uppersizer)
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.status = self.CreateStatusBar()
self.status.SetStatusText(_("Not connected to printer."))
self.statusbar = self.CreateStatusBar()
self.statusbar.SetStatusText(_("Not connected to printer."))
self.panel.Bind(wx.EVT_MOUSE_EVENTS, self.editbutton)
self.Bind(wx.EVT_CLOSE, self.kill)
......@@ -464,5 +488,4 @@ class MainWindow(wx.Frame):
for i in self.printerControls:
i.Disable()
#self.panel.Fit()
self.cbuttons_panel = self.panel
self.cbuttons_reload()
......@@ -120,8 +120,7 @@ class MacroEditor(wx.Dialog):
reindented += self.indent_chars + line + "\n"
return reindented
SETTINGS_GROUPS = {"General": _("General"),
"Printer": _("Printer settings"),
SETTINGS_GROUPS = {"Printer": _("Printer settings"),
"UI": _("User interface"),
"External": _("External commands")}
......@@ -136,7 +135,7 @@ class PronterOptionsDialog(wx.Dialog):
all_settings = pronterface.settings._all_settings()
group_list = []
groups = {}
for group in ["General", "UI", "Printer"]:
for group in ["Printer", "UI", "External"]:
group_list.append(group)
groups[group] = []
for setting in all_settings:
......@@ -153,8 +152,13 @@ class PronterOptionsDialog(wx.Dialog):
grid.AddGrowableCol(1)
grid.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_SPECIFIED)
for setting in settings:
grid.Add(setting.get_label(grouppanel), 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL|wx.ALIGN_RIGHT)
grid.Add(setting.get_widget(grouppanel), 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL|wx.EXPAND)
label,widget = setting.get_label(grouppanel),setting.get_widget(grouppanel)
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)
sbox.Add(notebook, 1, wx.EXPAND)
panel.SetSizer(sbox)
......
#!/usr/bin/python
#!/usr/bin/env python
# This file is part of the Printrun suite.
#
......
......@@ -60,14 +60,28 @@ def setting_add_tooltip(func):
@wraps(func)
def decorator(self, *args, **kwargs):
widget = func(self, *args, **kwargs)
if self.help:
widget.SetToolTipString(self.help)
helptxt = self.help or ""
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 decorator
class Setting(object):
DEFAULT_GROUP = "General"
DEFAULT_GROUP = "Printer"
hidden = False
......@@ -85,10 +99,20 @@ class Setting(object):
raise NotImplementedError
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
def get_label(self, parent):
import wx
widget = wx.StaticText(parent, -1, self.label or self.name)
widget.set_default = self.set_default
return widget
@setting_add_tooltip
......@@ -98,12 +122,6 @@ class Setting(object):
def get_specific_widget(self, parent):
raise NotImplementedError
def set(self, value):
raise NotImplementedError
def get(self):
raise NotImplementedError
def update(self):
raise NotImplementedError
......@@ -178,6 +196,9 @@ class BooleanSetting(wxSetting):
return bool(self._value)
def _set_value(self, value):
self._value = value
if self.widget:
self.widget.SetValue(bool(value))
value = property(_get_value, _set_value)
def get_specific_widget(self, parent):
......@@ -186,6 +207,23 @@ class BooleanSetting(wxSetting):
self.widget.SetValue(bool(self.value))
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):
#def _temperature_alias(self): return {"pla":210, "abs":230, "off":0}
#def _temperature_validate(self, v):
......@@ -196,16 +234,16 @@ class Settings(object):
# defaults here.
# the initial value determines the type
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(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_pla", 60, 0, 400, _("Bed temperature for PLA"), _("Heated Build Platform temp for PLA (default: 60 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_pla", 185, 0, 400, _("Extruder temperature for PLA"), _("Extruder temp for PLA (default: 185 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("z_feedrate", 200, 0, 50000, _("Z manual feedrate"), _("Feedrate for Control Panel Moves in Z (default: 200mm/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(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("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(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 (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 (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 (mm/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 (mm/min)"), "Printer"))
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"), "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))
......@@ -241,8 +279,10 @@ class Settings(object):
return object.__getattribute__(self, name)
return getattr(self, "_" + name).value
def _add(self, setting):
def _add(self, setting, callback = None):
setattr(self, setting.name, setting)
if callback:
setattr(self, "_" + setting.name + "_cb", callback)
def _set(self, key, value):
try:
......@@ -479,6 +519,9 @@ class pronsole(cmd.Cmd):
self.log("Empty macro - cancelled")
del self.cur_macro_name, self.cur_macro_def
def parseusercmd(self, line):
pass
def compile_macro_line(self, line):
line = line.rstrip()
ls = line.lstrip()
......@@ -487,7 +530,8 @@ class pronsole(cmd.Cmd):
if ls.startswith('!'):
return ws + ls[1:] + "\n" # python mode
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):
if macro_def.strip() == "":
......@@ -1157,7 +1201,7 @@ class pronsole(cmd.Cmd):
self.log("Printer is not online. Unable to extrude.")
return
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
ls = l.split()
if len(ls):
......
......@@ -46,7 +46,7 @@ import printcore
from printrun.printrun_utils import pixmapfile, configfile
from printrun.gui import MainWindow
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
tempreport_exp = re.compile("([TB]\d*):([-+]?\d*\.?\d*)(?: \/)?([-+]?\d*\.?\d*)")
......@@ -182,17 +182,19 @@ class PronterWindow(MainWindow, pronsole.pronsole):
monitorsetting.hidden = True
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(StringSetting("bgcolor", "#FFFFFF", _("Background color"), _("Pronterface background color (default: #FFFFFF)"), "UI"))
self.settings._add(BooleanSetting("tabbed", False, _("Use tabbed interface"), _("Use tabbed interface instead of the single window one"), "UI"))
self.settings._add(BooleanSetting("viz3d", False, _("Enable 3D viewer (requires restarting)"), _("Use 3D visualization instead of 2D layered visualization"), "UI"))
self.settings._add(StringSetting("bgcolor", "#FFFFFF", _("Background color"), _("Pronterface background color"), "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"), _("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(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(HiddenSetting("last_bed_temperature", 0.0))
self.settings._add(HiddenSetting("last_file_path", ""))
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(SpinSetting("preview_grid_step1", 10., 0, 200, _("Fine grid spacing"), _("Fine Grid Spacing (default: 10)"), "UI"))
self.settings._add(SpinSetting("preview_grid_step2", 50., 0, 200, _("Coarse grid spacing"), _("Coarse Grid Spacing (default: 50)"), "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"), "UI"), self.update_gviz_params)
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.endScript = "end.gcode"
......@@ -211,6 +213,8 @@ class PronterWindow(MainWindow, pronsole.pronsole):
self.capture_skip = {}
self.capture_skip_newline = False
self.tempreport = ""
self.userm114 = 0
self.userm105 = 0
self.monitor = 0
self.fgcode = None
self.skeinp = None
......@@ -229,6 +233,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
self.autoconnect = False
self.parse_cmdline(sys.argv[1:])
self.build_dimensions_list = parse_build_dimensions(self.settings.build_dimensions)
self.display_graph = self.settings.tempgraph
self.display_gauges = self.settings.tempgauges
#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):
except:
pass
self.popmenu()
if self.settings.tabbed:
if self.settings.uimode == "Tabbed":
self.createTabbedGui()
else:
self.createGui()
self.createGui(self.settings.uimode == "Compact")
self.t = Tee(self.catchprint)
self.stdout = sys.stdout
self.skeining = 0
......@@ -315,10 +320,13 @@ class PronterWindow(MainWindow, pronsole.pronsole):
pronsole.pronsole.process_cmdline_arguments(self, args)
self.autoconnect = args.autoconnect
def startcb(self):
def startcb(self, resuming = False):
self.starttime = time.time()
self.compute_eta = RemainingTimeEstimator(self.p.mainqueue)
print _("Print Started at: %s") % format_time(self.starttime)
if resuming:
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):
if self.p.queueindex == 0:
......@@ -372,13 +380,13 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if gline.s != None:
temp = gline.s
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":
gline.parse_coordinates(imperial = False, force = True)
if gline.s != None:
temp = gline.s
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:
return
self.sentlines.put_nowait(line)
......@@ -408,7 +416,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def setbedgui(self, f):
self.bsetpoint = 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:
wx.CallAfter(self.btemp.SetValue, str(f))
self.set("last_bed_temperature", str(f))
......@@ -428,7 +436,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def sethotendgui(self, f):
self.hsetpoint = 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:
wx.CallAfter(self.htemp.SetValue, str(f))
self.set("last_temperature", str(f))
......@@ -628,7 +636,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
try:
while True:
item = self.macros_menu.FindItemByPosition(1)
if item is None: return
if item is None: break
self.macros_menu.DeleteItem(item)
except:
pass
......@@ -707,6 +715,37 @@ class PronterWindow(MainWindow, pronsole.pronsole):
self.gwindow.SetToolTip(wx.ToolTip("Mousewheel zooms the display\nShift / Mousewheel scrolls layers"))
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):
self.feedrates_changed = True
try:
......@@ -723,28 +762,15 @@ class PronterWindow(MainWindow, pronsole.pronsole):
pass
def cbuttons_reload(self):
allcbs = []
ubs = self.uppersizer
cs = self.centersizer
#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)
allcbs = getattr(self, "custombuttonbuttons", [])
for button in allcbs:
self.centersizer.Detach(button)
button.Destroy()
self.custombuttonbuttons = []
newbuttonbuttonindex = len(self.custombuttons)
while newbuttonbuttonindex>0 and self.custombuttons[newbuttonbuttonindex-1] is None:
newbuttonbuttonindex -= 1
while len(self.custombuttons) < 13:
self.custombuttons.append(None)
for i in xrange(len(self.custombuttons)):
btndef = self.custombuttons[i]
custombuttons = self.custombuttons[:] + [None]
for i, btndef in enumerate(custombuttons):
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))
if btndef.background:
b.SetBackgroundColour(btndef.background)
......@@ -752,14 +778,14 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if 0.3*rr+0.59*gg+0.11*bb < 60:
b.SetForegroundColour("#ffffff")
except:
if i == newbuttonbuttonindex:
self.newbuttonbutton = b = wx.Button(self.cbuttons_panel, -1, "+", size = (19, 18), style = wx.BU_EXACTFIT)
if i == len(custombuttons) - 1:
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.SetForegroundColour("#4444ff")
b.SetToolTip(wx.ToolTip(_("click to add new custom button")))
b.Bind(wx.EVT_BUTTON, self.cbutton_edit)
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.Disable()
#continue
......@@ -768,14 +794,9 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if btndef is not None:
b.Bind(wx.EVT_BUTTON, self.procbutton)
b.Bind(wx.EVT_MOUSE_EVENTS, self.editbutton)
#else:
# b.Bind(wx.EVT_BUTTON, lambda e:e.Skip())
self.custombuttonbuttons.append(b)
#if i<4:
# ubs.Add(b)
#else:
cs.Add(b, pos = ((i)/4, (i)%4))
self.mainsizer.Layout()
self.centersizer.Add(b, pos = (i // 4, i % 4))
self.panel.GetSizer().Layout()
def help_button(self):
print _('Defines custom button. Usage: button <num> "title" [/c "colour"] command')
......@@ -1063,13 +1084,21 @@ class PronterWindow(MainWindow, pronsole.pronsole):
self.zb.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):
try:
if hasattr(e.GetEventObject(),"custombutton"):
if wx.GetKeyState(wx.WXK_CONTROL) or wx.GetKeyState(wx.WXK_ALT):
return self.editbutton(e)
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
except:
print _("event object missing")
......@@ -1110,6 +1139,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def setmonitor(self, e):
self.monitor = self.monitorbox.GetValue()
self.set("monitor", self.monitor)
if self.display_graph:
if self.monitor:
wx.CallAfter(self.graph.StartPlotting, 1000)
else:
......@@ -1129,6 +1159,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if not len(command):
return
wx.CallAfter(self.addtexttolog, ">>>" + command + "\n");
self.parseusercmd(str(command))
self.onecmd(str(command))
self.commandbox.SetSelection(0, len(command))
self.commandbox.history.append(command)
......@@ -1145,13 +1176,13 @@ class PronterWindow(MainWindow, pronsole.pronsole):
hotend_temp = float(temps["T0"][0])
else:
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 "T1" in temps:
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
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)
except:
traceback.print_exc()
......@@ -1196,8 +1227,14 @@ class PronterWindow(MainWindow, pronsole.pronsole):
string += _(" Est: %s of %s remaining | ") % (format_duration(secondsremain),
format_duration(secondsestimate))
string += _(" Z: %.3f mm") % self.curlayer
wx.CallAfter(self.status.SetStatusText, string)
wx.CallAfter(self.statusbar.SetStatusText, string)
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.sdprinting:
self.p.send_now("M27")
......@@ -1210,10 +1247,14 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if not self.statuscheck:
break
time.sleep(0.25)
try:
while not self.sentlines.empty():
gc = self.sentlines.get_nowait()
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):
stdout = sys.stdout
......@@ -1239,11 +1280,17 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if "ok C:" in l or "Count" in l:
self.posreport = l
self.update_pos(l)
if self.userm114 > 0:
self.userm114 -= 1
else:
isreport = True
if "ok T:" in l:
self.tempreport = l
wx.CallAfter(self.tempdisp.SetLabel, self.tempreport.strip().replace("ok ", ""))
self.update_tempdisplay()
if self.userm105 > 0:
self.userm105 -= 1
else:
isreport = True
tstring = l.rstrip()
if self.p.loud or (tstring not in ["ok", "wait"] and not isreport):
......@@ -1263,19 +1310,19 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def waitforsdresponse(self, 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)
return
if "File opened" in l:
wx.CallAfter(self.status.SetStatusText, l)
wx.CallAfter(self.statusbar.SetStatusText, l)
if "File selected" in l:
wx.CallAfter(self.status.SetStatusText, _("Starting print"))
wx.CallAfter(self.statusbar.SetStatusText, _("Starting print"))
self.sdprinting = 1
self.p.send_now("M24")
self.startcb()
return
if "Done printing file" in l:
wx.CallAfter(self.status.SetStatusText, l)
wx.CallAfter(self.statusbar.SetStatusText, l)
self.sdprinting = 0
self.recvlisteners.remove(self.waitforsdresponse)
self.endcb()
......@@ -1330,7 +1377,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def skein_monitor(self):
while(not self.stopsf):
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:
pass
time.sleep(0.1)
......@@ -1341,7 +1388,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if self.p.online:
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),)
wx.CallAfter(self.pausebtn.Disable)
wx.CallAfter(self.printbtn.SetLabel, _("Print"))
......@@ -1391,7 +1438,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
name = dlg.GetPath()
dlg.Destroy()
if not os.path.exists(name):
self.status.SetStatusText(_("File not found!"))
self.statusbar.SetStatusText(_("File not found!"))
return
path = os.path.split(name)[0]
if path != self.settings.last_file_path:
......@@ -1403,7 +1450,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
else:
self.filename = name
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))
wx.CallAfter(self.printbtn.SetLabel, _("Print"))
wx.CallAfter(self.pausebtn.SetLabel, _("Pause"))
......@@ -1435,17 +1482,17 @@ class PronterWindow(MainWindow, pronsole.pronsole):
if self.paused:
self.p.paused = 0
self.paused = 0
self.on_startprint()
if self.sdprinting:
self.on_startprint()
self.p.send_now("M26 S0")
self.p.send_now("M24")
return
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
if not self.p.online:
wx.CallAfter(self.status.SetStatusText, _("Not connected to printer."))
wx.CallAfter(self.statusbar.SetStatusText, _("Not connected to printer."))
return
self.on_startprint()
self.p.startprint(self.fgcode)
......@@ -1457,7 +1504,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def endupload(self):
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)
self.p.clear = True
self.uploading = False
......@@ -1484,8 +1531,8 @@ class PronterWindow(MainWindow, pronsole.pronsole):
dlg.Destroy()
def pause(self, event):
print _("Paused.")
if not self.paused:
print _("Print paused at: %s") % format_time(time.time())
if self.sdprinting:
self.p.send_now("M25")
else:
......@@ -1499,6 +1546,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
self.extra_print_time += int(time.time() - self.starttime)
wx.CallAfter(self.pausebtn.SetLabel, _("Resume"))
else:
print _("Resuming.")
self.paused = False
if self.sdprinting:
self.p.send_now("M24")
......@@ -1537,12 +1585,12 @@ class PronterWindow(MainWindow, pronsole.pronsole):
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.")
print _("Error: You are trying to connect to a non-existing 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
traceback.print_exc()
# Kill the scope anyway
return
self.statuscheck = True
......@@ -1558,7 +1606,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
def recover(self, event):
self.extra_print_time = 0
if not self.p.online:
wx.CallAfter(self.status.SetStatusText, _("Not connected to printer."))
wx.CallAfter(self.statusbar.SetStatusText, _("Not connected to printer."))
return
# Reset Z
self.p.send_now("G92 Z%f" % self.predisconnect_layer)
......@@ -1572,7 +1620,7 @@ class PronterWindow(MainWindow, pronsole.pronsole):
self.predisconnect_queueindex = self.p.queueindex
self.predisconnect_layer = self.curlayer
def disconnect(self, event):
def disconnect(self, event = None):
print _("Disconnected.")
if self.p.printing or self.p.paused or self.paused:
self.store_predisconnect_state()
......
#!/usr/bin/env python2.7
#!/usr/bin/env python
import tornado.ioloop
import tornado.web
......
......@@ -144,8 +144,8 @@ setup (
url = "http://github.com/kliment/Printrun/",
license = "GPLv3",
data_files = data_files,
packages = ["printrun", "printrun.svg"],
scripts = ["pronsole.py", "pronterface.py", "plater.py", "printcore.py", "pronserve.py"],
packages = ["printrun", "printrun.cairosvg"],
scripts = ["pronsole.py", "pronterface.py", "plater.py", "printcore.py", "prontserve.py"],
cmdclass = {"uninstall" : uninstall,
"install" : install,
"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