# Conflicts:
#	FlatCAMDraw.py
#	FlatCAMGUI.py
This commit is contained in:
Marius Stanciu
2018-05-31 18:11:41 +03:00
78 changed files with 495 additions and 512 deletions

View File

@@ -8,7 +8,7 @@
import sys
import traceback
import urllib
import urllib.request, urllib.parse, urllib.error
import getopt
import random
import logging
@@ -16,8 +16,8 @@ import simplejson as json
import re
import webbrowser
import os
import Tkinter
from PyQt4 import QtCore
import tkinter
from PyQt4 import Qt, QtCore, QtGui
import time # Just used for debugging. Double check before removing.
from xml.dom.minidom import parseString as parse_xml_string
from contextlib import contextmanager
@@ -27,10 +27,10 @@ from contextlib import contextmanager
########################################
import FlatCAMVersion
from FlatCAMWorker import Worker
from ObjectCollection import *
from FlatCAMObj import *
from PlotCanvas import *
from FlatCAMGUI import *
import ObjectCollection
from FlatCAMObj import FlatCAMCNCjob, FlatCAMExcellon, FlatCAMGerber, FlatCAMGeometry, FlatCAMObj
from PlotCanvas import PlotCanvas
from FlatCAMGUI import FlatCAMGUI, GlobalOptionsUI, FlatCAMActivityView, FlatCAMInfoBar
from FlatCAMCommon import LoudDict
from FlatCAMShell import FCShell
from FlatCAMDraw import FlatCAMDraw
@@ -39,6 +39,8 @@ from MeasurementTool import Measurement
from DblSidedTool import DblSidedTool
import tclCommands
from camlib import *
########################################
## App ##
@@ -54,11 +56,11 @@ class App(QtCore.QObject):
try:
cmd_line_options, args = getopt.getopt(sys.argv[1:], "h:", "shellfile=")
except getopt.GetoptError:
print cmd_line_help
print(cmd_line_help)
sys.exit(2)
for opt, arg in cmd_line_options:
if opt == '-h':
print cmd_line_help
print(cmd_line_help)
sys.exit()
elif opt == '--shellfile':
cmd_line_shellfile = arg
@@ -106,16 +108,16 @@ class App(QtCore.QObject):
# Note: Setting the parameters to unicode does not seem
# to have an effect. Then are received as Qstring
# anyway.
file_opened = QtCore.pyqtSignal(unicode, unicode) # File type and filename
file_opened = QtCore.pyqtSignal(str, str) # File type and filename
progress = QtCore.pyqtSignal(int) # Percentage of progress
plots_updated = QtCore.pyqtSignal()
# Emitted by new_object() and passes the new object as argument.
# on_object_created() adds the object to the collection,
# Emitted by new_object() and passes the new object as argument and a plot flag
# on_object_created() adds the object to the collection, plot the object if plot flag is True
# and emits new_object_available.
object_created = QtCore.pyqtSignal(object)
object_created = QtCore.pyqtSignal(object, bool)
# Emitted when a new object has been added to the collection
# and is ready to be used.
@@ -471,7 +473,7 @@ class App(QtCore.QObject):
#self.options_write_form()
self.on_options_combo_change(0) # Will show the initial form
self.collection = ObjectCollection()
self.collection = ObjectCollection.ObjectCollection()
self.ui.project_tab_layout.addWidget(self.collection.view)
#### End of Data ####
@@ -619,7 +621,7 @@ class App(QtCore.QObject):
cmd_line_shellfile_text = myfile.read()
self.shell._sysShell.exec_command(cmd_line_shellfile_text)
except Exception as ext:
print "ERROR: ", ext
print(("ERROR: ", ext))
sys.exit(2)
# Post-GUI initialization: Experimental attempt
@@ -637,7 +639,7 @@ class App(QtCore.QObject):
# because tcl was execudted in old instance of TCL
pass
else:
self.tcl = Tkinter.Tcl()
self.tcl = tkinter.Tcl()
self.setup_shell()
def defaults_read_form(self):
@@ -700,7 +702,7 @@ class App(QtCore.QObject):
:return: None
"""
if not isinstance(self.collection.get_active(), FlatCAMGeometry):
self.info("Select a Geometry Object to edit.")
self.inform.emit("Select a Geometry Object to edit.")
return
self.ui.updategeo_btn.setEnabled(True)
@@ -715,7 +717,7 @@ class App(QtCore.QObject):
"""
geo = self.collection.get_active()
if not isinstance(geo, FlatCAMGeometry):
self.info("Select a Geometry Object to update.")
self.inform.emit("Select a Geometry Object to update.")
return
self.draw.update_fcgeometry(geo)
@@ -856,7 +858,7 @@ class App(QtCore.QObject):
if result != 'None':
self.shell.append_output(result + '\n')
except Tkinter.TclError, e:
except tkinter.TclError as e:
# This will display more precise answer if something in TCL shell fails
result = self.tcl.eval("set errorInfo")
self.log.error("Exec command Exception: %s" % (result + '\n'))
@@ -902,7 +904,7 @@ class App(QtCore.QObject):
if retval and retfcn(retval):
self.shell.append_output(retfcn(retval) + "\n")
except Exception, e:
except Exception as e:
#self.shell.append_error(''.join(traceback.format_exc()))
#self.shell.append_error("?\n")
self.shell.append_error(str(e) + "\n")
@@ -922,14 +924,14 @@ class App(QtCore.QObject):
if match:
level = match.group(1)
msg_ = match.group(2)
self.ui.fcinfo.set_status(QtCore.QString(msg_), level=level)
self.ui.fcinfo.set_status(str(msg_), level=level)
if toshell:
error = level == "error" or level == "warning"
self.shell_message(msg, error=error, show=True)
else:
self.ui.fcinfo.set_status(QtCore.QString(msg), level="info")
self.ui.fcinfo.set_status(str(msg), level="info")
if toshell:
self.shell_message(msg)
@@ -980,7 +982,7 @@ class App(QtCore.QObject):
self.log.debug(" %s" % kind)
self.log.debug(" %s" % filename)
record = {'kind': unicode(kind), 'filename': unicode(filename)}
record = {'kind': str(kind), 'filename': str(filename)}
if record in self.recent:
return
@@ -1028,9 +1030,12 @@ class App(QtCore.QObject):
but before it is attached to the application. The function is
called with 2 parameters: the new object and the App instance.
:type initialize: function
:param plot: Whether to plot the object or not
:type plot: Bool
:return: None
:rtype: None
"""
self.plot = plot
App.log.debug("new_object()")
@@ -1054,6 +1059,10 @@ class App(QtCore.QObject):
oname = option[len(kind) + 1:]
obj.options[oname] = self.options[option]
# make sure that the plot option of the new object is reflecting the current status and not the general option
# solve issues with the modelview currently used (checkbox on the Project Tab)
obj.options['plot'] = self.plot
# Initialize as per user request
# User must take care to implement initialize
# in a thread-safe way as is is likely that we
@@ -1072,11 +1081,11 @@ class App(QtCore.QObject):
t3 = time.time()
self.log.debug("%f seconds converting units." % (t3 - t2))
FlatCAMApp.App.log.debug("Moving new object back to main thread.")
self.log.debug("Moving new object back to main thread.")
# Move the object to the main thread and let the app know that it is available.
obj.moveToThread(QtGui.QApplication.instance().thread())
self.object_created.emit(obj)
self.object_created.emit(obj, self.plot)
return obj
@@ -1123,7 +1132,7 @@ class App(QtCore.QObject):
layout1.addLayout(layout2)
logo = QtGui.QLabel()
logo.setPixmap(QtGui.QPixmap('share:flatcam_icon256.png'))
logo.setPixmap(QtGui.QPixmap('share/flatcam_icon256.png'))
layout2.addWidget(logo, stretch=0)
title = QtGui.QLabel(
@@ -1490,12 +1499,14 @@ class App(QtCore.QObject):
# Keep this for later
try:
name = self.collection.get_active().options["name"]
isPlotted = self.collection.get_active().options["plot"]
except AttributeError:
self.log.debug("Nothing selected for deletion")
return
# Remove plot
self.plotcanvas.figure.delaxes(self.collection.get_active().axes)
# Remove plot only if the object was plotted otherwise delaxes will fail
if isPlotted:
self.plotcanvas.figure.delaxes(self.collection.get_active().axes)
self.plotcanvas.auto_adjust_axes()
# Clear form
@@ -1537,11 +1548,12 @@ class App(QtCore.QObject):
def on_row_activated(self, index):
self.ui.notebook.setCurrentWidget(self.ui.selected_tab)
def on_object_created(self, obj):
def on_object_created(self, obj, plot):
"""
Event callback for object creation.
:param obj: The newly created FlatCAM object.
:param plot: If to plot the new object, bool
:return: None
"""
t0 = time.time() # DEBUG
@@ -1552,7 +1564,9 @@ class App(QtCore.QObject):
self.inform.emit("Object (%s) created: %s" % (obj.kind, obj.options['name']))
self.new_object_available.emit(obj)
obj.plot()
if plot:
obj.plot()
self.on_zoom_fit(None)
t1 = time.time() # DEBUG
self.log.debug("%f seconds adding object and plotting." % (t1 - t0))
@@ -1634,10 +1648,11 @@ class App(QtCore.QObject):
try:
App.log.debug('button=%d, x=%d, y=%d, xdata=%f, ydata=%f' % (
event.button, event.x, event.y, event.xdata, event.ydata))
modifiers = QtGui.QApplication.keyboardModifiers()
if modifiers == QtCore.Qt.ControlModifier:
self.clipboard.setText(self.defaults["point_clipboard_format"] % (event.xdata, event.ydata))
self.clipboard.setText(self.defaults["point_clipboard_format"] % (event.xdata, event.ydata))
except Exception, e:
except Exception as e:
App.log.debug("Outside plot?")
App.log.debug(str(e))
@@ -1707,7 +1722,7 @@ class App(QtCore.QObject):
# The Qt methods above will return a QString which can cause problems later.
# So far json.dump() will fail to serialize it.
# TODO: Improve the serialization methods and remove this fix.
filename = unicode(filename)
filename = str(filename)
if filename == "":
self.inform.emit("Open cancelled.")
@@ -1734,7 +1749,7 @@ class App(QtCore.QObject):
# The Qt methods above will return a QString which can cause problems later.
# So far json.dump() will fail to serialize it.
# TODO: Improve the serialization methods and remove this fix.
filename = unicode(filename)
filename = str(filename)
if filename == "":
self.inform.emit("Open cancelled.")
@@ -1761,7 +1776,7 @@ class App(QtCore.QObject):
# The Qt methods above will return a QString which can cause problems later.
# So far json.dump() will fail to serialize it.
# TODO: Improve the serialization methods and remove this fix.
filename = unicode(filename)
filename = str(filename)
if filename == "":
self.inform.emit("Open cancelled.")
@@ -1788,7 +1803,7 @@ class App(QtCore.QObject):
# The Qt methods above will return a QString which can cause problems later.
# So far json.dump() will fail to serialize it.
# TODO: Improve the serialization methods and remove this fix.
filename = unicode(filename)
filename = str(filename)
if filename == "":
self.inform.emit("Open cancelled.")
@@ -1838,7 +1853,7 @@ class App(QtCore.QObject):
except TypeError:
filename = QtGui.QFileDialog.getSaveFileName(caption="Export SVG")
filename = unicode(filename)
filename = str(filename)
if filename == "":
self.inform.emit("Export SVG cancelled.")
@@ -1861,7 +1876,7 @@ class App(QtCore.QObject):
except TypeError:
filename = QtGui.QFileDialog.getOpenFileName(caption="Import SVG")
filename = unicode(filename)
filename = str(filename)
if filename == "":
self.inform.emit("Open cancelled.")
@@ -1904,7 +1919,7 @@ class App(QtCore.QObject):
except TypeError:
filename = QtGui.QFileDialog.getSaveFileName(caption="Save Project As ...")
filename = unicode(filename)
filename = str(filename)
try:
f = open(filename, 'r')
@@ -2038,7 +2053,7 @@ class App(QtCore.QObject):
app_obj.progress.emit(0)
raise IOError('Failed to open file: ' + filename)
except ParseError, e:
except ParseError as e:
app_obj.inform.emit("[error] Failed to parse file: " + filename + ". " + e[0])
app_obj.progress.emit(0)
self.log.error(str(e))
@@ -2339,7 +2354,7 @@ class App(QtCore.QObject):
self.worker_task.emit({'fcn': worker_task, 'params': [self]})
def register_folder(self, filename):
self.defaults["last_folder"] = os.path.split(unicode(filename))[0]
self.defaults["last_folder"] = os.path.split(str(filename))[0]
def set_progress_bar(self, percentage, text=""):
self.ui.progress_bar.setValue(int(percentage))
@@ -3591,7 +3606,7 @@ class App(QtCore.QObject):
output = ''
import collections
od = collections.OrderedDict(sorted(commands.items()))
for cmd_, val in od.iteritems():
for cmd_, val in list(od.items()):
#print cmd, '\n', ''.join(['~']*len(cmd))
output += cmd_ + ' \n' + ''.join(['~'] * len(cmd_)) + '\n'
@@ -3645,7 +3660,7 @@ class App(QtCore.QObject):
try:
obj.follow(**kwa)
except Exception, e:
except Exception as e:
return "ERROR: %s" % str(e)
# def get_sys(param):
@@ -4139,11 +4154,11 @@ class App(QtCore.QObject):
# TODO: Move this to constructor
icons = {
"gerber": "share:flatcam_icon16.png",
"excellon": "share:drill16.png",
"cncjob": "share:cnc16.png",
"project": "share:project16.png",
"svg": "share:geometry16.png"
"gerber": "share/flatcam_icon16.png",
"excellon": "share/drill16.png",
"cncjob": "share/cnc16.png",
"project": "share/project16.png",
"svg": "share/geometry16.png"
}
openers = {
@@ -4232,12 +4247,12 @@ class App(QtCore.QObject):
"?s=" + str(self.defaults['serial']) + \
"&v=" + str(self.version) + \
"&os=" + str(self.os) + \
"&" + urllib.urlencode(self.defaults["stats"])
"&" + urllib.parse.urlencode(self.defaults["stats"])
App.log.debug("Checking for updates @ %s" % full_url)
### Get the data
try:
f = urllib.urlopen(full_url)
f = urllib.request.urlopen(full_url)
except:
# App.log.warning("Failed checking for latest version. Could not connect.")
self.log.warning("Failed checking for latest version. Could not connect.")
@@ -4246,7 +4261,7 @@ class App(QtCore.QObject):
try:
data = json.load(f)
except Exception, e:
except Exception as e:
App.log.error("Could not parse information about latest version.")
self.inform.emit("[error] Could not parse information about latest version.")
App.log.debug("json.load(): %s" % str(e))
@@ -4264,7 +4279,7 @@ class App(QtCore.QObject):
App.log.debug("Newer version available.")
self.message.emit(
"Newer Version Available",
QtCore.QString("There is a newer version of FlatCAM " +
str("There is a newer version of FlatCAM " +
"available for download:<br><br>" +
"<B>" + data["name"] + "</b><br>" +
data["message"].replace("\n", "<br>")),