From 8aaeee23fd4eda645138107014b5ba93ef9688de Mon Sep 17 00:00:00 2001 From: mquezada Date: Wed, 16 May 2018 16:05:23 -0400 Subject: [PATCH 01/21] Fix model reference for test. --- ObjectCollection.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ObjectCollection.py b/ObjectCollection.py index 82ccef5b..a28e7afc 100644 --- a/ObjectCollection.py +++ b/ObjectCollection.py @@ -289,7 +289,7 @@ class ObjectCollection(): :param name: Name of the FlatCAM Object :return: None """ - iobj = self.createIndex(self.get_names().index(name), 0) # Column 0 + iobj = self.model.createIndex(self.get_names().index(name), 0) # Column 0 self.view.selectionModel().select(iobj, QtGui.QItemSelectionModel.Select) def set_inactive(self, name): @@ -300,7 +300,7 @@ class ObjectCollection(): :param name: Name of the FlatCAM Object :return: None """ - iobj = self.createIndex(self.get_names().index(name), 0) # Column 0 + iobj = self.model.createIndex(self.get_names().index(name), 0) # Column 0 self.view.selectionModel().select(iobj, QtGui.QItemSelectionModel.Deselect) def set_all_inactive(self): From bdc2d8cc593381c3d5d46362558effc23c030f0f Mon Sep 17 00:00:00 2001 From: Jakob Staudt Date: Thu, 24 May 2018 11:52:02 +0200 Subject: [PATCH 02/21] Added postprocessing GUI and Code --- FlatCAMObj.py | 6 ++++-- ObjectUI.py | 13 ++++++++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index f37ff471..89997ef8 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -1044,6 +1044,7 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): "tooldia": self.ui.tooldia_entry, "append": self.ui.append_text, "prepend": self.ui.prepend_text, + "postprocess": self.ui.process_script, "dwell": self.ui.dwell_cb, "dwelltime": self.ui.dwelltime_entry }) @@ -1073,8 +1074,9 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): preamble = str(self.ui.prepend_text.get_value()) postamble = str(self.ui.append_text.get_value()) + processor = str(self.ui.process_script.get_value()) - self.export_gcode(filename, preamble=preamble, postamble=postamble) + self.export_gcode(filename, preamble=preamble, postamble=postamble, processor=processor) def dwell_generator(self, lines): """ @@ -1110,7 +1112,7 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): raise StopIteration - def export_gcode(self, filename, preamble='', postamble=''): + def export_gcode(self, filename, preamble='', postamble='', processor=''): lines = StringIO(self.gcode) diff --git a/ObjectUI.py b/ObjectUI.py index 1bf20bf7..1e80be65 100644 --- a/ObjectUI.py +++ b/ObjectUI.py @@ -196,6 +196,17 @@ class CNCObjectUI(ObjectUI): self.append_text = FCTextArea() self.custom_box.addWidget(self.append_text) + processorlabel = QtGui.QLabel('Postprocessing-Script:') + processorlabel.setToolTip( + "Enter a Postprocessing Script here.\n" + "It gets applied to the G-Code after it\n" + "is generated." + ) + self.custom_box.addWidget(processorlabel) + self.processing_script = FCTextArea() + self.custom_box.addWidget(self.processing_script) + + # Dwell grid1 = QtGui.QGridLayout() self.custom_box.addLayout(grid1) @@ -814,4 +825,4 @@ class GerberObjectUI(ObjectUI): # # # if __name__ == '__main__': -# main() \ No newline at end of file +# main() From 6877d0cd9b551bceb76f0cff24183be2e75765a4 Mon Sep 17 00:00:00 2001 From: Jakob Staudt Date: Thu, 24 May 2018 11:57:42 +0200 Subject: [PATCH 03/21] Added postprocessing GUI and Code --- FlatCAMObj.py | 2 +- ObjectUI.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 89997ef8..b8c12945 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -1074,7 +1074,7 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): preamble = str(self.ui.prepend_text.get_value()) postamble = str(self.ui.append_text.get_value()) - processor = str(self.ui.process_script.get_value()) + processor = str(self.ui.process_script.get_value()) self.export_gcode(filename, preamble=preamble, postamble=postamble, processor=processor) diff --git a/ObjectUI.py b/ObjectUI.py index 1e80be65..611a8bc4 100644 --- a/ObjectUI.py +++ b/ObjectUI.py @@ -203,8 +203,8 @@ class CNCObjectUI(ObjectUI): "is generated." ) self.custom_box.addWidget(processorlabel) - self.processing_script = FCTextArea() - self.custom_box.addWidget(self.processing_script) + self.process_script = FCTextArea() + self.custom_box.addWidget(self.process_script) # Dwell From 20bc6b4da5894ccf5fd1db9d5627e53a151188d2 Mon Sep 17 00:00:00 2001 From: Jakob Staudt Date: Thu, 24 May 2018 10:04:47 +0000 Subject: [PATCH 04/21] Fixed Indentation Error in line 1077 --- FlatCAMObj.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index b8c12945..bea692b5 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -1074,7 +1074,7 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): preamble = str(self.ui.prepend_text.get_value()) postamble = str(self.ui.append_text.get_value()) - processor = str(self.ui.process_script.get_value()) + processor = str(self.ui.process_script.get_value()) self.export_gcode(filename, preamble=preamble, postamble=postamble, processor=processor) From c34c59f8704f2b0447b22f12b9f98129d08051b3 Mon Sep 17 00:00:00 2001 From: Jakob Staudt Date: Thu, 24 May 2018 10:16:48 +0000 Subject: [PATCH 05/21] Changed Indentation to Spaces --- FlatCAMObj.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index bea692b5..56a4e695 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -1044,7 +1044,7 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): "tooldia": self.ui.tooldia_entry, "append": self.ui.append_text, "prepend": self.ui.prepend_text, - "postprocess": self.ui.process_script, + "postprocess": self.ui.process_script, "dwell": self.ui.dwell_cb, "dwelltime": self.ui.dwelltime_entry }) @@ -1074,7 +1074,7 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): preamble = str(self.ui.prepend_text.get_value()) postamble = str(self.ui.append_text.get_value()) - processor = str(self.ui.process_script.get_value()) + processor = str(self.ui.process_script.get_value()) self.export_gcode(filename, preamble=preamble, postamble=postamble, processor=processor) From a4bbb98bf1a70c306f4417e2e3032112e6b9b671 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sat, 26 May 2018 04:43:40 +0300 Subject: [PATCH 06/21] - converted from Python2 code to Python3 code - in camlib.py, CNCJob class -> generate_from_excellon_by_tool() was failing in the line to sort the tools due of been unable to compare between dict's. I replaced that section. --- FlatCAMApp.py | 68 ++++++------ FlatCAMDraw.py | 62 +++++------ FlatCAMGUI.py | 100 +++++++++--------- FlatCAMObj.py | 41 +++---- GUIElements.py | 18 ++-- ObjectCollection.py | 10 +- ObjectUI.py | 8 +- bugs/conf.py | 16 +-- camlib.py | 14 ++- descartes/tests.py | 12 +-- doc/source/conf.py | 16 +-- flatcam | 2 +- make_win32.py | 6 +- sandbox/diagnose.py | 20 ++-- sandbox/gerber_find.py | 6 +- svgparse.py | 4 +- tclCommands/TclCommand.py | 12 +-- tclCommands/TclCommandAddCircle.py | 4 +- tclCommands/TclCommandAddPolygon.py | 4 +- tclCommands/TclCommandAddPolyline.py | 4 +- tclCommands/TclCommandAddRectangle.py | 4 +- tclCommands/TclCommandAlignDrill.py | 8 +- tclCommands/TclCommandAlignDrillGrid.py | 4 +- tclCommands/TclCommandCncjob.py | 4 +- tclCommands/TclCommandCutout.py | 6 +- tclCommands/TclCommandDelete.py | 4 +- tclCommands/TclCommandDrillcncjob.py | 4 +- tclCommands/TclCommandExportGcode.py | 4 +- tclCommands/TclCommandExportSVG.py | 4 +- tclCommands/TclCommandExteriors.py | 4 +- tclCommands/TclCommandGeoCutout.py | 4 +- tclCommands/TclCommandGeoUnion.py | 4 +- tclCommands/TclCommandGetNames.py | 4 +- tclCommands/TclCommandGetSys.py | 4 +- tclCommands/TclCommandImportSvg.py | 4 +- tclCommands/TclCommandInteriors.py | 4 +- tclCommands/TclCommandIsolate.py | 4 +- tclCommands/TclCommandJoinExcellon.py | 4 +- tclCommands/TclCommandJoinGeometry.py | 4 +- tclCommands/TclCommandMillHoles.py | 4 +- tclCommands/TclCommandMirror.py | 8 +- tclCommands/TclCommandNew.py | 4 +- tclCommands/TclCommandNewGeometry.py | 4 +- tclCommands/TclCommandOffset.py | 4 +- tclCommands/TclCommandOpenExcellon.py | 4 +- tclCommands/TclCommandOpenGCode.py | 4 +- tclCommands/TclCommandOpenGerber.py | 6 +- tclCommands/TclCommandOpenProject.py | 4 +- tclCommands/TclCommandOptions.py | 4 +- tclCommands/TclCommandPaint.py | 4 +- tclCommands/TclCommandPanelize.py | 4 +- tclCommands/TclCommandPlot.py | 4 +- tclCommands/TclCommandSaveProject.py | 4 +- tclCommands/TclCommandScale.py | 4 +- tclCommands/TclCommandSetActive.py | 4 +- tclCommands/TclCommandSetSys.py | 4 +- tclCommands/TclCommandSubtractPoly.py | 4 +- tclCommands/TclCommandSubtractRectangle.py | 4 +- tclCommands/TclCommandVersion.py | 4 +- tclCommands/TclCommandWriteGCode.py | 4 +- tclCommands/__init__.py | 4 +- tests/canvas/performance.py | 4 +- tests/other/destructor_test.py | 2 +- tests/other/test_fcrts.py | 6 +- tests/other/test_rt.py | 6 +- tests/test_excellon_flow.py | 18 ++-- tests/test_gerber_flow.py | 18 ++-- tests/test_paint.py | 42 ++++---- tests/test_pathconnect.py | 6 +- tests/test_polygon_paint.py | 24 ++--- tests/test_svg_flow.py | 14 +-- tests/test_tclCommands/__init__.py | 28 ++--- .../test_tclCommands/test_TclCommandCncjob.py | 2 +- .../test_TclCommandDrillcncjob.py | 2 +- .../test_TclCommandExportGcode.py | 4 +- tests/test_tcl_shell.py | 4 +- 76 files changed, 394 insertions(+), 389 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 04048a5b..095aa4c4 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -8,7 +8,7 @@ import sys import traceback -import urllib +import urllib.request, urllib.parse, urllib.error import getopt import random import logging @@ -16,7 +16,7 @@ import simplejson as json import re import webbrowser import os -import Tkinter +import tkinter from PyQt4 import QtCore import time # Just used for debugging. Double check before removing. from xml.dom.minidom import parseString as parse_xml_string @@ -54,11 +54,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,7 +106,7 @@ 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 @@ -612,7 +612,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 @@ -630,7 +630,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): @@ -849,7 +849,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')) @@ -895,7 +895,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") @@ -915,14 +915,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) @@ -973,7 +973,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 @@ -1116,7 +1116,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( @@ -1630,7 +1630,7 @@ class App(QtCore.QObject): 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)) @@ -1700,7 +1700,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.") @@ -1727,7 +1727,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.") @@ -1754,7 +1754,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.") @@ -1781,7 +1781,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.") @@ -1831,7 +1831,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.") @@ -1854,7 +1854,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.") @@ -1897,7 +1897,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') @@ -2031,7 +2031,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)) @@ -2332,7 +2332,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)) @@ -3584,7 +3584,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' @@ -3638,7 +3638,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): @@ -4132,11 +4132,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 = { @@ -4225,12 +4225,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.") @@ -4239,7 +4239,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)) @@ -4257,7 +4257,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:

" + "" + data["name"] + "
" + data["message"].replace("\n", "
")), diff --git a/FlatCAMDraw.py b/FlatCAMDraw.py index 57c1fdb6..67148e58 100644 --- a/FlatCAMDraw.py +++ b/FlatCAMDraw.py @@ -693,23 +693,23 @@ class FlatCAMDraw(QtCore.QObject): self.drawing_toolbar = QtGui.QToolBar() self.drawing_toolbar.setDisabled(disabled) self.app.ui.addToolBar(self.drawing_toolbar) - self.select_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share:pointer32.png'), "Select 'Esc'") - self.add_circle_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share:circle32.png'), 'Add Circle') - self.add_arc_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share:arc32.png'), 'Add Arc') - self.add_rectangle_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share:rectangle32.png'), 'Add Rectangle') - self.add_polygon_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share:polygon32.png'), 'Add Polygon') - self.add_path_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share:path32.png'), 'Add Path') - self.union_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share:union32.png'), 'Polygon Union') - self.intersection_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share:intersection32.png'), 'Polygon Intersection') - self.subtract_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share:subtract32.png'), 'Polygon Subtraction') - self.cutpath_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share:cutpath32.png'), 'Cut Path') - self.move_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share:move32.png'), "Move Objects 'm'") - self.copy_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share:copy32.png'), "Copy Objects 'c'") - self.delete_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share:deleteshape32.png'), "Delete Shape '-'") + self.select_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share/pointer32.png'), "Select 'Esc'") + self.add_circle_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share/circle32.png'), 'Add Circle') + self.add_arc_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share/arc32.png'), 'Add Arc') + self.add_rectangle_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share/rectangle32.png'), 'Add Rectangle') + self.add_polygon_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share/polygon32.png'), 'Add Polygon') + self.add_path_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share/path32.png'), 'Add Path') + self.union_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share/union32.png'), 'Polygon Union') + self.intersection_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share/intersection32.png'), 'Polygon Intersection') + self.subtract_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share/subtract32.png'), 'Polygon Subtraction') + self.cutpath_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share/cutpath32.png'), 'Cut Path') + self.move_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share/move32.png'), "Move Objects 'm'") + self.copy_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share/copy32.png'), "Copy Objects 'c'") + self.delete_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share/deleteshape32.png'), "Delete Shape '-'") ### Snap Toolbar ### self.snap_toolbar = QtGui.QToolBar() - self.grid_snap_btn = self.snap_toolbar.addAction(QtGui.QIcon('share:grid32.png'), 'Snap to grid') + self.grid_snap_btn = self.snap_toolbar.addAction(QtGui.QIcon('share/grid32.png'), 'Snap to grid') self.grid_gap_x_entry = QtGui.QLineEdit() self.grid_gap_x_entry.setMaximumWidth(70) self.grid_gap_x_entry.setToolTip("Grid X distance") @@ -719,7 +719,7 @@ class FlatCAMDraw(QtCore.QObject): self.grid_gap_y_entry.setToolTip("Grid Y distante") self.snap_toolbar.addWidget(self.grid_gap_y_entry) - self.corner_snap_btn = self.snap_toolbar.addAction(QtGui.QIcon('share:corner32.png'), 'Snap to corner') + self.corner_snap_btn = self.snap_toolbar.addAction(QtGui.QIcon('share/corner32.png'), 'Snap to corner') self.snap_max_dist_entry = QtGui.QLineEdit() self.snap_max_dist_entry.setMaximumWidth(70) self.snap_max_dist_entry.setToolTip("Max. magnet distance") @@ -731,21 +731,21 @@ class FlatCAMDraw(QtCore.QObject): ### Application menu ### self.menu = QtGui.QMenu("Drawing") self.app.ui.menu.insertMenu(self.app.ui.menutoolaction, self.menu) - # self.select_menuitem = self.menu.addAction(QtGui.QIcon('share:pointer16.png'), "Select 'Esc'") - # self.add_circle_menuitem = self.menu.addAction(QtGui.QIcon('share:circle16.png'), 'Add Circle') - # self.add_arc_menuitem = self.menu.addAction(QtGui.QIcon('share:arc16.png'), 'Add Arc') - # self.add_rectangle_menuitem = self.menu.addAction(QtGui.QIcon('share:rectangle16.png'), 'Add Rectangle') - # self.add_polygon_menuitem = self.menu.addAction(QtGui.QIcon('share:polygon16.png'), 'Add Polygon') - # self.add_path_menuitem = self.menu.addAction(QtGui.QIcon('share:path16.png'), 'Add Path') - self.union_menuitem = self.menu.addAction(QtGui.QIcon('share:union16.png'), 'Polygon Union') - self.intersection_menuitem = self.menu.addAction(QtGui.QIcon('share:intersection16.png'), 'Polygon Intersection') - # self.subtract_menuitem = self.menu.addAction(QtGui.QIcon('share:subtract16.png'), 'Polygon Subtraction') - self.cutpath_menuitem = self.menu.addAction(QtGui.QIcon('share:cutpath16.png'), 'Cut Path') - # self.move_menuitem = self.menu.addAction(QtGui.QIcon('share:move16.png'), "Move Objects 'm'") - # self.copy_menuitem = self.menu.addAction(QtGui.QIcon('share:copy16.png'), "Copy Objects 'c'") - self.delete_menuitem = self.menu.addAction(QtGui.QIcon('share:deleteshape16.png'), "Delete Shape '-'") - self.buffer_menuitem = self.menu.addAction(QtGui.QIcon('share:buffer16.png'), "Buffer selection 'b'") - self.paint_menuitem = self.menu.addAction(QtGui.QIcon('share:paint16.png'), "Paint selection") + # self.select_menuitem = self.menu.addAction(QtGui.QIcon('share/pointer16.png'), "Select 'Esc'") + # self.add_circle_menuitem = self.menu.addAction(QtGui.QIcon('share/circle16.png'), 'Add Circle') + # self.add_arc_menuitem = self.menu.addAction(QtGui.QIcon('share/arc16.png'), 'Add Arc') + # self.add_rectangle_menuitem = self.menu.addAction(QtGui.QIcon('share/rectangle16.png'), 'Add Rectangle') + # self.add_polygon_menuitem = self.menu.addAction(QtGui.QIcon('share/polygon16.png'), 'Add Polygon') + # self.add_path_menuitem = self.menu.addAction(QtGui.QIcon('share/path16.png'), 'Add Path') + self.union_menuitem = self.menu.addAction(QtGui.QIcon('share/union16.png'), 'Polygon Union') + self.intersection_menuitem = self.menu.addAction(QtGui.QIcon('share/intersection16.png'), 'Polygon Intersection') + # self.subtract_menuitem = self.menu.addAction(QtGui.QIcon('share/subtract16.png'), 'Polygon Subtraction') + self.cutpath_menuitem = self.menu.addAction(QtGui.QIcon('share/cutpath16.png'), 'Cut Path') + # self.move_menuitem = self.menu.addAction(QtGui.QIcon('share/move16.png'), "Move Objects 'm'") + # self.copy_menuitem = self.menu.addAction(QtGui.QIcon('share/copy16.png'), "Copy Objects 'c'") + self.delete_menuitem = self.menu.addAction(QtGui.QIcon('share/deleteshape16.png'), "Delete Shape '-'") + self.buffer_menuitem = self.menu.addAction(QtGui.QIcon('share/buffer16.png'), "Buffer selection 'b'") + self.paint_menuitem = self.menu.addAction(QtGui.QIcon('share/paint16.png'), "Paint selection") self.menu.addSeparator() self.paint_menuitem.triggered.connect(self.on_paint_tool) @@ -1473,7 +1473,7 @@ class FlatCAMDraw(QtCore.QObject): for param in [tooldia, overlap, margin]: if not isinstance(param, float): - param_name = [k for k, v in locals().iteritems() if v is param][0] + param_name = [k for k, v in list(locals().items()) if v is param][0] self.app.inform.emit("[warning] Invalid value for {}".format()) # Todo: Check for valid method. diff --git a/FlatCAMGUI.py b/FlatCAMGUI.py index bba9875b..c8a1275b 100644 --- a/FlatCAMGUI.py +++ b/FlatCAMGUI.py @@ -28,55 +28,55 @@ class FlatCAMGUI(QtGui.QMainWindow): self.menufile = self.menu.addMenu('&File') # New - self.menufilenew = QtGui.QAction(QtGui.QIcon('share:file16.png'), '&New', self) + self.menufilenew = QtGui.QAction(QtGui.QIcon('share/file16.png'), '&New', self) self.menufile.addAction(self.menufilenew) # Open recent # Recent - self.recent = self.menufile.addMenu(QtGui.QIcon('share:folder16.png'), "Open recent ...") + self.recent = self.menufile.addMenu(QtGui.QIcon('share/folder16.png'), "Open recent ...") # Open gerber ... - self.menufileopengerber = QtGui.QAction(QtGui.QIcon('share:folder16.png'), 'Open &Gerber ...', self) + self.menufileopengerber = QtGui.QAction(QtGui.QIcon('share/folder16.png'), 'Open &Gerber ...', self) self.menufile.addAction(self.menufileopengerber) # Open Excellon ... - self.menufileopenexcellon = QtGui.QAction(QtGui.QIcon('share:folder16.png'), 'Open &Excellon ...', self) + self.menufileopenexcellon = QtGui.QAction(QtGui.QIcon('share/folder16.png'), 'Open &Excellon ...', self) self.menufile.addAction(self.menufileopenexcellon) # Open G-Code ... - self.menufileopengcode = QtGui.QAction(QtGui.QIcon('share:folder16.png'), 'Open G-&Code ...', self) + self.menufileopengcode = QtGui.QAction(QtGui.QIcon('share/folder16.png'), 'Open G-&Code ...', self) self.menufile.addAction(self.menufileopengcode) # Open Project ... - self.menufileopenproject = QtGui.QAction(QtGui.QIcon('share:folder16.png'), 'Open &Project ...', self) + self.menufileopenproject = QtGui.QAction(QtGui.QIcon('share/folder16.png'), 'Open &Project ...', self) self.menufile.addAction(self.menufileopenproject) # Import SVG ... - self.menufileimportsvg = QtGui.QAction(QtGui.QIcon('share:folder16.png'), 'Import &SVG ...', self) + self.menufileimportsvg = QtGui.QAction(QtGui.QIcon('share/folder16.png'), 'Import &SVG ...', self) self.menufile.addAction(self.menufileimportsvg) # Export SVG ... - self.menufileexportsvg = QtGui.QAction(QtGui.QIcon('share:folder16.png'), 'Export &SVG ...', self) + self.menufileexportsvg = QtGui.QAction(QtGui.QIcon('share/folder16.png'), 'Export &SVG ...', self) self.menufile.addAction(self.menufileexportsvg) # Save Project - self.menufilesaveproject = QtGui.QAction(QtGui.QIcon('share:floppy16.png'), '&Save Project', self) + self.menufilesaveproject = QtGui.QAction(QtGui.QIcon('share/floppy16.png'), '&Save Project', self) self.menufile.addAction(self.menufilesaveproject) # Save Project As ... - self.menufilesaveprojectas = QtGui.QAction(QtGui.QIcon('share:floppy16.png'), 'Save Project &As ...', self) + self.menufilesaveprojectas = QtGui.QAction(QtGui.QIcon('share/floppy16.png'), 'Save Project &As ...', self) self.menufile.addAction(self.menufilesaveprojectas) # Save Project Copy ... - self.menufilesaveprojectcopy = QtGui.QAction(QtGui.QIcon('share:floppy16.png'), 'Save Project C&opy ...', self) + self.menufilesaveprojectcopy = QtGui.QAction(QtGui.QIcon('share/floppy16.png'), 'Save Project C&opy ...', self) self.menufile.addAction(self.menufilesaveprojectcopy) # Save Defaults - self.menufilesavedefaults = QtGui.QAction(QtGui.QIcon('share:floppy16.png'), 'Save &Defaults', self) + self.menufilesavedefaults = QtGui.QAction(QtGui.QIcon('share/floppy16.png'), 'Save &Defaults', self) self.menufile.addAction(self.menufilesavedefaults) # Quit - self.exit_action = QtGui.QAction(QtGui.QIcon('share:power16.png'), '&Exit', self) + self.exit_action = QtGui.QAction(QtGui.QIcon('share/power16.png'), '&Exit', self) # exitAction.setShortcut('Ctrl+Q') # exitAction.setStatusTip('Exit application') #self.exit_action.triggered.connect(QtGui.qApp.quit) @@ -85,13 +85,13 @@ class FlatCAMGUI(QtGui.QMainWindow): ### Edit ### self.menuedit = self.menu.addMenu('&Edit') - self.menueditnew = self.menuedit.addAction(QtGui.QIcon('share:new_geo16.png'), 'New Geometry') - self.menueditedit = self.menuedit.addAction(QtGui.QIcon('share:edit16.png'), 'Edit Geometry') - self.menueditok = self.menuedit.addAction(QtGui.QIcon('share:edit_ok16.png'), 'Update Geometry') + self.menueditnew = self.menuedit.addAction(QtGui.QIcon('share/new_geo16.png'), 'New Geometry') + self.menueditedit = self.menuedit.addAction(QtGui.QIcon('share/edit16.png'), 'Edit Geometry') + self.menueditok = self.menuedit.addAction(QtGui.QIcon('share/edit_ok16.png'), 'Update Geometry') #self.menueditok. - #self.menueditcancel = self.menuedit.addAction(QtGui.QIcon('share:cancel_edit16.png'), "Cancel Edit") - self.menueditjoin = self.menuedit.addAction(QtGui.QIcon('share:join16.png'), 'Join Geometry') - self.menueditdelete = self.menuedit.addAction(QtGui.QIcon('share:trash16.png'), 'Delete') + #self.menueditcancel = self.menuedit.addAction(QtGui.QIcon('share/cancel_edit16.png'), "Cancel Edit") + self.menueditjoin = self.menuedit.addAction(QtGui.QIcon('share/join16.png'), 'Join Geometry') + self.menueditdelete = self.menuedit.addAction(QtGui.QIcon('share/trash16.png'), 'Delete') ### Options ### self.menuoptions = self.menu.addMenu('&Options') @@ -105,22 +105,22 @@ class FlatCAMGUI(QtGui.QMainWindow): ### View ### self.menuview = self.menu.addMenu('&View') - self.menuviewdisableall = self.menuview.addAction(QtGui.QIcon('share:clear_plot16.png'), 'Disable all plots') - self.menuviewdisableother = self.menuview.addAction(QtGui.QIcon('share:clear_plot16.png'), + self.menuviewdisableall = self.menuview.addAction(QtGui.QIcon('share/clear_plot16.png'), 'Disable all plots') + self.menuviewdisableother = self.menuview.addAction(QtGui.QIcon('share/clear_plot16.png'), 'Disable all plots but this one') - self.menuviewenable = self.menuview.addAction(QtGui.QIcon('share:replot16.png'), 'Enable all plots') + self.menuviewenable = self.menuview.addAction(QtGui.QIcon('share/replot16.png'), 'Enable all plots') ### Tool ### #self.menutool = self.menu.addMenu('&Tool') self.menutool = QtGui.QMenu('&Tool') self.menutoolaction = self.menu.addMenu(self.menutool) - self.menutoolshell = self.menutool.addAction(QtGui.QIcon('share:shell16.png'), '&Command Line') + self.menutoolshell = self.menutool.addAction(QtGui.QIcon('share/shell16.png'), '&Command Line') ### Help ### self.menuhelp = self.menu.addMenu('&Help') - self.menuhelp_about = self.menuhelp.addAction(QtGui.QIcon('share:tv16.png'), 'About FlatCAM') - self.menuhelp_home = self.menuhelp.addAction(QtGui.QIcon('share:home16.png'), 'Home') - self.menuhelp_manual = self.menuhelp.addAction(QtGui.QIcon('share:globe16.png'), 'Manual') + self.menuhelp_about = self.menuhelp.addAction(QtGui.QIcon('share/tv16.png'), 'About FlatCAM') + self.menuhelp_home = self.menuhelp.addAction(QtGui.QIcon('share/home16.png'), 'Home') + self.menuhelp_manual = self.menuhelp.addAction(QtGui.QIcon('share/globe16.png'), 'Manual') ############### ### Toolbar ### @@ -128,18 +128,18 @@ class FlatCAMGUI(QtGui.QMainWindow): self.toolbar = QtGui.QToolBar() self.addToolBar(self.toolbar) - self.zoom_fit_btn = self.toolbar.addAction(QtGui.QIcon('share:zoom_fit32.png'), "&Zoom Fit") - self.zoom_out_btn = self.toolbar.addAction(QtGui.QIcon('share:zoom_out32.png'), "&Zoom Out") - self.zoom_in_btn = self.toolbar.addAction(QtGui.QIcon('share:zoom_in32.png'), "&Zoom In") - self.clear_plot_btn = self.toolbar.addAction(QtGui.QIcon('share:clear_plot32.png'), "&Clear Plot") - self.replot_btn = self.toolbar.addAction(QtGui.QIcon('share:replot32.png'), "&Replot") - self.newgeo_btn = self.toolbar.addAction(QtGui.QIcon('share:new_geo32.png'), "New Blank Geometry") - self.editgeo_btn = self.toolbar.addAction(QtGui.QIcon('share:edit32.png'), "Edit Geometry") - self.updategeo_btn = self.toolbar.addAction(QtGui.QIcon('share:edit_ok32.png'), "Update Geometry") + self.zoom_fit_btn = self.toolbar.addAction(QtGui.QIcon('share/zoom_fit32.png'), "&Zoom Fit") + self.zoom_out_btn = self.toolbar.addAction(QtGui.QIcon('share/zoom_out32.png'), "&Zoom Out") + self.zoom_in_btn = self.toolbar.addAction(QtGui.QIcon('share/zoom_in32.png'), "&Zoom In") + self.clear_plot_btn = self.toolbar.addAction(QtGui.QIcon('share/clear_plot32.png'), "&Clear Plot") + self.replot_btn = self.toolbar.addAction(QtGui.QIcon('share/replot32.png'), "&Replot") + self.newgeo_btn = self.toolbar.addAction(QtGui.QIcon('share/new_geo32.png'), "New Blank Geometry") + self.editgeo_btn = self.toolbar.addAction(QtGui.QIcon('share/edit32.png'), "Edit Geometry") + self.updategeo_btn = self.toolbar.addAction(QtGui.QIcon('share/edit_ok32.png'), "Update Geometry") self.updategeo_btn.setEnabled(False) - #self.canceledit_btn = self.toolbar.addAction(QtGui.QIcon('share:cancel_edit32.png'), "Cancel Edit") - self.delete_btn = self.toolbar.addAction(QtGui.QIcon('share:delete32.png'), "&Delete") - self.shell_btn = self.toolbar.addAction(QtGui.QIcon('share:shell32.png'), "&Command Line") + #self.canceledit_btn = self.toolbar.addAction(QtGui.QIcon('share/cancel_edit32.png'), "Cancel Edit") + self.delete_btn = self.toolbar.addAction(QtGui.QIcon('share/delete32.png'), "&Delete") + self.shell_btn = self.toolbar.addAction(QtGui.QIcon('share/shell32.png'), "&Command Line") ################ ### Splitter ### @@ -179,7 +179,7 @@ class FlatCAMGUI(QtGui.QMainWindow): self.options_tab_layout.addLayout(hlay1) self.icon = QtGui.QLabel() - self.icon.setPixmap(QtGui.QPixmap('share:gear48.png')) + self.icon.setPixmap(QtGui.QPixmap('share/gear48.png')) hlay1.addWidget(self.icon) self.options_combo = QtGui.QComboBox() @@ -247,12 +247,12 @@ class FlatCAMGUI(QtGui.QMainWindow): ### Icons ### ############# self.app_icon = QtGui.QIcon() - self.app_icon.addFile('share:flatcam_icon16.png', QtCore.QSize(16, 16)) - self.app_icon.addFile('share:flatcam_icon24.png', QtCore.QSize(24, 24)) - self.app_icon.addFile('share:flatcam_icon32.png', QtCore.QSize(32, 32)) - self.app_icon.addFile('share:flatcam_icon48.png', QtCore.QSize(48, 48)) - self.app_icon.addFile('share:flatcam_icon128.png', QtCore.QSize(128, 128)) - self.app_icon.addFile('share:flatcam_icon256.png', QtCore.QSize(256, 256)) + self.app_icon.addFile('share/flatcam_icon16.png', QtCore.QSize(16, 16)) + self.app_icon.addFile('share/flatcam_icon24.png', QtCore.QSize(24, 24)) + self.app_icon.addFile('share/flatcam_icon32.png', QtCore.QSize(32, 32)) + self.app_icon.addFile('share/flatcam_icon48.png', QtCore.QSize(48, 48)) + self.app_icon.addFile('share/flatcam_icon128.png', QtCore.QSize(128, 128)) + self.app_icon.addFile('share/flatcam_icon256.png', QtCore.QSize(256, 256)) self.setWindowIcon(self.app_icon) self.setGeometry(100, 100, 1024, 650) @@ -278,7 +278,7 @@ class FlatCAMActivityView(QtGui.QWidget): self.icon = QtGui.QLabel(self) self.icon.setGeometry(0, 0, 12, 12) - self.movie = QtGui.QMovie("share:active.gif") + self.movie = QtGui.QMovie("share/active.gif") self.icon.setMovie(self.movie) #self.movie.start() @@ -309,7 +309,7 @@ class FlatCAMInfoBar(QtGui.QWidget): self.icon = QtGui.QLabel(self) self.icon.setGeometry(0, 0, 12, 12) - self.pmap = QtGui.QPixmap('share:graylight12.png') + self.pmap = QtGui.QPixmap('share/graylight12.png') self.icon.setPixmap(self.pmap) layout = QtGui.QHBoxLayout() @@ -334,13 +334,13 @@ class FlatCAMInfoBar(QtGui.QWidget): level = str(level) self.pmap.fill() if level == "error": - self.pmap = QtGui.QPixmap('share:redlight12.png') + self.pmap = QtGui.QPixmap('share/redlight12.png') elif level == "success": - self.pmap = QtGui.QPixmap('share:greenlight12.png') + self.pmap = QtGui.QPixmap('share/greenlight12.png') elif level == "warning": - self.pmap = QtGui.QPixmap('share:yellowlight12.png') + self.pmap = QtGui.QPixmap('share/yellowlight12.png') else: - self.pmap = QtGui.QPixmap('share:graylight12.png') + self.pmap = QtGui.QPixmap('share/graylight12.png') self.icon.setPixmap(self.pmap) self.set_text_(text) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index f37ff471..2464e955 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -6,7 +6,7 @@ # MIT Licence # ############################################################ -from cStringIO import StringIO +from io import StringIO from PyQt4 import QtCore from copy import copy from ObjectUI import * @@ -511,15 +511,16 @@ class FlatCAMGerber(FlatCAMObj, Gerber): # to cut on the right side of the left over copper i.e on the left side of the features. geom = self.isolation_geometry(offset) if invert: - if type(geom) is MultiPolygon: - pl = [] - for p in geom: - pl.append(Polygon(p.exterior.coords[::-1], p.interiors)) - geom = MultiPolygon(pl) - elif type(geom) is Polygon: - geom = Polygon(geom.exterior.coords[::-1], geom.interiors) - else: - raise "Unexpected Geometry" + try: + if type(geom) is MultiPolygon: + pl = [] + for p in geom: + pl.append(Polygon(p.exterior.coords[::-1], p.interiors)) + geom = MultiPolygon(pl) + elif type(geom) is Polygon: + geom = Polygon(geom.exterior.coords[::-1], geom.interiors) + except Exception as e: + str("Unexpected Geometry") return geom if combine: @@ -728,20 +729,20 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): exc_final.drills.append({"point": point, "tool": drill['tool']}) toolsrework=dict() max_numeric_tool=0 - for toolname in exc.tools.iterkeys(): + for toolname in list(exc.tools.keys()): numeric_tool=int(toolname) if numeric_tool>max_numeric_tool: max_numeric_tool=numeric_tool toolsrework[exc.tools[toolname]['C']]=toolname #exc_final as last because names from final tools will be used - for toolname in exc_final.tools.iterkeys(): + for toolname in list(exc_final.tools.keys()): numeric_tool=int(toolname) if numeric_tool>max_numeric_tool: max_numeric_tool=numeric_tool toolsrework[exc_final.tools[toolname]['C']]=toolname - for toolvalues in toolsrework.iterkeys(): + for toolvalues in list(toolsrework.keys()): if toolsrework[toolvalues] in exc_final.tools: if exc_final.tools[toolsrework[toolvalues]]!={"C": toolvalues}: exc_final.tools[str(max_numeric_tool+1)]={"C": toolvalues} @@ -846,7 +847,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): tooldia = self.options["tooldia"] # Sort tools by diameter. items() -> [('name', diameter), ...] - sorted_tools = sorted(self.tools.items(), key=lambda tl: tl[1]) + sorted_tools = sorted(list(self.tools.items()), key=lambda tl: tl[1]) if tools == "all": tools = [i[0] for i in sorted_tools] # List if ordered tool names. @@ -1066,10 +1067,10 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob): self.read_form() try: - filename = unicode(QtGui.QFileDialog.getSaveFileName(caption="Export G-Code ...", + filename = str(QtGui.QFileDialog.getSaveFileName(caption="Export G-Code ...", directory=self.app.defaults["last_folder"])) except TypeError: - filename = unicode(QtGui.QFileDialog.getSaveFileName(caption="Export G-Code ...")) + filename = str(QtGui.QFileDialog.getSaveFileName(caption="Export G-Code ...")) preamble = str(self.ui.prepend_text.get_value()) postamble = str(self.ui.append_text.get_value()) @@ -1351,9 +1352,9 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): geo_obj.options["cnctooldia"] = tooldia # Experimental... - print "Indexing...", + print("Indexing...") geo_obj.make_index() - print "Done" + print("Done") self.app.inform.emit("Done.") @@ -1437,9 +1438,9 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): geo_obj.options["cnctooldia"] = tooldia # Experimental... - print "Indexing...", + print("Indexing...") geo_obj.make_index() - print "Done" + print("Done") self.app.inform.emit("Done.") diff --git a/GUIElements.py b/GUIElements.py index c2b728d6..b962248f 100644 --- a/GUIElements.py +++ b/GUIElements.py @@ -81,7 +81,7 @@ class LengthEntry(QtGui.QLineEdit): def returnPressed(self, *args, **kwargs): val = self.get_value() if val is not None: - self.set_text(QtCore.QString(str(val))) + self.set_text(str(val)) else: log.warning("Could not interpret entry: %s" % self.get_text()) @@ -105,7 +105,7 @@ class LengthEntry(QtGui.QLineEdit): return None def set_value(self, val): - self.setText(QtCore.QString(str(val))) + self.setText(str(val)) class FloatEntry(QtGui.QLineEdit): @@ -115,7 +115,7 @@ class FloatEntry(QtGui.QLineEdit): def returnPressed(self, *args, **kwargs): val = self.get_value() if val is not None: - self.set_text(QtCore.QString(str(val))) + self.set_text(str(val)) else: log.warning("Could not interpret entry: %s" % self.text()) @@ -151,10 +151,10 @@ class IntEntry(QtGui.QLineEdit): def set_value(self, val): if val == self.empty_val and self.allow_empty: - self.setText(QtCore.QString("")) + self.setText("") return - self.setText(QtCore.QString(str(val))) + self.setText(str(val)) class FCEntry(QtGui.QLineEdit): @@ -165,7 +165,7 @@ class FCEntry(QtGui.QLineEdit): return str(self.text()) def set_value(self, val): - self.setText(QtCore.QString(str(val))) + self.setText(str(val)) class EvalEntry(QtGui.QLineEdit): @@ -175,7 +175,7 @@ class EvalEntry(QtGui.QLineEdit): def returnPressed(self, *args, **kwargs): val = self.get_value() if val is not None: - self.setText(QtCore.QString(str(val))) + self.setText(str(val)) else: log.warning("Could not interpret entry: %s" % self.get_text()) @@ -188,12 +188,12 @@ class EvalEntry(QtGui.QLineEdit): return None def set_value(self, val): - self.setText(QtCore.QString(str(val))) + self.setText(str(val)) class FCCheckBox(QtGui.QCheckBox): def __init__(self, label='', parent=None): - super(FCCheckBox, self).__init__(QtCore.QString(label), parent) + super(FCCheckBox, self).__init__(str(label), parent) def get_value(self): return self.isChecked() diff --git a/ObjectCollection.py b/ObjectCollection.py index 82ccef5b..211c5a82 100644 --- a/ObjectCollection.py +++ b/ObjectCollection.py @@ -39,10 +39,10 @@ class ObjectCollection(): } icon_files = { - "gerber": "share:flatcam_icon16.png", - "excellon": "share:drill16.png", - "cncjob": "share:cnc16.png", - "geometry": "share:geometry16.png" + "gerber": "share/flatcam_icon16.png", + "excellon": "share/drill16.png", + "cncjob": "share/cnc16.png", + "geometry": "share/geometry16.png" } def __init__(self, parent=None): @@ -102,7 +102,7 @@ class ObjectCollection(): def print_list(self): for obj in self.object_list: - print obj + print(obj) def on_mouse_down(self, event): FlatCAMApp.App.log.debug("Mouse button pressed on list") diff --git a/ObjectUI.py b/ObjectUI.py index 1bf20bf7..2211126b 100644 --- a/ObjectUI.py +++ b/ObjectUI.py @@ -11,7 +11,7 @@ class ObjectUI(QtGui.QWidget): put UI elements in ObjectUI.custom_box (QtGui.QLayout). """ - def __init__(self, icon_file='share:flatcam_icon32.png', title='FlatCAM Object', parent=None): + def __init__(self, icon_file='share/flatcam_icon32.png', title='FlatCAM Object', parent=None): QtGui.QWidget.__init__(self, parent=parent) layout = QtGui.QVBoxLayout() @@ -117,7 +117,7 @@ class CNCObjectUI(ObjectUI): be placed in ``self.custom_box`` to preserve the layout. """ - ObjectUI.__init__(self, title='CNC Job Object', icon_file='share:cnc32.png', parent=parent) + ObjectUI.__init__(self, title='CNC Job Object', icon_file='share/cnc32.png', parent=parent) # Scale and offset are not available for CNCJob objects. # Hiding from the GUI. @@ -231,7 +231,7 @@ class GeometryObjectUI(ObjectUI): """ def __init__(self, parent=None): - super(GeometryObjectUI, self).__init__(title='Geometry Object', icon_file='share:geometry32.png', parent=parent) + super(GeometryObjectUI, self).__init__(title='Geometry Object', icon_file='share/geometry32.png', parent=parent) ## Plot options self.plot_options_label = QtGui.QLabel("Plot Options:") @@ -450,7 +450,7 @@ class ExcellonObjectUI(ObjectUI): def __init__(self, parent=None): ObjectUI.__init__(self, title='Excellon Object', - icon_file='share:drill32.png', + icon_file='share/drill32.png', parent=parent) #### Plot options #### diff --git a/bugs/conf.py b/bugs/conf.py index df9a4b50..4a4f0c0e 100644 --- a/bugs/conf.py +++ b/bugs/conf.py @@ -43,8 +43,8 @@ source_suffix = '.rst' master_doc = 'index' # General information about the project. -project = u'FlatCAM Bugs' -copyright = u'2014, Juan Pablo Caram' +project = 'FlatCAM Bugs' +copyright = '2014, Juan Pablo Caram' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -196,8 +196,8 @@ latex_elements = { # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - ('index', 'FlatCAMBugs.tex', u'FlatCAM Bugs Documentation', - u'Juan Pablo Caram', 'manual'), + ('index', 'FlatCAMBugs.tex', 'FlatCAM Bugs Documentation', + 'Juan Pablo Caram', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of @@ -226,8 +226,8 @@ latex_documents = [ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'flatcambugs', u'FlatCAM Bugs Documentation', - [u'Juan Pablo Caram'], 1) + ('index', 'flatcambugs', 'FlatCAM Bugs Documentation', + ['Juan Pablo Caram'], 1) ] # If true, show URL addresses after external links. @@ -240,8 +240,8 @@ man_pages = [ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'FlatCAMBugs', u'FlatCAM Bugs Documentation', - u'Juan Pablo Caram', 'FlatCAMBugs', 'One line description of project.', + ('index', 'FlatCAMBugs', 'FlatCAM Bugs Documentation', + 'Juan Pablo Caram', 'FlatCAMBugs', 'One line description of project.', 'Miscellaneous'), ] diff --git a/camlib.py b/camlib.py index d79b4532..0ab1190e 100644 --- a/camlib.py +++ b/camlib.py @@ -9,7 +9,7 @@ #from scipy import optimize #import traceback -from cStringIO import StringIO +from io import StringIO from numpy import arctan2, Inf, array, sqrt, pi, ceil, sin, cos, dot, float32, \ transpose from numpy.linalg import solve, norm @@ -2360,7 +2360,7 @@ class Gerber (Geometry): else: self.solid_geometry = self.solid_geometry.difference(new_poly) - except Exception, err: + except Exception as err: ex_type, ex, tb = sys.exc_info() traceback.print_tb(tb) #print traceback.format_exc() @@ -2972,14 +2972,18 @@ class CNCjob(Geometry): # Tools # Sort tools by diameter. items() -> [('name', diameter), ...] - sorted_tools = sorted(exobj.tools.items(), key=lambda tl: tl[1]) + #sorted_tools = sorted(list(exobj.tools.items()), key=lambda tl: tl[1]) + sort = [] + for k, v in exobj.tools.items(): + sort.append((k, v.get('C'))) + sorted_tools = sorted(sort, key=lambda t1: t1[1]) if tools == "all": tools = [i[0] for i in sorted_tools] # List if ordered tool names. log.debug("Tools 'all' and sorted are: %s" % str(tools)) else: selected_tools = [x.strip() for x in tools.split(",")] - selected_tools = filter(lambda tl: tl in selected_tools, selected_tools) + selected_tools = [tl for tl in selected_tools if tl in selected_tools] # Create a sorted list of selected tools from the sorted_tools list tools = [i for i, j in sorted_tools for k in selected_tools if i == k] @@ -4103,7 +4107,7 @@ class FlatCAMRTree(object): :param pt: :return: """ - return self.rti.nearest(pt, objects=True).next() + return next(self.rti.nearest(pt, objects=True)) class FlatCAMRTreeStorage(FlatCAMRTree): diff --git a/descartes/tests.py b/descartes/tests.py index 8cb48b4f..d5f4e143 100644 --- a/descartes/tests.py +++ b/descartes/tests.py @@ -8,10 +8,10 @@ class PolygonTestCase(unittest.TestCase): MultiPoint([(-5, 0), (5, 0)]).buffer(3.0)) def test_patch(self): patch = PolygonPatch(self.polygon) - self.failUnlessEqual(str(type(patch)), + self.assertEqual(str(type(patch)), "") path = patch.get_path() - self.failUnless(len(path.vertices) == len(path.codes) == 198) + self.assertTrue(len(path.vertices) == len(path.codes) == 198) class JSONPolygonTestCase(unittest.TestCase): polygon = Point(0, 0).buffer(10.0).difference( @@ -19,10 +19,10 @@ class JSONPolygonTestCase(unittest.TestCase): def test_patch(self): geo = self.polygon.__geo_interface__ patch = PolygonPatch(geo) - self.failUnlessEqual(str(type(patch)), + self.assertEqual(str(type(patch)), "") path = patch.get_path() - self.failUnless(len(path.vertices) == len(path.codes) == 198) + self.assertTrue(len(path.vertices) == len(path.codes) == 198) class GeoInterfacePolygonTestCase(unittest.TestCase): class GeoThing: @@ -32,7 +32,7 @@ class GeoInterfacePolygonTestCase(unittest.TestCase): MultiPoint([(-5, 0), (5, 0)]).buffer(3.0)).__geo_interface__ def test_patch(self): patch = PolygonPatch(self.thing) - self.failUnlessEqual(str(type(patch)), + self.assertEqual(str(type(patch)), "") path = patch.get_path() - self.failUnless(len(path.vertices) == len(path.codes) == 198) + self.assertTrue(len(path.vertices) == len(path.codes) == 198) diff --git a/doc/source/conf.py b/doc/source/conf.py index 28920d89..0ea6194c 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -45,8 +45,8 @@ source_suffix = '.rst' master_doc = 'index' # General information about the project. -project = u'Cirkuix' -copyright = u'2014, Juan Pablo Caram' +project = 'Cirkuix' +copyright = '2014, Juan Pablo Caram' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -203,8 +203,8 @@ latex_elements = { # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - ('index', 'Cirkuix.tex', u'Cirkuix Documentation', - u'Juan Pablo Caram', 'manual'), + ('index', 'Cirkuix.tex', 'Cirkuix Documentation', + 'Juan Pablo Caram', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of @@ -233,8 +233,8 @@ latex_documents = [ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'cirkuix', u'Cirkuix Documentation', - [u'Juan Pablo Caram'], 1) + ('index', 'cirkuix', 'Cirkuix Documentation', + ['Juan Pablo Caram'], 1) ] # If true, show URL addresses after external links. @@ -247,8 +247,8 @@ man_pages = [ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'Cirkuix', u'Cirkuix Documentation', - u'Juan Pablo Caram', 'Cirkuix', 'One line description of project.', + ('index', 'Cirkuix', 'Cirkuix Documentation', + 'Juan Pablo Caram', 'Cirkuix', 'One line description of project.', 'Miscellaneous'), ] diff --git a/flatcam b/flatcam index 2a8b0356..3c5ef0bf 100755 --- a/flatcam +++ b/flatcam @@ -30,6 +30,6 @@ debug_trace() # NOTE: Never talk to the GUI from threads! This is why I commented the above. app = QtGui.QApplication(sys.argv) -QtCore.QDir.setSearchPaths("share", QtCore.QStringList(("share", "share/flatcam", "/usr/share/flatcam"))); +QtCore.QDir.setSearchPaths("share", str(("share", "share/flatcam", "/usr/share/flatcam"))); fc = App() sys.exit(app.exec_()) diff --git a/make_win32.py b/make_win32.py index 4ee6ef6f..9f998533 100644 --- a/make_win32.py +++ b/make_win32.py @@ -43,16 +43,16 @@ if sys.platform == "win32": buildOptions = dict( compressed=False, include_files=include_files, - icon='share:flatcam_icon48.ico', + icon='share/flatcam_icon48.ico', # excludes=['PyQt4', 'tk', 'tcl'] excludes=['scipy.lib.lapack.flapack.pyd', 'scipy.lib.blas.fblas.pyd', 'QtOpenGL4.dll'] ) -print "INCLUDE_FILES", include_files +print(("INCLUDE_FILES", include_files)) -execfile('clean.py') +exec(compile(open('clean.py').read(), 'clean.py', 'exec')) setup( name="FlatCAM", diff --git a/sandbox/diagnose.py b/sandbox/diagnose.py index 89618022..11a99b51 100644 --- a/sandbox/diagnose.py +++ b/sandbox/diagnose.py @@ -1,34 +1,34 @@ #import sys import platform -print "Platform", platform.system(), platform.release() -print "Distro", platform.dist() -print "Python", platform.python_version() +print(("Platform", platform.system(), platform.release())) +print(("Distro", platform.dist())) +print(("Python", platform.python_version())) import rtree -print "rtree", rtree.__version__ +print(("rtree", rtree.__version__)) import shapely import shapely.geos -print "shapely", shapely.__version__ -print "GEOS library", shapely.geos.geos_version +print(("shapely", shapely.__version__)) +print(("GEOS library", shapely.geos.geos_version)) from PyQt4 import Qt -print "Qt", Qt.qVersion() +print(("Qt", Qt.qVersion())) import numpy -print "Numpy", numpy.__version__ +print(("Numpy", numpy.__version__)) import matplotlib -print "MatPlotLib", matplotlib.__version__ -print "MPL Numpy", matplotlib.__version__numpy__ \ No newline at end of file +print(("MatPlotLib", matplotlib.__version__)) +print(("MPL Numpy", matplotlib.__version__numpy__)) \ No newline at end of file diff --git a/sandbox/gerber_find.py b/sandbox/gerber_find.py index e757c003..fdf38f2c 100644 --- a/sandbox/gerber_find.py +++ b/sandbox/gerber_find.py @@ -19,10 +19,10 @@ def gerber_find(filename, coords, frac_digits=5, tol=0.1): current_y = parse_gerber_number(match.group(3), frac_digits) if distance(coords, (current_x, current_y)) <= tol: - print line_num, ":", line.strip('\n\r') + print((line_num, ":", line.strip('\n\r'))) except Exception as e: - print str(e) - print line_num, ":", line.strip('\n\r') + print((str(e))) + print((line_num, ":", line.strip('\n\r'))) if __name__ == "__main__": diff --git a/svgparse.py b/svgparse.py index c24f64dd..1f401267 100644 --- a/svgparse.py +++ b/svgparse.py @@ -521,6 +521,6 @@ if __name__ == "__main__": tree = ET.parse('tests/svg/drawing.svg') root = tree.getroot() ns = re.search(r'\{(.*)\}', root.tag).group(1) - print ns + print(ns) for geo in getsvggeo(root): - print geo \ No newline at end of file + print(geo) \ No newline at end of file diff --git a/tclCommands/TclCommand.py b/tclCommands/TclCommand.py index 22f7438f..554d319e 100644 --- a/tclCommands/TclCommand.py +++ b/tclCommands/TclCommand.py @@ -97,7 +97,7 @@ class TclCommand(object): command_string = [] - for arg_key, arg_type in self.help['args'].items(): + for arg_key, arg_type in list(self.help['args'].items()): command_string.append(get_decorated_argument(arg_key, arg_type, True)) return "> " + alias_name + " " + " ".join(command_string) @@ -147,7 +147,7 @@ class TclCommand(object): for alias in self.aliases: help_string.append(get_decorated_command(alias)) - for key, value in self.help['args'].items(): + for key, value in list(self.help['args'].items()): help_string.append(get_decorated_argument(key, value)) # timeout is unique for signaled commands (this is not best oop practice, but much easier for now) @@ -206,13 +206,13 @@ class TclCommand(object): # check arguments idx = 0 - arg_names_items = self.arg_names.items() + arg_names_items = list(self.arg_names.items()) for argument in arguments: if len(self.arg_names) > idx: key, arg_type = arg_names_items[idx] try: named_args[key] = arg_type(argument) - except Exception, e: + except Exception as e: self.raise_tcl_error("Cannot cast named argument '%s' to type %s with exception '%s'." % (key, arg_type, str(e))) else: @@ -228,7 +228,7 @@ class TclCommand(object): named_args[key] = self.option_types[key](options[key]) else: named_args[key] = int(options[key]) - except Exception, e: + except Exception as e: self.raise_tcl_error("Cannot cast argument '-%s' to type '%s' with exception '%s'." % (key, self.option_types[key], str(e))) @@ -292,7 +292,7 @@ class TclCommandSignaled(TclCommand): """ !!! I left it here only for demonstration !!! Go to TclCommandCncjob and into class definition put - class TclCommandCncjob(TclCommand.TclCommandSignaled): + class TclCommandCncjob(TclCommandSignaled): also change obj.generatecncjob(use_thread = False, **args) to diff --git a/tclCommands/TclCommandAddCircle.py b/tclCommands/TclCommandAddCircle.py index 2d3a626e..a83777fa 100644 --- a/tclCommands/TclCommandAddCircle.py +++ b/tclCommands/TclCommandAddCircle.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommand -class TclCommandAddCircle(TclCommand.TclCommand): +class TclCommandAddCircle(TclCommand): """ Tcl shell command to creates a circle in the given Geometry object. diff --git a/tclCommands/TclCommandAddPolygon.py b/tclCommands/TclCommandAddPolygon.py index c9e35078..5c6d7923 100644 --- a/tclCommands/TclCommandAddPolygon.py +++ b/tclCommands/TclCommandAddPolygon.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommandSignaled -class TclCommandAddPolygon(TclCommand.TclCommandSignaled): +class TclCommandAddPolygon(TclCommandSignaled): """ Tcl shell command to create a polygon in the given Geometry object """ diff --git a/tclCommands/TclCommandAddPolyline.py b/tclCommands/TclCommandAddPolyline.py index 3c994760..18e58096 100644 --- a/tclCommands/TclCommandAddPolyline.py +++ b/tclCommands/TclCommandAddPolyline.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommandSignaled -class TclCommandAddPolyline(TclCommand.TclCommandSignaled): +class TclCommandAddPolyline(TclCommandSignaled): """ Tcl shell command to create a polyline in the given Geometry object """ diff --git a/tclCommands/TclCommandAddRectangle.py b/tclCommands/TclCommandAddRectangle.py index e5439aad..7b1e6b9f 100644 --- a/tclCommands/TclCommandAddRectangle.py +++ b/tclCommands/TclCommandAddRectangle.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommandSignaled -class TclCommandAddRectangle(TclCommand.TclCommandSignaled): +class TclCommandAddRectangle(TclCommandSignaled): """ Tcl shell command to add a rectange to the given Geometry object. """ diff --git a/tclCommands/TclCommandAlignDrill.py b/tclCommands/TclCommandAlignDrill.py index 54caca02..6fbaf7c0 100644 --- a/tclCommands/TclCommandAlignDrill.py +++ b/tclCommands/TclCommandAlignDrill.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommandSignaled -class TclCommandAlignDrill(TclCommand.TclCommandSignaled): +class TclCommandAlignDrill(TclCommandSignaled): """ Tcl shell command to create excellon with drills for aligment. """ @@ -180,7 +180,7 @@ class TclCommandAlignDrill(TclCommand.TclCommandSignaled): name + "_aligndrill", alligndrill_init_me) - except Exception, e: + except Exception as e: return "Operation failed: %s" % str(e) else: @@ -195,7 +195,7 @@ class TclCommandAlignDrill(TclCommand.TclCommandSignaled): px = dist py = dist obj.app.new_object("excellon", name + "_alligndrill", alligndrill_init_me) - except Exception, e: + except Exception as e: return "Operation failed: %s" % str(e) return 'Ok' diff --git a/tclCommands/TclCommandAlignDrillGrid.py b/tclCommands/TclCommandAlignDrillGrid.py index 34d70168..a90397b6 100644 --- a/tclCommands/TclCommandAlignDrillGrid.py +++ b/tclCommands/TclCommandAlignDrillGrid.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommandSignaled -class TclCommandAlignDrillGrid(TclCommand.TclCommandSignaled): +class TclCommandAlignDrillGrid(TclCommandSignaled): """ Tcl shell command to create an Excellon object with drills for aligment grid. diff --git a/tclCommands/TclCommandCncjob.py b/tclCommands/TclCommandCncjob.py index f914eb8f..773c7234 100644 --- a/tclCommands/TclCommandCncjob.py +++ b/tclCommands/TclCommandCncjob.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommandSignaled -class TclCommandCncjob(TclCommand.TclCommandSignaled): +class TclCommandCncjob(TclCommandSignaled): """ Tcl shell command to Generates a CNC Job from a Geometry Object. diff --git a/tclCommands/TclCommandCutout.py b/tclCommands/TclCommandCutout.py index c3057bae..40e83b01 100644 --- a/tclCommands/TclCommandCutout.py +++ b/tclCommands/TclCommandCutout.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommand -class TclCommandCutout(TclCommand.TclCommand): +class TclCommandCutout(TclCommand): """ Tcl shell command to create a board cutout geometry. @@ -95,5 +95,5 @@ class TclCommandCutout(TclCommand.TclCommand): try: obj.app.new_object("geometry", name + "_cutout", geo_init_me) - except Exception, e: + except Exception as e: return "Operation failed: %s" % str(e) diff --git a/tclCommands/TclCommandDelete.py b/tclCommands/TclCommandDelete.py index c4f3ab7b..455dfe60 100644 --- a/tclCommands/TclCommandDelete.py +++ b/tclCommands/TclCommandDelete.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommand -class TclCommandDelete(TclCommand.TclCommand): +class TclCommandDelete(TclCommand): """ Tcl shell command to delete an object. diff --git a/tclCommands/TclCommandDrillcncjob.py b/tclCommands/TclCommandDrillcncjob.py index b5eabbbb..2ecc451c 100644 --- a/tclCommands/TclCommandDrillcncjob.py +++ b/tclCommands/TclCommandDrillcncjob.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommandSignaled -class TclCommandDrillcncjob(TclCommand.TclCommandSignaled): +class TclCommandDrillcncjob(TclCommandSignaled): """ Tcl shell command to Generates a Drill CNC Job from a Excellon Object. """ diff --git a/tclCommands/TclCommandExportGcode.py b/tclCommands/TclCommandExportGcode.py index 6b262d4c..84d0b676 100644 --- a/tclCommands/TclCommandExportGcode.py +++ b/tclCommands/TclCommandExportGcode.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommandSignaled -class TclCommandExportGcode(TclCommand.TclCommandSignaled): +class TclCommandExportGcode(TclCommandSignaled): """ Tcl shell command to export gcode as tcl output for "set X [export_gcode ...]" diff --git a/tclCommands/TclCommandExportSVG.py b/tclCommands/TclCommandExportSVG.py index 986e92e7..7084e980 100644 --- a/tclCommands/TclCommandExportSVG.py +++ b/tclCommands/TclCommandExportSVG.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommand -class TclCommandExportSVG(TclCommand.TclCommand): +class TclCommandExportSVG(TclCommand): """ Tcl shell command to export a Geometry Object as an SVG File. diff --git a/tclCommands/TclCommandExteriors.py b/tclCommands/TclCommandExteriors.py index ac69e7cb..6c93bb59 100644 --- a/tclCommands/TclCommandExteriors.py +++ b/tclCommands/TclCommandExteriors.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommandSignaled -class TclCommandExteriors(TclCommand.TclCommandSignaled): +class TclCommandExteriors(TclCommandSignaled): """ Tcl shell command to get exteriors of polygons """ diff --git a/tclCommands/TclCommandGeoCutout.py b/tclCommands/TclCommandGeoCutout.py index 3e7ba317..1b905845 100644 --- a/tclCommands/TclCommandGeoCutout.py +++ b/tclCommands/TclCommandGeoCutout.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommandSignaled -class TclCommandGeoCutout(TclCommand.TclCommandSignaled): +class TclCommandGeoCutout(TclCommandSignaled): """ Tcl shell command to cut holding gaps from geometry. """ diff --git a/tclCommands/TclCommandGeoUnion.py b/tclCommands/TclCommandGeoUnion.py index c18ade7f..d0294e93 100644 --- a/tclCommands/TclCommandGeoUnion.py +++ b/tclCommands/TclCommandGeoUnion.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommand -class TclCommandGeoUnion(TclCommand.TclCommand): +class TclCommandGeoUnion(TclCommand): """ Tcl shell command to run a union (addition) operation on the components of a geometry object. diff --git a/tclCommands/TclCommandGetNames.py b/tclCommands/TclCommandGetNames.py index aa7ea3a3..db4524f0 100644 --- a/tclCommands/TclCommandGetNames.py +++ b/tclCommands/TclCommandGetNames.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommand -class TclCommandGetNames(TclCommand.TclCommand): +class TclCommandGetNames(TclCommand): """ Tcl shell command to set an object as active in the GUI. diff --git a/tclCommands/TclCommandGetSys.py b/tclCommands/TclCommandGetSys.py index 3bfeb99e..635decad 100644 --- a/tclCommands/TclCommandGetSys.py +++ b/tclCommands/TclCommandGetSys.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommand -class TclCommandGetSys(TclCommand.TclCommand): +class TclCommandGetSys(TclCommand): """ Tcl shell command to get the value of a system variable diff --git a/tclCommands/TclCommandImportSvg.py b/tclCommands/TclCommandImportSvg.py index 51cc1901..fa940439 100644 --- a/tclCommands/TclCommandImportSvg.py +++ b/tclCommands/TclCommandImportSvg.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommandSignaled -class TclCommandImportSvg(TclCommand.TclCommandSignaled): +class TclCommandImportSvg(TclCommandSignaled): """ Tcl shell command to import an SVG file as a Geometry Object. """ diff --git a/tclCommands/TclCommandInteriors.py b/tclCommands/TclCommandInteriors.py index 61bfe9f0..00a6a1a6 100644 --- a/tclCommands/TclCommandInteriors.py +++ b/tclCommands/TclCommandInteriors.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommandSignaled -class TclCommandInteriors(TclCommand.TclCommandSignaled): +class TclCommandInteriors(TclCommandSignaled): """ Tcl shell command to get interiors of polygons """ diff --git a/tclCommands/TclCommandIsolate.py b/tclCommands/TclCommandIsolate.py index f73aafa0..93ad41d0 100644 --- a/tclCommands/TclCommandIsolate.py +++ b/tclCommands/TclCommandIsolate.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommandSignaled -class TclCommandIsolate(TclCommand.TclCommandSignaled): +class TclCommandIsolate(TclCommandSignaled): """ Tcl shell command to Creates isolation routing geometry for the given Gerber. diff --git a/tclCommands/TclCommandJoinExcellon.py b/tclCommands/TclCommandJoinExcellon.py index 134df2aa..ef2654ca 100644 --- a/tclCommands/TclCommandJoinExcellon.py +++ b/tclCommands/TclCommandJoinExcellon.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommand -class TclCommandJoinExcellon(TclCommand.TclCommand): +class TclCommandJoinExcellon(TclCommand): """ Tcl shell command to merge Excellon objects. diff --git a/tclCommands/TclCommandJoinGeometry.py b/tclCommands/TclCommandJoinGeometry.py index 4da7beb1..90beac4f 100644 --- a/tclCommands/TclCommandJoinGeometry.py +++ b/tclCommands/TclCommandJoinGeometry.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommand -class TclCommandJoinGeometry(TclCommand.TclCommand): +class TclCommandJoinGeometry(TclCommand): """ Tcl shell command to merge Excellon objects. diff --git a/tclCommands/TclCommandMillHoles.py b/tclCommands/TclCommandMillHoles.py index 1ba800cf..88dbeb79 100644 --- a/tclCommands/TclCommandMillHoles.py +++ b/tclCommands/TclCommandMillHoles.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommandSignaled -class TclCommandMillHoles(TclCommand.TclCommandSignaled): +class TclCommandMillHoles(TclCommandSignaled): """ Tcl shell command to Create Geometry Object for milling holes from Excellon. diff --git a/tclCommands/TclCommandMirror.py b/tclCommands/TclCommandMirror.py index 33abbdcb..db7ec3c8 100644 --- a/tclCommands/TclCommandMirror.py +++ b/tclCommands/TclCommandMirror.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommandSignaled -class TclCommandMirror(TclCommand.TclCommandSignaled): +class TclCommandMirror(TclCommandSignaled): """ Tcl shell command to mirror an object. """ @@ -90,7 +90,7 @@ class TclCommandMirror(TclCommand.TclCommandSignaled): obj.mirror(axis, [px, py]) obj.plot() - except Exception, e: + except Exception as e: return "Operation failed: %s" % str(e) else: @@ -104,5 +104,5 @@ class TclCommandMirror(TclCommand.TclCommandSignaled): try: obj.mirror(axis, [dist, dist]) obj.plot() - except Exception, e: + except Exception as e: return "Operation failed: %s" % str(e) diff --git a/tclCommands/TclCommandNew.py b/tclCommands/TclCommandNew.py index 382fc86c..bf386d0c 100644 --- a/tclCommands/TclCommandNew.py +++ b/tclCommands/TclCommandNew.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommand -class TclCommandNew(TclCommand.TclCommand): +class TclCommandNew(TclCommand): """ Tcl shell command to starts a new project. Clears objects from memory """ diff --git a/tclCommands/TclCommandNewGeometry.py b/tclCommands/TclCommandNewGeometry.py index 3f757637..349f8842 100644 --- a/tclCommands/TclCommandNewGeometry.py +++ b/tclCommands/TclCommandNewGeometry.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommandSignaled -class TclCommandNewGeometry(TclCommand.TclCommandSignaled): +class TclCommandNewGeometry(TclCommandSignaled): """ Tcl shell command to subtract polygon from the given Geometry object. """ diff --git a/tclCommands/TclCommandOffset.py b/tclCommands/TclCommandOffset.py index 63ddc607..7031c0db 100644 --- a/tclCommands/TclCommandOffset.py +++ b/tclCommands/TclCommandOffset.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommand -class TclCommandOffset(TclCommand.TclCommand): +class TclCommandOffset(TclCommand): """ Tcl shell command to change the position of the object. diff --git a/tclCommands/TclCommandOpenExcellon.py b/tclCommands/TclCommandOpenExcellon.py index cf18bc75..69f8ce70 100644 --- a/tclCommands/TclCommandOpenExcellon.py +++ b/tclCommands/TclCommandOpenExcellon.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommandSignaled -class TclCommandOpenExcellon(TclCommand.TclCommandSignaled): +class TclCommandOpenExcellon(TclCommandSignaled): """ Tcl shell command to open an Excellon file. """ diff --git a/tclCommands/TclCommandOpenGCode.py b/tclCommands/TclCommandOpenGCode.py index 2926380e..99314365 100644 --- a/tclCommands/TclCommandOpenGCode.py +++ b/tclCommands/TclCommandOpenGCode.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommandSignaled -class TclCommandOpenGCode(TclCommand.TclCommandSignaled): +class TclCommandOpenGCode(TclCommandSignaled): """ Tcl shell command to open a G-Code file. """ diff --git a/tclCommands/TclCommandOpenGerber.py b/tclCommands/TclCommandOpenGerber.py index afc7dd2a..0dd00d38 100644 --- a/tclCommands/TclCommandOpenGerber.py +++ b/tclCommands/TclCommandOpenGerber.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommandSignaled -class TclCommandOpenGerber(TclCommand.TclCommandSignaled): +class TclCommandOpenGerber(TclCommandSignaled): """ Tcl shell command to opens a Gerber file """ @@ -61,7 +61,7 @@ class TclCommandOpenGerber(TclCommand.TclCommandSignaled): app_obj.progress.emit(0) self.raise_tcl_error('Failed to open file: %s' % filename) - except ParseError, e: + except ParseError as e: app_obj.inform.emit("[error] Failed to parse file: %s, %s " % (filename, str(e))) app_obj.progress.emit(0) self.log.error(str(e)) diff --git a/tclCommands/TclCommandOpenProject.py b/tclCommands/TclCommandOpenProject.py index b4d394ca..97d39ad6 100644 --- a/tclCommands/TclCommandOpenProject.py +++ b/tclCommands/TclCommandOpenProject.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommandSignaled -class TclCommandOpenProject(TclCommand.TclCommandSignaled): +class TclCommandOpenProject(TclCommandSignaled): """ Tcl shell command to open a FlatCAM project. """ diff --git a/tclCommands/TclCommandOptions.py b/tclCommands/TclCommandOptions.py index 3a15549f..443416cf 100644 --- a/tclCommands/TclCommandOptions.py +++ b/tclCommands/TclCommandOptions.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommandSignaled -class TclCommandOptions(TclCommand.TclCommandSignaled): +class TclCommandOptions(TclCommandSignaled): """ Tcl shell command to open an Excellon file. """ diff --git a/tclCommands/TclCommandPaint.py b/tclCommands/TclCommandPaint.py index 41a226a5..8a118290 100644 --- a/tclCommands/TclCommandPaint.py +++ b/tclCommands/TclCommandPaint.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommandSignaled -class TclCommandPaint(TclCommand.TclCommandSignaled): +class TclCommandPaint(TclCommandSignaled): """ Paint the interior of polygons """ diff --git a/tclCommands/TclCommandPanelize.py b/tclCommands/TclCommandPanelize.py index f04d7819..4dcd907e 100644 --- a/tclCommands/TclCommandPanelize.py +++ b/tclCommands/TclCommandPanelize.py @@ -1,10 +1,10 @@ from ObjectCollection import * from copy import copy,deepcopy -import TclCommand +from tclCommands.TclCommand import TclCommand -class TclCommandPanelize(TclCommand.TclCommand): +class TclCommandPanelize(TclCommand): """ Tcl shell command to pannelize an object. diff --git a/tclCommands/TclCommandPlot.py b/tclCommands/TclCommandPlot.py index 5fb59648..d9d045b0 100644 --- a/tclCommands/TclCommandPlot.py +++ b/tclCommands/TclCommandPlot.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommand -class TclCommandPlot(TclCommand.TclCommand): +class TclCommandPlot(TclCommand): """ Tcl shell command to update the plot on the user interface. diff --git a/tclCommands/TclCommandSaveProject.py b/tclCommands/TclCommandSaveProject.py index 8e261f99..43bf73f3 100644 --- a/tclCommands/TclCommandSaveProject.py +++ b/tclCommands/TclCommandSaveProject.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommandSignaled -class TclCommandSaveProject(TclCommand.TclCommandSignaled): +class TclCommandSaveProject(TclCommandSignaled): """ Tcl shell command to save the FlatCAM project to file. """ diff --git a/tclCommands/TclCommandScale.py b/tclCommands/TclCommandScale.py index e6c107c7..8a8f4068 100644 --- a/tclCommands/TclCommandScale.py +++ b/tclCommands/TclCommandScale.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommand -class TclCommandScale(TclCommand.TclCommand): +class TclCommandScale(TclCommand): """ Tcl shell command to resizes the object by a factor. diff --git a/tclCommands/TclCommandSetActive.py b/tclCommands/TclCommandSetActive.py index 097f6f02..21aee2bf 100644 --- a/tclCommands/TclCommandSetActive.py +++ b/tclCommands/TclCommandSetActive.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommand -class TclCommandSetActive(TclCommand.TclCommand): +class TclCommandSetActive(TclCommand): """ Tcl shell command to set an object as active in the GUI. diff --git a/tclCommands/TclCommandSetSys.py b/tclCommands/TclCommandSetSys.py index 2f163cce..ac8fb528 100644 --- a/tclCommands/TclCommandSetSys.py +++ b/tclCommands/TclCommandSetSys.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommand -class TclCommandSetSys(TclCommand.TclCommand): +class TclCommandSetSys(TclCommand): """ Tcl shell command to set the value of a system variable diff --git a/tclCommands/TclCommandSubtractPoly.py b/tclCommands/TclCommandSubtractPoly.py index 03a6b122..54cbf8f4 100644 --- a/tclCommands/TclCommandSubtractPoly.py +++ b/tclCommands/TclCommandSubtractPoly.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommandSignaled -class TclCommandSubtractPoly(TclCommand.TclCommandSignaled): +class TclCommandSubtractPoly(TclCommandSignaled): """ Tcl shell command to create a new empty Geometry object. """ diff --git a/tclCommands/TclCommandSubtractRectangle.py b/tclCommands/TclCommandSubtractRectangle.py index eab6aae8..1ec2838c 100644 --- a/tclCommands/TclCommandSubtractRectangle.py +++ b/tclCommands/TclCommandSubtractRectangle.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommandSignaled -class TclCommandSubtractRectangle(TclCommand.TclCommandSignaled): +class TclCommandSubtractRectangle(TclCommandSignaled): """ Tcl shell command to subtract a rectange from the given Geometry object. """ diff --git a/tclCommands/TclCommandVersion.py b/tclCommands/TclCommandVersion.py index 7d05669c..86b539fd 100644 --- a/tclCommands/TclCommandVersion.py +++ b/tclCommands/TclCommandVersion.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommand -class TclCommandVersion(TclCommand.TclCommand): +class TclCommandVersion(TclCommand): """ Tcl shell command to check the program version. diff --git a/tclCommands/TclCommandWriteGCode.py b/tclCommands/TclCommandWriteGCode.py index 5b898bc1..1068def1 100644 --- a/tclCommands/TclCommandWriteGCode.py +++ b/tclCommands/TclCommandWriteGCode.py @@ -1,8 +1,8 @@ from ObjectCollection import * -import TclCommand +from tclCommands.TclCommand import TclCommandSignaled -class TclCommandWriteGCode(TclCommand.TclCommandSignaled): +class TclCommandWriteGCode(TclCommandSignaled): """ Tcl shell command to save the G-code of a CNC Job object to file. """ diff --git a/tclCommands/__init__.py b/tclCommands/__init__.py index eaa2c327..03325ef6 100644 --- a/tclCommands/__init__.py +++ b/tclCommands/__init__.py @@ -72,9 +72,9 @@ def register_all_commands(app, commands): :return: None """ - tcl_modules = {k: v for k, v in sys.modules.items() if k.startswith('tclCommands.TclCommand')} + tcl_modules = {k: v for k, v in list(sys.modules.items()) if k.startswith('tclCommands.TclCommand')} - for key, mod in tcl_modules.items(): + for key, mod in list(tcl_modules.items()): if key != 'tclCommands.TclCommand': class_name = key.split('.')[1] class_type = getattr(mod, class_name) diff --git a/tests/canvas/performance.py b/tests/canvas/performance.py index 9478bcbf..40047291 100644 --- a/tests/canvas/performance.py +++ b/tests/canvas/performance.py @@ -1,9 +1,9 @@ -from __future__ import division + import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt import numpy as np -import cStringIO +import io from matplotlib.backends.backend_agg import FigureCanvasAgg from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg from matplotlib.figure import Figure diff --git a/tests/other/destructor_test.py b/tests/other/destructor_test.py index c42d8d17..5ae57ce9 100644 --- a/tests/other/destructor_test.py +++ b/tests/other/destructor_test.py @@ -8,7 +8,7 @@ class MyObj(): pass def __del__(self): - print "##### Destroyed ######" + print("##### Destroyed ######") def parse(): diff --git a/tests/other/test_fcrts.py b/tests/other/test_fcrts.py index 7c4afbbb..5c1222d5 100644 --- a/tests/other/test_fcrts.py +++ b/tests/other/test_fcrts.py @@ -26,12 +26,12 @@ for geo in geoms: current_pt = (0, 0) pt, geo = s.nearest(current_pt) while geo is not None: - print pt, geo - print "OBJECTS BEFORE:", s.objects + print((pt, geo)) + print(("OBJECTS BEFORE:", s.objects)) #geo.coords = list(geo.coords[::-1]) s.remove(geo) - print "OBJECTS AFTER:", s.objects + print(("OBJECTS AFTER:", s.objects)) current_pt = geo.coords[-1] pt, geo = s.nearest(current_pt) diff --git a/tests/other/test_rt.py b/tests/other/test_rt.py index 609e5fb4..2df9bd1a 100644 --- a/tests/other/test_rt.py +++ b/tests/other/test_rt.py @@ -13,12 +13,12 @@ rt = rtindex.Index(properties=p) # If interleaved is True, the coordinates must be in # the form [xmin, ymin, ..., kmin, xmax, ymax, ..., kmax]. -print rt.interleaved +print((rt.interleaved)) [rt.add(0, pt2rect(pt)) for pt in pts] -print [r.bbox for r in list(rt.nearest((0, 0), 10, True))] +print([r.bbox for r in list(rt.nearest((0, 0), 10, True))]) for pt in pts: rt.delete(0, pt2rect(pt)) - print pt2rect(pt), [r.bbox for r in list(rt.nearest((0, 0), 10, True))] + print((pt2rect(pt), [r.bbox for r in list(rt.nearest((0, 0), 10, True))])) diff --git a/tests/test_excellon_flow.py b/tests/test_excellon_flow.py index 234dff99..67069e1f 100644 --- a/tests/test_excellon_flow.py +++ b/tests/test_excellon_flow.py @@ -36,18 +36,18 @@ class ExcellonFlowTestCase(unittest.TestCase): def test_flow(self): # Names of available objects. names = self.fc.collection.get_names() - print names + print(names) #-------------------------------------- # Total of 1 objects. #-------------------------------------- - self.assertEquals(len(names), 1, + self.assertEqual(len(names), 1, "Expected 1 object, found %d" % len(names)) #-------------------------------------- # Object's name matches the file name. #-------------------------------------- - self.assertEquals(names[0], self.filename, + self.assertEqual(names[0], self.filename, "Expected name == %s, got %s" % (self.filename, names[0])) #--------------------------------------- @@ -65,14 +65,14 @@ class ExcellonFlowTestCase(unittest.TestCase): # TODO: Open GUI with double-click on object. # Opens the Object's GUI, populates it. excellon_obj.build_ui() - for option, value in excellon_obj.options.iteritems(): + for option, value in list(excellon_obj.options.items()): try: form_field = excellon_obj.form_fields[option] except KeyError: - print ("**********************************************************\n" + print(("**********************************************************\n" "* WARNING: Option '{}' has no form field\n" "**********************************************************" - "".format(option)) + "".format(option))) continue self.assertEqual(value, form_field.get_value(), "Option '{}' == {} but form has {}".format( @@ -87,7 +87,7 @@ class ExcellonFlowTestCase(unittest.TestCase): form_field = excellon_obj.form_fields['feedrate'] value = form_field.get_value() form_field.set_value(value * 1.1) # Increase by 10% - print "'feedrate' == {}".format(value) + print(("'feedrate' == {}".format(value))) #-------------------------------------------------- # Create GCode using all tools. @@ -119,7 +119,7 @@ class ExcellonFlowTestCase(unittest.TestCase): self.assertEqual(value, form_value, "Form value for '{}' == {} was not read into options" "which has {}".format('feedrate', form_value, value)) - print "'feedrate' == {}".format(value) + print(("'feedrate' == {}".format(value))) #--------------------------------------------- # Check that only 1 object has been created. @@ -160,4 +160,4 @@ class ExcellonFlowTestCase(unittest.TestCase): self.assertTrue(os.path.isfile(output_filename)) os.remove(output_filename) - print names + print(names) diff --git a/tests/test_gerber_flow.py b/tests/test_gerber_flow.py index a832150a..15ca26d7 100644 --- a/tests/test_gerber_flow.py +++ b/tests/test_gerber_flow.py @@ -36,18 +36,18 @@ class GerberFlowTestCase(unittest.TestCase): def test_flow(self): # Names of available objects. names = self.fc.collection.get_names() - print names + print(names) #-------------------------------------- # Total of 1 objects. #-------------------------------------- - self.assertEquals(len(names), 1, + self.assertEqual(len(names), 1, "Expected 1 object, found %d" % len(names)) #-------------------------------------- # Object's name matches the file name. #-------------------------------------- - self.assertEquals(names[0], self.filename, + self.assertEqual(names[0], self.filename, "Expected name == %s, got %s" % (self.filename, names[0])) #--------------------------------------- @@ -65,14 +65,14 @@ class GerberFlowTestCase(unittest.TestCase): # TODO: Open GUI with double-click on object. # Opens the Object's GUI, populates it. gerber_obj.build_ui() - for option, value in gerber_obj.options.iteritems(): + for option, value in list(gerber_obj.options.items()): try: form_field = gerber_obj.form_fields[option] except KeyError: - print ("**********************************************************\n" + print(("**********************************************************\n" "* WARNING: Option '{}' has no form field\n" "**********************************************************" - "".format(option)) + "".format(option))) continue self.assertEqual(value, form_field.get_value(), "Option '{}' == {} but form has {}".format( @@ -87,7 +87,7 @@ class GerberFlowTestCase(unittest.TestCase): form_field = gerber_obj.form_fields['isotooldia'] value = form_field.get_value() form_field.set_value(value * 1.1) # Increase by 10% - print "'isotooldia' == {}".format(value) + print(("'isotooldia' == {}".format(value))) #-------------------------------------------------- # Create isolation routing using default values @@ -110,7 +110,7 @@ class GerberFlowTestCase(unittest.TestCase): self.assertEqual(value, form_value, "Form value for '{}' == {} was not read into options" "which has {}".format('isotooldia', form_value, value)) - print "'isotooldia' == {}".format(value) + print(("'isotooldia' == {}".format(value))) #--------------------------------------------- # Check that only 1 object has been created. @@ -187,4 +187,4 @@ class GerberFlowTestCase(unittest.TestCase): self.assertTrue(os.path.isfile(output_filename)) os.remove(output_filename) - print names + print(names) diff --git a/tests/test_paint.py b/tests/test_paint.py index 4bba42db..62115642 100644 --- a/tests/test_paint.py +++ b/tests/test_paint.py @@ -75,66 +75,66 @@ class PaintConnectTest(PaintTestCase): self.boundary = Polygon([[0, 0], [0, 5], [5, 5], [5, 0]]) def test_jump(self): - print "Test: WALK Expected" + print("Test: WALK Expected") paths = [ LineString([[0.5, 2], [2, 4.5]]), LineString([[2, 0.5], [4.5, 2]]) ] for p in paths: - print p + print(p) tooldia = 1.0 - print "--" + print("--") result = Geometry.paint_connect(mkstorage(deepcopy(paths)), self.boundary, tooldia) result = list(result.get_objects()) for r in result: - print r + print(r) self.assertEqual(len(result), 1) # self.plot_summary_A(paths, tooldia, result, "WALK expected.") def test_no_jump1(self): - print "Test: FLY Expected" + print("Test: FLY Expected") paths = [ LineString([[0, 2], [2, 5]]), LineString([[2, 0], [5, 2]]) ] for p in paths: - print p + print(p) tooldia = 1.0 - print "--" + print("--") result = Geometry.paint_connect(mkstorage(deepcopy(paths)), self.boundary, tooldia) result = list(result.get_objects()) for r in result: - print r + print(r) self.assertEqual(len(result), len(paths)) # self.plot_summary_A(paths, tooldia, result, "FLY Expected") def test_no_jump2(self): - print "Test: FLY Expected" + print("Test: FLY Expected") paths = [ LineString([[0.5, 2], [2, 4.5]]), LineString([[2, 0.5], [4.5, 2]]) ] for p in paths: - print p + print(p) tooldia = 1.1 - print "--" + print("--") result = Geometry.paint_connect(mkstorage(deepcopy(paths)), self.boundary, tooldia) result = list(result.get_objects()) for r in result: - print r + print(r) self.assertEqual(len(result), len(paths)) @@ -153,22 +153,22 @@ class PaintConnectTest2(PaintTestCase): ) def test_no_jump3(self): - print "TEST: No jump expected" + print("TEST: No jump expected") paths = [ LineString([[0.5, 1], [1.5, 3]]), LineString([[4, 1], [4, 4]]) ] for p in paths: - print p + print(p) tooldia = 1.0 - print "--" + print("--") result = Geometry.paint_connect(mkstorage(deepcopy(paths)), self.boundary, tooldia) result = list(result.get_objects()) for r in result: - print r + print(r) self.assertEqual(len(result), len(paths)) @@ -182,26 +182,26 @@ class PaintConnectTest3(PaintTestCase): def setUp(self): self.boundary = Polygon([[0, 0], [0, 5], [5, 5], [5, 0]]) - print "TEST w/ LinearRings" + print("TEST w/ LinearRings") def test_jump2(self): - print "Test: WALK Expected" + print("Test: WALK Expected") paths = [ LineString([[0.5, 2], [2, 4.5]]), LineString([[2, 0.5], [4.5, 2]]), self.boundary.buffer(-0.5).exterior ] for p in paths: - print p + print(p) tooldia = 1.0 - print "--" + print("--") result = Geometry.paint_connect(mkstorage(deepcopy(paths)), self.boundary, tooldia) result = list(result.get_objects()) for r in result: - print r + print(r) self.assertEqual(len(result), 1) diff --git a/tests/test_pathconnect.py b/tests/test_pathconnect.py index ec422c1e..74dbfb22 100644 --- a/tests/test_pathconnect.py +++ b/tests/test_pathconnect.py @@ -20,7 +20,7 @@ def mkstorage(paths): class PathConnectTest1(unittest.TestCase): def setUp(self): - print "PathConnectTest1.setUp()" + print("PathConnectTest1.setUp()") pass def test_simple_connect(self): @@ -68,8 +68,8 @@ class PathConnectTest1(unittest.TestCase): [2 + offset_x, 1 + offset_y]]))) def test_ring_interfere_connect(self): - print - print "TEST STARTING ..." + print() + print("TEST STARTING ...") paths = [ LineString([[0, 0], [1, 1]]), diff --git a/tests/test_polygon_paint.py b/tests/test_polygon_paint.py index d7375acc..edaab0ee 100644 --- a/tests/test_polygon_paint.py +++ b/tests/test_polygon_paint.py @@ -30,9 +30,9 @@ class PolyPaintTestCase(unittest.TestCase): def test_poly_paint_svg_all(self): - print "*********************************" - print "* svg_all *" - print "*********************************" + print("*********************************") + print("* svg_all *") + print("*********************************") # Clear workspace self.fc.on_file_new() @@ -69,9 +69,9 @@ class PolyPaintTestCase(unittest.TestCase): def test_poly_paint_svg_click(self): - print "*********************************" - print "* svg_click *" - print "*********************************" + print("*********************************") + print("* svg_click *") + print("*********************************") # Clear workspace self.fc.on_file_new() @@ -109,9 +109,9 @@ class PolyPaintTestCase(unittest.TestCase): def test_poly_paint_noncopper_all(self): - print "*********************************" - print "* noncopper_all *" - print "*********************************" + print("*********************************") + print("* noncopper_all *") + print("*********************************") # Clear workspace self.fc.on_file_new() @@ -165,9 +165,9 @@ class PolyPaintTestCase(unittest.TestCase): def test_poly_paint_noncopper_click(self): - print "*********************************" - print "* noncopper_click *" - print "*********************************" + print("*********************************") + print("* noncopper_click *") + print("*********************************") # Clear workspace self.fc.on_file_new() diff --git a/tests/test_svg_flow.py b/tests/test_svg_flow.py index c3b43223..630a989e 100644 --- a/tests/test_svg_flow.py +++ b/tests/test_svg_flow.py @@ -29,18 +29,18 @@ class SVGFlowTestCase(unittest.TestCase): self.fc.import_svg('tests/svg/' + self.filename) names = self.fc.collection.get_names() - print names + print(names) #-------------------------------------- # Total of 1 objects. #-------------------------------------- - self.assertEquals(len(names), 1, + self.assertEqual(len(names), 1, "Expected 1 object, found %d" % len(names)) #-------------------------------------- # Object's name matches the file name. #-------------------------------------- - self.assertEquals(names[0], self.filename, + self.assertEqual(names[0], self.filename, "Expected name == %s, got %s" % (self.filename, names[0])) #--------------------------------------- @@ -58,14 +58,14 @@ class SVGFlowTestCase(unittest.TestCase): # TODO: Open GUI with double-click on object. # Opens the Object's GUI, populates it. geo_obj.build_ui() - for option, value in geo_obj.options.iteritems(): + for option, value in list(geo_obj.options.items()): try: form_field = geo_obj.form_fields[option] except KeyError: - print ("**********************************************************\n" + print(("**********************************************************\n" "* WARNING: Option '{}' has no form field\n" "**********************************************************" - "".format(option)) + "".format(option))) continue self.assertEqual(value, form_field.get_value(), "Option '{}' == {} but form has {}".format( @@ -126,4 +126,4 @@ class SVGFlowTestCase(unittest.TestCase): self.assertTrue(os.path.isfile(output_filename)) os.remove(output_filename) - print names + print(names) diff --git a/tests/test_tclCommands/__init__.py b/tests/test_tclCommands/__init__.py index 2d1ed5cd..615ad03d 100644 --- a/tests/test_tclCommands/__init__.py +++ b/tests/test_tclCommands/__init__.py @@ -2,17 +2,17 @@ import pkgutil import sys # allowed command tests (please append them alphabetically ordered) -from test_TclCommandAddPolygon import * -from test_TclCommandAddPolyline import * -from test_TclCommandCncjob import * -from test_TclCommandDrillcncjob import * -from test_TclCommandExportGcode import * -from test_TclCommandExteriors import * -from test_TclCommandImportSvg import * -from test_TclCommandInteriors import * -from test_TclCommandIsolate import * -from test_TclCommandNew import * -from test_TclCommandNewGeometry import * -from test_TclCommandOpenExcellon import * -from test_TclCommandOpenGerber import * -from test_TclCommandPaintPolygon import * +from .test_TclCommandAddPolygon import * +from .test_TclCommandAddPolyline import * +from .test_TclCommandCncjob import * +from .test_TclCommandDrillcncjob import * +from .test_TclCommandExportGcode import * +from .test_TclCommandExteriors import * +from .test_TclCommandImportSvg import * +from .test_TclCommandInteriors import * +from .test_TclCommandIsolate import * +from .test_TclCommandNew import * +from .test_TclCommandNewGeometry import * +from .test_TclCommandOpenExcellon import * +from .test_TclCommandOpenGerber import * +from .test_TclCommandPaintPolygon import * diff --git a/tests/test_tclCommands/test_TclCommandCncjob.py b/tests/test_tclCommands/test_TclCommandCncjob.py index cdd8e79f..63ded99b 100644 --- a/tests/test_tclCommands/test_TclCommandCncjob.py +++ b/tests/test_tclCommands/test_TclCommandCncjob.py @@ -1,5 +1,5 @@ from FlatCAMObj import FlatCAMGerber, FlatCAMGeometry, FlatCAMObj -from test_TclCommandIsolate import * +from .test_TclCommandIsolate import * def test_cncjob(self): """ diff --git a/tests/test_tclCommands/test_TclCommandDrillcncjob.py b/tests/test_tclCommands/test_TclCommandDrillcncjob.py index 78326d24..ce651a6e 100644 --- a/tests/test_tclCommands/test_TclCommandDrillcncjob.py +++ b/tests/test_tclCommands/test_TclCommandDrillcncjob.py @@ -1,5 +1,5 @@ from FlatCAMObj import FlatCAMObj -from test_TclCommandOpenExcellon import * +from .test_TclCommandOpenExcellon import * def test_drillcncjob(self): diff --git a/tests/test_tclCommands/test_TclCommandExportGcode.py b/tests/test_tclCommands/test_TclCommandExportGcode.py index 102e6e36..880b5bea 100644 --- a/tests/test_tclCommands/test_TclCommandExportGcode.py +++ b/tests/test_tclCommands/test_TclCommandExportGcode.py @@ -1,8 +1,8 @@ import os import tempfile -from test_TclCommandCncjob import * -from test_TclCommandDrillcncjob import * +from .test_TclCommandCncjob import * +from .test_TclCommandDrillcncjob import * def test_export_gcodecncjob(self): diff --git a/tests/test_tcl_shell.py b/tests/test_tcl_shell.py index 59ac3340..bcf7bed2 100644 --- a/tests/test_tcl_shell.py +++ b/tests/test_tcl_shell.py @@ -82,7 +82,7 @@ class TclShellTest(unittest.TestCase): # Units must be IN #---------------------------------------- units = self.fc.exec_command_test('get_sys units') - self.assertEquals(units, "IN") + self.assertEqual(units, "IN") # MM self.fc.exec_command_test('set_sys units MM') @@ -92,7 +92,7 @@ class TclShellTest(unittest.TestCase): # Units must be MM #---------------------------------------- units = self.fc.exec_command_test('get_sys units') - self.assertEquals(units, "MM") + self.assertEqual(units, "MM") def test_gerber_flow(self): """ From fca9f0ca88d4ff0b1e9b0d99619b7f8dcbfafdfd Mon Sep 17 00:00:00 2001 From: mquezada Date: Sat, 26 May 2018 19:43:01 -0400 Subject: [PATCH 07/21] Double clicking on the object label in the Project list view should select the object and take user to Selected tab. --- ObjectCollection.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ObjectCollection.py b/ObjectCollection.py index a28e7afc..a4d8c32a 100644 --- a/ObjectCollection.py +++ b/ObjectCollection.py @@ -70,7 +70,6 @@ class ObjectCollection(): self.model = QtGui.QStandardItemModel(self.view) self.view.setModel(self.model) self.model.itemChanged.connect(self.on_item_changed) - #self.view.setModel(self) self.click_modifier = None @@ -164,6 +163,10 @@ class ObjectCollection(): # Create the model item to insert into the QListView icon = QtGui.QIcon(self.icons[obj.kind])#self.icons["gerber"]) item = QtGui.QStandardItem(icon, name) + # Item is not editable, so that double click + # does not allow cell value modification. + item.setEditable(False) + # The item is checkable, to add the checkbox. item.setCheckable(True) if obj.options["plot"] == True: item.setCheckState(2)#Qt.Checked) From bc4411d56609ac544e967495083404ecec13a67f Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sun, 27 May 2018 12:07:57 +0300 Subject: [PATCH 08/21] - added a new column in the TableTool where I show the number of drill holes for each tool. --- FlatCAMObj.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index f37ff471..12038e1b 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -756,18 +756,29 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): # Populate tool list n = len(self.tools) - self.ui.tools_table.setColumnCount(2) - self.ui.tools_table.setHorizontalHeaderLabels(['#', 'Diameter']) + self.ui.tools_table.setColumnCount(3) + self.ui.tools_table.setHorizontalHeaderLabels(['#', 'Diameter', 'Count']) self.ui.tools_table.setRowCount(n) self.ui.tools_table.setSortingEnabled(False) + i = 0 for tool in self.tools: + + drill_cnt = 0 # variable to store the nr of drills per tool + # Find no of drills for the current tool + for drill in self.drills: + if drill.get('tool') == tool: + drill_cnt += 1 + id = QtGui.QTableWidgetItem(tool) id.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.ui.tools_table.setItem(i, 0, id) # Tool name/id dia = QtGui.QTableWidgetItem(str(self.tools[tool]['C'])) dia.setFlags(QtCore.Qt.ItemIsEnabled) + drill_count = QtGui.QTableWidgetItem('%d' % drill_cnt) + drill_count.setFlags(QtCore.Qt.ItemIsEnabled) self.ui.tools_table.setItem(i, 1, dia) # Diameter + self.ui.tools_table.setItem(i, 2, drill_count) # Number of drills per tool i += 1 # sort the tool diameter column @@ -777,7 +788,11 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): self.ui.tools_table.resizeColumnsToContents() self.ui.tools_table.resizeRowsToContents() - self.ui.tools_table.horizontalHeader().setStretchLastSection(True) + horizontal_header = self.ui.tools_table.horizontalHeader() + horizontal_header.setResizeMode(0, QtGui.QHeaderView.ResizeToContents) + horizontal_header.setResizeMode(1, QtGui.QHeaderView.Stretch) + horizontal_header.setResizeMode(2, QtGui.QHeaderView.ResizeToContents) + # horizontal_header.setStretchLastSection(True) self.ui.tools_table.verticalHeader().hide() self.ui.tools_table.setSortingEnabled(True) From 5c6b68d7cb847e93d43b7afe1b7d3590215c6fbb Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 28 May 2018 13:55:20 +0300 Subject: [PATCH 09/21] - forgot to make the changes to sorted_tools in generate_milling method from FlatCAMObj.py --- FlatCAMObj.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 2464e955..1d6e7754 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -847,7 +847,14 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): tooldia = self.options["tooldia"] # Sort tools by diameter. items() -> [('name', diameter), ...] - sorted_tools = sorted(list(self.tools.items()), key=lambda tl: tl[1]) + # sorted_tools = sorted(list(self.tools.items()), key=lambda tl: tl[1]) + + # Python3 no longer allows direct comparison between dicts so we need to sort tools differently + sort = [] + for k, v in self.tools.items(): + sort.append((k, v.get('C'))) + sorted_tools = sorted(sort, key=lambda t1: t1[1]) + log.debug("Tools are sorted: %s" % str(sorted_tools)) if tools == "all": tools = [i[0] for i in sorted_tools] # List if ordered tool names. From ef611753a653df6e570b643832c6021307f5e4c2 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 28 May 2018 15:46:42 +0300 Subject: [PATCH 10/21] - added the posibility to create an object without plotting it. Also if the project is created with plot=False then it will not be checked in Project tab - improved the panelize command by toggling OFF the plot for the temporary objects. There is no need to plot the temporary objects, only the panel is of interest - add a few aliases for the Panelize command ('pan' and 'panel') --- FlatCAMApp.py | 28 ++++++++++++++++++++-------- ObjectCollection.py | 4 ++-- tclCommands/TclCommandPanelize.py | 7 +++---- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 04048a5b..ea230c41 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -112,10 +112,10 @@ class App(QtCore.QObject): 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. @@ -1021,9 +1021,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()") @@ -1047,6 +1050,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 @@ -1069,7 +1076,7 @@ class App(QtCore.QObject): # 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 @@ -1483,12 +1490,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 @@ -1530,11 +1539,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 @@ -1545,7 +1555,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)) diff --git a/ObjectCollection.py b/ObjectCollection.py index 82ccef5b..a28e7afc 100644 --- a/ObjectCollection.py +++ b/ObjectCollection.py @@ -289,7 +289,7 @@ class ObjectCollection(): :param name: Name of the FlatCAM Object :return: None """ - iobj = self.createIndex(self.get_names().index(name), 0) # Column 0 + iobj = self.model.createIndex(self.get_names().index(name), 0) # Column 0 self.view.selectionModel().select(iobj, QtGui.QItemSelectionModel.Select) def set_inactive(self, name): @@ -300,7 +300,7 @@ class ObjectCollection(): :param name: Name of the FlatCAM Object :return: None """ - iobj = self.createIndex(self.get_names().index(name), 0) # Column 0 + iobj = self.model.createIndex(self.get_names().index(name), 0) # Column 0 self.view.selectionModel().select(iobj, QtGui.QItemSelectionModel.Deselect) def set_all_inactive(self): diff --git a/tclCommands/TclCommandPanelize.py b/tclCommands/TclCommandPanelize.py index f04d7819..e1e01a91 100644 --- a/tclCommands/TclCommandPanelize.py +++ b/tclCommands/TclCommandPanelize.py @@ -13,7 +13,7 @@ class TclCommandPanelize(TclCommand.TclCommand): """ # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) - aliases = ['panelize'] + aliases = ['panelize', 'pan', 'panel'] # Dictionary of types from Tcl command, needs to be ordered arg_names = collections.OrderedDict([ @@ -130,10 +130,9 @@ class TclCommandPanelize(TclCommand.TclCommand): for col in range(args['columns']): local_outname = outname + ".tmp." + str(col) + "." + str(row) if isinstance(obj, FlatCAMExcellon): - self.app.new_object("excellon", local_outname, initialize_local_excellon) + self.app.new_object("excellon", local_outname, initialize_local_excellon, plot=False) else: - self.app.new_object("geometry", local_outname, initialize_local) - + self.app.new_object("geometry", local_outname, initialize_local, plot=False) currentx += lenghtx currenty += lenghty From 4c0884e16d02ef132ab5a2e584765f2c5ea17cb3 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Tue, 29 May 2018 03:42:35 +0300 Subject: [PATCH 11/21] - when using .keys method (in Python3 is no longer atomic operation) to make it more resilient to multithreading I've added the more costing operation of copy(). --- FlatCAMObj.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 1d6e7754..6599f873 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -729,20 +729,20 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): exc_final.drills.append({"point": point, "tool": drill['tool']}) toolsrework=dict() max_numeric_tool=0 - for toolname in list(exc.tools.keys()): + for toolname in list(exc.tools.copy().keys()): numeric_tool=int(toolname) if numeric_tool>max_numeric_tool: max_numeric_tool=numeric_tool toolsrework[exc.tools[toolname]['C']]=toolname #exc_final as last because names from final tools will be used - for toolname in list(exc_final.tools.keys()): + for toolname in list(exc_final.tools.copy().keys()): numeric_tool=int(toolname) if numeric_tool>max_numeric_tool: max_numeric_tool=numeric_tool toolsrework[exc_final.tools[toolname]['C']]=toolname - for toolvalues in list(toolsrework.keys()): + for toolvalues in list(toolsrework.copy().keys()): if toolsrework[toolvalues] in exc_final.tools: if exc_final.tools[toolsrework[toolvalues]]!={"C": toolvalues}: exc_final.tools[str(max_numeric_tool+1)]={"C": toolvalues} From 3b9767cc6faad4a6a30415380f35603ce90358f5 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 30 May 2018 02:17:34 +0300 Subject: [PATCH 12/21] - I've finally run the tests with OK result (56 tests in 102.937 sec) - I had to play with module imports as they created a lot of error in the tests although in reality the program worked OK. - I've fixed some mistakes in TcL commands (they were testing isinstance against the like of Geometry instead of FlatCAMGeometry) - I've had to add some fixes in ObjectCollections.py (error on create_index() method but Marco already fixed this in the checkbox in project tab pull request and knew about this. - Although at some point the tests run fine, I've made some checkings on my own over the Tcl commands and discovered errors which I fixed as mentioned above. - conclusion is that tests are just a must and do not cover everything (like saving projects which at some point by juggling with imports I braked and tests were 100% OK) --- FlatCAMApp.py | 16 +++++++++------- FlatCAMObj.py | 2 +- ObjectCollection.py | 15 +++++++-------- tclCommands/TclCommand.py | 1 + tclCommands/TclCommandAddCircle.py | 3 +-- tclCommands/TclCommandAddPolygon.py | 3 +-- tclCommands/TclCommandAddPolyline.py | 3 +-- tclCommands/TclCommandAddRectangle.py | 3 +-- tclCommands/TclCommandAlignDrill.py | 3 +-- tclCommands/TclCommandAlignDrillGrid.py | 3 +-- tclCommands/TclCommandCncjob.py | 3 +-- tclCommands/TclCommandCutout.py | 3 +-- tclCommands/TclCommandDelete.py | 3 +-- tclCommands/TclCommandDrillcncjob.py | 3 +-- tclCommands/TclCommandExportGcode.py | 3 +-- tclCommands/TclCommandExportSVG.py | 3 +-- tclCommands/TclCommandExteriors.py | 5 ++--- tclCommands/TclCommandGeoCutout.py | 3 +-- tclCommands/TclCommandGeoUnion.py | 3 +-- tclCommands/TclCommandGetNames.py | 3 +-- tclCommands/TclCommandGetSys.py | 3 +-- tclCommands/TclCommandImportSvg.py | 3 +-- tclCommands/TclCommandInteriors.py | 3 +-- tclCommands/TclCommandIsolate.py | 3 +-- tclCommands/TclCommandJoinExcellon.py | 3 +-- tclCommands/TclCommandJoinGeometry.py | 3 +-- tclCommands/TclCommandMillHoles.py | 3 +-- tclCommands/TclCommandMirror.py | 3 +-- tclCommands/TclCommandNew.py | 3 +-- tclCommands/TclCommandNewGeometry.py | 3 +-- tclCommands/TclCommandOffset.py | 3 +-- tclCommands/TclCommandOpenExcellon.py | 3 +-- tclCommands/TclCommandOpenGCode.py | 3 +-- tclCommands/TclCommandOpenGerber.py | 5 ++--- tclCommands/TclCommandOpenProject.py | 3 +-- tclCommands/TclCommandOptions.py | 3 +-- tclCommands/TclCommandPaint.py | 3 +-- tclCommands/TclCommandPanelize.py | 4 +--- tclCommands/TclCommandPlot.py | 3 +-- tclCommands/TclCommandSaveProject.py | 3 +-- tclCommands/TclCommandScale.py | 3 +-- tclCommands/TclCommandSetActive.py | 3 +-- tclCommands/TclCommandSetSys.py | 3 +-- tclCommands/TclCommandSubtractPoly.py | 3 +-- tclCommands/TclCommandSubtractRectangle.py | 3 +-- tclCommands/TclCommandVersion.py | 3 +-- tclCommands/TclCommandWriteGCode.py | 3 +-- 47 files changed, 63 insertions(+), 105 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 095aa4c4..6774960f 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -17,7 +17,7 @@ import re import webbrowser import os import tkinter -from PyQt4 import QtCore +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 ## @@ -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 #### @@ -1065,7 +1067,7 @@ 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()) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 6599f873..d3d6bf37 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -221,7 +221,7 @@ class FlatCAMObj(QtCore.QObject): try: self.form_fields[option].set_value(self.options[option]) except KeyError: - self.app.log.warn("Tried to set an option or field that does not exist: %s" % option) + self.app.log.warning("Tried to set an option or field that does not exist: %s" % option) def read_form_item(self, option): """ diff --git a/ObjectCollection.py b/ObjectCollection.py index 211c5a82..377e88db 100644 --- a/ObjectCollection.py +++ b/ObjectCollection.py @@ -6,7 +6,6 @@ # MIT Licence # ############################################################ -#from PyQt4.QtCore import QModelIndex from FlatCAMObj import * import inspect # TODO: Remove import FlatCAMApp @@ -162,13 +161,13 @@ class ObjectCollection(): self.object_list.append(obj) # Create the model item to insert into the QListView - icon = QtGui.QIcon(self.icons[obj.kind])#self.icons["gerber"]) - item = QtGui.QStandardItem(icon, name) + icon = QtGui.QIcon(self.icons[obj.kind]) #self.icons["gerber"]) + item = QtGui.QStandardItem(icon, str(name)) item.setCheckable(True) - if obj.options["plot"] == True: - item.setCheckState(2)#Qt.Checked) + if obj.options["plot"] is True: + item.setCheckState(2) #Qt.Checked) else: - item.setCheckState(0) #Qt.Unchecked) + item.setCheckState(0) #Qt.Unchecked) self.model.appendRow(item) @@ -289,7 +288,7 @@ class ObjectCollection(): :param name: Name of the FlatCAM Object :return: None """ - iobj = self.createIndex(self.get_names().index(name), 0) # Column 0 + iobj = self.model.createIndex(self.get_names().index(name), 0) # Column 0 self.view.selectionModel().select(iobj, QtGui.QItemSelectionModel.Select) def set_inactive(self, name): @@ -300,7 +299,7 @@ class ObjectCollection(): :param name: Name of the FlatCAM Object :return: None """ - iobj = self.createIndex(self.get_names().index(name), 0) # Column 0 + iobj = self.model.createIndex(self.get_names().index(name), 0) # Column 0 self.view.selectionModel().select(iobj, QtGui.QItemSelectionModel.Deselect) def set_all_inactive(self): diff --git a/tclCommands/TclCommand.py b/tclCommands/TclCommand.py index 554d319e..45a0e6c6 100644 --- a/tclCommands/TclCommand.py +++ b/tclCommands/TclCommand.py @@ -5,6 +5,7 @@ import abc import collections from PyQt4 import QtCore from contextlib import contextmanager +from FlatCAMObj import FlatCAMGerber, FlatCAMExcellon, FlatCAMGeometry, FlatCAMCNCjob, FlatCAMObj class TclCommand(object): diff --git a/tclCommands/TclCommandAddCircle.py b/tclCommands/TclCommandAddCircle.py index a83777fa..868848a4 100644 --- a/tclCommands/TclCommandAddCircle.py +++ b/tclCommands/TclCommandAddCircle.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommand +from tclCommands.TclCommand import * class TclCommandAddCircle(TclCommand): diff --git a/tclCommands/TclCommandAddPolygon.py b/tclCommands/TclCommandAddPolygon.py index 5c6d7923..79fd5b02 100644 --- a/tclCommands/TclCommandAddPolygon.py +++ b/tclCommands/TclCommandAddPolygon.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommandSignaled +from tclCommands.TclCommand import * class TclCommandAddPolygon(TclCommandSignaled): diff --git a/tclCommands/TclCommandAddPolyline.py b/tclCommands/TclCommandAddPolyline.py index 18e58096..f449e0c2 100644 --- a/tclCommands/TclCommandAddPolyline.py +++ b/tclCommands/TclCommandAddPolyline.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommandSignaled +from tclCommands.TclCommand import * class TclCommandAddPolyline(TclCommandSignaled): diff --git a/tclCommands/TclCommandAddRectangle.py b/tclCommands/TclCommandAddRectangle.py index 7b1e6b9f..e190a399 100644 --- a/tclCommands/TclCommandAddRectangle.py +++ b/tclCommands/TclCommandAddRectangle.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommandSignaled +from tclCommands.TclCommand import * class TclCommandAddRectangle(TclCommandSignaled): diff --git a/tclCommands/TclCommandAlignDrill.py b/tclCommands/TclCommandAlignDrill.py index 6fbaf7c0..1cd1f129 100644 --- a/tclCommands/TclCommandAlignDrill.py +++ b/tclCommands/TclCommandAlignDrill.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommandSignaled +from tclCommands.TclCommand import * class TclCommandAlignDrill(TclCommandSignaled): diff --git a/tclCommands/TclCommandAlignDrillGrid.py b/tclCommands/TclCommandAlignDrillGrid.py index a90397b6..2cac28a1 100644 --- a/tclCommands/TclCommandAlignDrillGrid.py +++ b/tclCommands/TclCommandAlignDrillGrid.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommandSignaled +from tclCommands.TclCommand import * class TclCommandAlignDrillGrid(TclCommandSignaled): diff --git a/tclCommands/TclCommandCncjob.py b/tclCommands/TclCommandCncjob.py index 773c7234..09a1260a 100644 --- a/tclCommands/TclCommandCncjob.py +++ b/tclCommands/TclCommandCncjob.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommandSignaled +from tclCommands.TclCommand import * class TclCommandCncjob(TclCommandSignaled): diff --git a/tclCommands/TclCommandCutout.py b/tclCommands/TclCommandCutout.py index 40e83b01..8d0cc4f8 100644 --- a/tclCommands/TclCommandCutout.py +++ b/tclCommands/TclCommandCutout.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommand +from tclCommands.TclCommand import * class TclCommandCutout(TclCommand): diff --git a/tclCommands/TclCommandDelete.py b/tclCommands/TclCommandDelete.py index 455dfe60..8706722b 100644 --- a/tclCommands/TclCommandDelete.py +++ b/tclCommands/TclCommandDelete.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommand +from tclCommands.TclCommand import * class TclCommandDelete(TclCommand): diff --git a/tclCommands/TclCommandDrillcncjob.py b/tclCommands/TclCommandDrillcncjob.py index 2ecc451c..cba89704 100644 --- a/tclCommands/TclCommandDrillcncjob.py +++ b/tclCommands/TclCommandDrillcncjob.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommandSignaled +from tclCommands.TclCommand import * class TclCommandDrillcncjob(TclCommandSignaled): diff --git a/tclCommands/TclCommandExportGcode.py b/tclCommands/TclCommandExportGcode.py index 84d0b676..d5f10df2 100644 --- a/tclCommands/TclCommandExportGcode.py +++ b/tclCommands/TclCommandExportGcode.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommandSignaled +from tclCommands.TclCommand import * class TclCommandExportGcode(TclCommandSignaled): diff --git a/tclCommands/TclCommandExportSVG.py b/tclCommands/TclCommandExportSVG.py index 7084e980..07fb65b6 100644 --- a/tclCommands/TclCommandExportSVG.py +++ b/tclCommands/TclCommandExportSVG.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommand +from tclCommands.TclCommand import * class TclCommandExportSVG(TclCommand): diff --git a/tclCommands/TclCommandExteriors.py b/tclCommands/TclCommandExteriors.py index 6c93bb59..750ec6ce 100644 --- a/tclCommands/TclCommandExteriors.py +++ b/tclCommands/TclCommandExteriors.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommandSignaled +from tclCommands.TclCommand import * class TclCommandExteriors(TclCommandSignaled): @@ -54,7 +53,7 @@ class TclCommandExteriors(TclCommandSignaled): if obj is None: self.raise_tcl_error("Object not found: %s" % name) - if not isinstance(obj, Geometry): + if not isinstance(obj, FlatCAMGeometry): self.raise_tcl_error('Expected Geometry, got %s %s.' % (name, type(obj))) def geo_init(geo_obj, app_obj): diff --git a/tclCommands/TclCommandGeoCutout.py b/tclCommands/TclCommandGeoCutout.py index 1b905845..bca56b72 100644 --- a/tclCommands/TclCommandGeoCutout.py +++ b/tclCommands/TclCommandGeoCutout.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommandSignaled +from tclCommands.TclCommand import * class TclCommandGeoCutout(TclCommandSignaled): diff --git a/tclCommands/TclCommandGeoUnion.py b/tclCommands/TclCommandGeoUnion.py index d0294e93..3ecbb6d4 100644 --- a/tclCommands/TclCommandGeoUnion.py +++ b/tclCommands/TclCommandGeoUnion.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommand +from tclCommands.TclCommand import * class TclCommandGeoUnion(TclCommand): diff --git a/tclCommands/TclCommandGetNames.py b/tclCommands/TclCommandGetNames.py index db4524f0..e6e0a461 100644 --- a/tclCommands/TclCommandGetNames.py +++ b/tclCommands/TclCommandGetNames.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommand +from tclCommands.TclCommand import * class TclCommandGetNames(TclCommand): diff --git a/tclCommands/TclCommandGetSys.py b/tclCommands/TclCommandGetSys.py index 635decad..2cb213c4 100644 --- a/tclCommands/TclCommandGetSys.py +++ b/tclCommands/TclCommandGetSys.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommand +from tclCommands.TclCommand import * class TclCommandGetSys(TclCommand): diff --git a/tclCommands/TclCommandImportSvg.py b/tclCommands/TclCommandImportSvg.py index fa940439..b49dac02 100644 --- a/tclCommands/TclCommandImportSvg.py +++ b/tclCommands/TclCommandImportSvg.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommandSignaled +from tclCommands.TclCommand import * class TclCommandImportSvg(TclCommandSignaled): diff --git a/tclCommands/TclCommandInteriors.py b/tclCommands/TclCommandInteriors.py index 00a6a1a6..70d37c48 100644 --- a/tclCommands/TclCommandInteriors.py +++ b/tclCommands/TclCommandInteriors.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommandSignaled +from tclCommands.TclCommand import * class TclCommandInteriors(TclCommandSignaled): diff --git a/tclCommands/TclCommandIsolate.py b/tclCommands/TclCommandIsolate.py index 93ad41d0..dc1ab1fa 100644 --- a/tclCommands/TclCommandIsolate.py +++ b/tclCommands/TclCommandIsolate.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommandSignaled +from tclCommands.TclCommand import * class TclCommandIsolate(TclCommandSignaled): diff --git a/tclCommands/TclCommandJoinExcellon.py b/tclCommands/TclCommandJoinExcellon.py index ef2654ca..64c20e78 100644 --- a/tclCommands/TclCommandJoinExcellon.py +++ b/tclCommands/TclCommandJoinExcellon.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommand +from tclCommands.TclCommand import * class TclCommandJoinExcellon(TclCommand): diff --git a/tclCommands/TclCommandJoinGeometry.py b/tclCommands/TclCommandJoinGeometry.py index 90beac4f..18ca2d38 100644 --- a/tclCommands/TclCommandJoinGeometry.py +++ b/tclCommands/TclCommandJoinGeometry.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommand +from tclCommands.TclCommand import * class TclCommandJoinGeometry(TclCommand): diff --git a/tclCommands/TclCommandMillHoles.py b/tclCommands/TclCommandMillHoles.py index 88dbeb79..214b4226 100644 --- a/tclCommands/TclCommandMillHoles.py +++ b/tclCommands/TclCommandMillHoles.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommandSignaled +from tclCommands.TclCommand import * class TclCommandMillHoles(TclCommandSignaled): diff --git a/tclCommands/TclCommandMirror.py b/tclCommands/TclCommandMirror.py index db7ec3c8..437d741b 100644 --- a/tclCommands/TclCommandMirror.py +++ b/tclCommands/TclCommandMirror.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommandSignaled +from tclCommands.TclCommand import * class TclCommandMirror(TclCommandSignaled): diff --git a/tclCommands/TclCommandNew.py b/tclCommands/TclCommandNew.py index bf386d0c..2607035a 100644 --- a/tclCommands/TclCommandNew.py +++ b/tclCommands/TclCommandNew.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommand +from tclCommands.TclCommand import * class TclCommandNew(TclCommand): diff --git a/tclCommands/TclCommandNewGeometry.py b/tclCommands/TclCommandNewGeometry.py index 349f8842..b543c439 100644 --- a/tclCommands/TclCommandNewGeometry.py +++ b/tclCommands/TclCommandNewGeometry.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommandSignaled +from tclCommands.TclCommand import * class TclCommandNewGeometry(TclCommandSignaled): diff --git a/tclCommands/TclCommandOffset.py b/tclCommands/TclCommandOffset.py index 7031c0db..09f5f28e 100644 --- a/tclCommands/TclCommandOffset.py +++ b/tclCommands/TclCommandOffset.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommand +from tclCommands.TclCommand import * class TclCommandOffset(TclCommand): diff --git a/tclCommands/TclCommandOpenExcellon.py b/tclCommands/TclCommandOpenExcellon.py index 69f8ce70..3b731fa6 100644 --- a/tclCommands/TclCommandOpenExcellon.py +++ b/tclCommands/TclCommandOpenExcellon.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommandSignaled +from tclCommands.TclCommand import * class TclCommandOpenExcellon(TclCommandSignaled): diff --git a/tclCommands/TclCommandOpenGCode.py b/tclCommands/TclCommandOpenGCode.py index 99314365..10c475b4 100644 --- a/tclCommands/TclCommandOpenGCode.py +++ b/tclCommands/TclCommandOpenGCode.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommandSignaled +from tclCommands.TclCommand import * class TclCommandOpenGCode(TclCommandSignaled): diff --git a/tclCommands/TclCommandOpenGerber.py b/tclCommands/TclCommandOpenGerber.py index 0dd00d38..0ad4bba7 100644 --- a/tclCommands/TclCommandOpenGerber.py +++ b/tclCommands/TclCommandOpenGerber.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommandSignaled +from tclCommands.TclCommand import * class TclCommandOpenGerber(TclCommandSignaled): @@ -48,7 +47,7 @@ class TclCommandOpenGerber(TclCommandSignaled): # How the object should be initialized def obj_init(gerber_obj, app_obj): - if not isinstance(gerber_obj, Geometry): + if not isinstance(gerber_obj, FlatCAMGerber): self.raise_tcl_error('Expected FlatCAMGerber, got %s %s.' % (outname, type(gerber_obj))) # Opening the file happens here diff --git a/tclCommands/TclCommandOpenProject.py b/tclCommands/TclCommandOpenProject.py index 97d39ad6..971f4f96 100644 --- a/tclCommands/TclCommandOpenProject.py +++ b/tclCommands/TclCommandOpenProject.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommandSignaled +from tclCommands.TclCommand import * class TclCommandOpenProject(TclCommandSignaled): diff --git a/tclCommands/TclCommandOptions.py b/tclCommands/TclCommandOptions.py index 443416cf..7f185621 100644 --- a/tclCommands/TclCommandOptions.py +++ b/tclCommands/TclCommandOptions.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommandSignaled +from tclCommands.TclCommand import * class TclCommandOptions(TclCommandSignaled): diff --git a/tclCommands/TclCommandPaint.py b/tclCommands/TclCommandPaint.py index 8a118290..f3222adb 100644 --- a/tclCommands/TclCommandPaint.py +++ b/tclCommands/TclCommandPaint.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommandSignaled +from tclCommands.TclCommand import * class TclCommandPaint(TclCommandSignaled): diff --git a/tclCommands/TclCommandPanelize.py b/tclCommands/TclCommandPanelize.py index 4dcd907e..7ddf3273 100644 --- a/tclCommands/TclCommandPanelize.py +++ b/tclCommands/TclCommandPanelize.py @@ -1,7 +1,5 @@ -from ObjectCollection import * from copy import copy,deepcopy - -from tclCommands.TclCommand import TclCommand +from tclCommands.TclCommand import * class TclCommandPanelize(TclCommand): diff --git a/tclCommands/TclCommandPlot.py b/tclCommands/TclCommandPlot.py index d9d045b0..687b34db 100644 --- a/tclCommands/TclCommandPlot.py +++ b/tclCommands/TclCommandPlot.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommand +from tclCommands.TclCommand import * class TclCommandPlot(TclCommand): diff --git a/tclCommands/TclCommandSaveProject.py b/tclCommands/TclCommandSaveProject.py index 43bf73f3..c4a44c5d 100644 --- a/tclCommands/TclCommandSaveProject.py +++ b/tclCommands/TclCommandSaveProject.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommandSignaled +from tclCommands.TclCommand import * class TclCommandSaveProject(TclCommandSignaled): diff --git a/tclCommands/TclCommandScale.py b/tclCommands/TclCommandScale.py index 8a8f4068..3b561992 100644 --- a/tclCommands/TclCommandScale.py +++ b/tclCommands/TclCommandScale.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommand +from tclCommands.TclCommand import * class TclCommandScale(TclCommand): diff --git a/tclCommands/TclCommandSetActive.py b/tclCommands/TclCommandSetActive.py index 21aee2bf..19d9f000 100644 --- a/tclCommands/TclCommandSetActive.py +++ b/tclCommands/TclCommandSetActive.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommand +from tclCommands.TclCommand import * class TclCommandSetActive(TclCommand): diff --git a/tclCommands/TclCommandSetSys.py b/tclCommands/TclCommandSetSys.py index 2e0bab7c..aff86124 100644 --- a/tclCommands/TclCommandSetSys.py +++ b/tclCommands/TclCommandSetSys.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommand +from tclCommands.TclCommand import * class TclCommandSetSys(TclCommand): diff --git a/tclCommands/TclCommandSubtractPoly.py b/tclCommands/TclCommandSubtractPoly.py index 54cbf8f4..427b85f7 100644 --- a/tclCommands/TclCommandSubtractPoly.py +++ b/tclCommands/TclCommandSubtractPoly.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommandSignaled +from tclCommands.TclCommand import * class TclCommandSubtractPoly(TclCommandSignaled): diff --git a/tclCommands/TclCommandSubtractRectangle.py b/tclCommands/TclCommandSubtractRectangle.py index 1ec2838c..73d91284 100644 --- a/tclCommands/TclCommandSubtractRectangle.py +++ b/tclCommands/TclCommandSubtractRectangle.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommandSignaled +from tclCommands.TclCommand import * class TclCommandSubtractRectangle(TclCommandSignaled): diff --git a/tclCommands/TclCommandVersion.py b/tclCommands/TclCommandVersion.py index 86b539fd..a2977289 100644 --- a/tclCommands/TclCommandVersion.py +++ b/tclCommands/TclCommandVersion.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommand +from tclCommands.TclCommand import * class TclCommandVersion(TclCommand): diff --git a/tclCommands/TclCommandWriteGCode.py b/tclCommands/TclCommandWriteGCode.py index 1068def1..17919150 100644 --- a/tclCommands/TclCommandWriteGCode.py +++ b/tclCommands/TclCommandWriteGCode.py @@ -1,5 +1,4 @@ -from ObjectCollection import * -from tclCommands.TclCommand import TclCommandSignaled +from tclCommands.TclCommand import * class TclCommandWriteGCode(TclCommandSignaled): From aff21d7cb02a36659ac289708a11c2c1a05b2021 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 30 May 2018 08:02:03 +0300 Subject: [PATCH 13/21] - changed the default way to copy the coordinates to clipboard. Before, at each mouse click on canvaas the coordinates were copied to clipboard. Now for the same feet it require to have the CTRL key pressed while clicking on canvas for the coordinates to be copied. --- FlatCAMApp.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index ea230c41..e3b0ddf8 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -1639,8 +1639,9 @@ 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)) - - self.clipboard.setText(self.defaults["point_clipboard_format"] % (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)) except Exception, e: App.log.debug("Outside plot?") From 560e882da0543a4b5172e8a23181f7caed3b1910 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 30 May 2018 15:54:14 +0300 Subject: [PATCH 14/21] - made sure FlatCAM use python3 in Linux (JP's find) - cgi module is deprecated in Python3, using the recommended module html as replacement --- flatcam | 2 +- termwidget.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/flatcam b/flatcam index 3c5ef0bf..fb3daa8c 100755 --- a/flatcam +++ b/flatcam @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 ############################################################ # FlatCAM: 2D Post-processing for Manufacturing # # http://flatcam.org # diff --git a/termwidget.py b/termwidget.py index 41433bed..66ea3f03 100644 --- a/termwidget.py +++ b/termwidget.py @@ -3,7 +3,7 @@ Terminal emulator widget. Shows intput and output text. Allows to enter commands. Supports history. """ -import cgi +import html from PyQt4.QtCore import pyqtSignal, Qt from PyQt4.QtGui import QColor, QKeySequence, QLineEdit, QPalette, \ QSizePolicy, QTextCursor, QTextEdit, \ @@ -152,7 +152,7 @@ class TermWidget(QWidget): """ assert style in ('in', 'out', 'err') - text = cgi.escape(text) + text = html.escape(text) text = text.replace('\n', '
') if style == 'in': From 3298da6dc5af4e46b33293705e4de35dabf7bc98 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 30 May 2018 18:02:44 +0300 Subject: [PATCH 15/21] - solve the conflicted files (hopefully) without CLI commands --- ObjectCollection.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ObjectCollection.py b/ObjectCollection.py index 377e88db..3b82b1f8 100644 --- a/ObjectCollection.py +++ b/ObjectCollection.py @@ -161,8 +161,12 @@ class ObjectCollection(): self.object_list.append(obj) # Create the model item to insert into the QListView - icon = QtGui.QIcon(self.icons[obj.kind]) #self.icons["gerber"]) - item = QtGui.QStandardItem(icon, str(name)) + icon = QtGui.QIcon(self.icons[obj.kind]) # self.icons["gerber"]) + item = QtGui.QStandardItem(icon, name) + # Item is not editable, so that double click + # does not allow cell value modification. + item.setEditable(False) + # The item is checkable, to add the checkbox. item.setCheckable(True) if obj.options["plot"] is True: item.setCheckState(2) #Qt.Checked) From 4cf06b71e8ecb7396f8cef6f698790e891c73555 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 30 May 2018 18:39:04 +0300 Subject: [PATCH 16/21] - for whatever reason, using directly the name of the object in a QtGui.QStadardItem is creating issues in the tests. Converting it to a string solve this. After solving the conflict in the pull request this modification was lost so I am doing it again. - the FlatCAMObj.FlatCAMGerber.isolate() method is having the line app.obj.info() which randomly create issues due of using QPixMaps outside of the GUI thread. --- FlatCAMObj.py | 5 ++++- ObjectCollection.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index d4ea1d8b..b6d2c92b 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -554,7 +554,10 @@ class FlatCAMGerber(FlatCAMObj, Gerber): # Propagate options geo_obj.options["cnctooldia"] = self.options["isotooldia"] geo_obj.solid_geometry = generate_envelope (offset, i == 0) - app_obj.info("Isolation geometry created: %s" % geo_obj.options["name"]) + + # The following line is commented because it creates errors + # regarding QPixmaps used outside GUI thread + # app_obj.info("Isolation geometry created: %s" % geo_obj.options["name"]) # TODO: Do something if this is None. Offer changing name? self.app.new_object("geometry", iso_name, iso_init) diff --git a/ObjectCollection.py b/ObjectCollection.py index 3b82b1f8..ccc6a6da 100644 --- a/ObjectCollection.py +++ b/ObjectCollection.py @@ -162,7 +162,7 @@ class ObjectCollection(): # Create the model item to insert into the QListView icon = QtGui.QIcon(self.icons[obj.kind]) # self.icons["gerber"]) - item = QtGui.QStandardItem(icon, name) + item = QtGui.QStandardItem(icon, str(name)) # Item is not editable, so that double click # does not allow cell value modification. item.setEditable(False) From c85a142759ae760512c52d700305c6eda6bbdc08 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 30 May 2018 22:52:50 +0300 Subject: [PATCH 17/21] - fixing issue #254 - replaced (as per advice from @jpcgt) the lines with app.info call to using a signal which is safe to use in a threaded environment, app.inform.emit() --- DblSidedTool.py | 2 +- FlatCAMApp.py | 4 ++-- FlatCAMDraw.py | 14 +++++++------- FlatCAMObj.py | 14 +++++++------- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/DblSidedTool.py b/DblSidedTool.py index 7446dd8b..4e52a4ba 100644 --- a/DblSidedTool.py +++ b/DblSidedTool.py @@ -165,7 +165,7 @@ class DblSidedTool(FlatCAMTool): if not isinstance(fcobj, FlatCAMGerber) and \ not isinstance(fcobj, FlatCAMExcellon) and \ not isinstance(fcobj, FlatCAMGeometry): - self.info("ERROR: Only Gerber, Excellon and Geometry objects can be mirrored.") + self.app.inform.emit("ERROR: Only Gerber, Excellon and Geometry objects can be mirrored.") return axis = self.mirror_axis.get_value() diff --git a/FlatCAMApp.py b/FlatCAMApp.py index ea230c41..85763ab1 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -693,7 +693,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) @@ -708,7 +708,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) diff --git a/FlatCAMDraw.py b/FlatCAMDraw.py index 57c1fdb6..86bd9725 100644 --- a/FlatCAMDraw.py +++ b/FlatCAMDraw.py @@ -983,7 +983,7 @@ class FlatCAMDraw(QtCore.QObject): self.tools[t]["button"].setChecked(False) self.active_tool = self.tools[tool]["constructor"](self) - self.app.info(self.active_tool.start_msg) + self.app.inform.emit(self.active_tool.start_msg) else: self.app.log.debug("%s is NOT checked." % tool) for t in self.tools: @@ -1002,7 +1002,7 @@ class FlatCAMDraw(QtCore.QObject): if self.active_tool is not None and event.button is 1: # Dispatch event to active_tool msg = self.active_tool.click(self.snap(event.xdata, event.ydata)) - self.app.info(msg) + self.app.inform.emit(msg) # If it is a shape generating tool if isinstance(self.active_tool, FCShapeTool) and self.active_tool.complete: @@ -1114,14 +1114,14 @@ class FlatCAMDraw(QtCore.QObject): self.active_tool.make() if self.active_tool.complete: self.on_shape_complete() - self.app.info("Done.") + self.app.inform.emit("Done.") return ### Abort the current action if event.key == 'escape': # TODO: ...? #self.on_tool_select("select") - self.app.info("Cancelled.") + self.app.inform.emit("Cancelled.") self.delete_utility_geometry() @@ -1141,14 +1141,14 @@ class FlatCAMDraw(QtCore.QObject): self.move_btn.setChecked(True) self.on_tool_select('move') self.active_tool.set_origin(self.snap(event.xdata, event.ydata)) - self.app.info("Click on target point.") + self.app.inform.emit("Click on target point.") ### Copy if event.key == 'c': self.copy_btn.setChecked(True) self.on_tool_select('copy') self.active_tool.set_origin(self.snap(event.xdata, event.ydata)) - self.app.info("Click on target point.") + self.app.inform.emit("Click on target point.") ### Snap if event.key == 'g': @@ -1165,7 +1165,7 @@ class FlatCAMDraw(QtCore.QObject): if self.active_tool is not None: response = self.active_tool.on_key(event.key) if response is not None: - self.app.info(response) + self.app.inform.emit(response) def on_canvas_key_release(self, event): self.key = None diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 12038e1b..443e803d 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -101,7 +101,7 @@ class FlatCAMObj(QtCore.QObject): old_name = copy(self.options["name"]) new_name = self.ui.name_entry.get_value() self.options["name"] = self.ui.name_entry.get_value() - self.app.info("Name changed from %s to %s" % (old_name, new_name)) + self.app.inform.emit("Name changed from %s to %s" % (old_name, new_name)) def on_offset_button_click(self): self.app.report_usage("obj_on_offset_button") @@ -473,7 +473,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber): # Propagate options follow_obj.options["cnctooldia"] = self.options["isotooldia"] follow_obj.solid_geometry = self.solid_geometry - app_obj.info("Follow geometry created: %s" % follow_obj.options["name"]) + app_obj.inform.emit("Follow geometry created: %s" % follow_obj.options["name"]) # TODO: Do something if this is None. Offer changing name? self.app.new_object("geometry", follow_name, follow_init) @@ -519,7 +519,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber): elif type(geom) is Polygon: geom = Polygon(geom.exterior.coords[::-1], geom.interiors) else: - raise "Unexpected Geometry" + raise str("Unexpected Geometry") return geom if combine: @@ -534,7 +534,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber): offset = (2 * i + 1) / 2.0 * dia - i * overlap * dia geom = generate_envelope (offset, i == 0) geo_obj.solid_geometry.append(geom) - app_obj.info("Isolation geometry created: %s" % geo_obj.options["name"]) + app_obj.inform.emit("Isolation geometry created: %s" % geo_obj.options["name"]) # TODO: Do something if this is None. Offer changing name? self.app.new_object("geometry", iso_name, iso_init) @@ -553,7 +553,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber): # Propagate options geo_obj.options["cnctooldia"] = self.options["isotooldia"] geo_obj.solid_geometry = generate_envelope (offset, i == 0) - app_obj.info("Isolation geometry created: %s" % geo_obj.options["name"]) + app_obj.inform.emit("Isolation geometry created: %s" % geo_obj.options["name"]) # TODO: Do something if this is None. Offer changing name? self.app.new_object("geometry", iso_name, iso_init) @@ -1294,11 +1294,11 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): return if self.options["selectmethod"] == "single": - self.app.info("Click inside the desired polygon.") + self.app.inform.emit("Click inside the desired polygon.") # To be called after clicking on the plot. def doit(event): - self.app.info("Painting polygon...") + self.app.inform.emit("Painting polygon...") self.app.plotcanvas.mpl_disconnect(subscription) point = [event.xdata, event.ydata] self.paint_poly_single_click(point, tooldia, overlap, From d50bac4d7136b26fef5c7ffd17826306dee9acc3 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 31 May 2018 01:08:52 +0300 Subject: [PATCH 18/21] - hopefully this will solve the conflict --- ObjectCollection.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/ObjectCollection.py b/ObjectCollection.py index ecfd680f..6485ca11 100644 --- a/ObjectCollection.py +++ b/ObjectCollection.py @@ -38,14 +38,15 @@ class ObjectCollection(): } icon_files = { - "gerber": "share/flatcam_icon16.png", - "excellon": "share/drill16.png", - "cncjob": "share/cnc16.png", - "geometry": "share/geometry16.png" + "gerber": "share:flatcam_icon16.png", + "excellon": "share:drill16.png", + "cncjob": "share:cnc16.png", + "geometry": "share:geometry16.png" } def __init__(self, parent=None): #QtCore.QAbstractListModel.__init__(self, parent=parent) + ### Icons for the list view self.icons = {} for kind in ObjectCollection.icon_files: @@ -161,7 +162,7 @@ class ObjectCollection(): # Create the model item to insert into the QListView icon = QtGui.QIcon(self.icons[obj.kind])#self.icons["gerber"]) - item = QtGui.QStandardItem(icon, name) + item = QtGui.QStandardItem(icon, str(name)) # Item is not editable, so that double click # does not allow cell value modification. item.setEditable(False) From 969eb933fbf69968d5c2e6dce4f7de54d29fb758 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 31 May 2018 01:11:17 +0300 Subject: [PATCH 19/21] - hopefully this will solve the conflict --- FlatCAMObj.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 378d892a..e4184aeb 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -554,10 +554,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber): # Propagate options geo_obj.options["cnctooldia"] = self.options["isotooldia"] geo_obj.solid_geometry = generate_envelope (offset, i == 0) - - # The following line is commented because it creates errors - # regarding QPixmaps used outside GUI thread - # app_obj.info("Isolation geometry created: %s" % geo_obj.options["name"]) + app_obj.inform.emit("Isolation geometry created: %s" % geo_obj.options["name"]) # TODO: Do something if this is None. Offer changing name? self.app.new_object("geometry", iso_name, iso_init) From 0b49a061be0c164bf6a9e5c4dca36311df960104 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 31 May 2018 01:14:04 +0300 Subject: [PATCH 20/21] - hopefully this will solve the conflict --- FlatCAMObj.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index e4184aeb..d4d2dec0 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -511,15 +511,14 @@ class FlatCAMGerber(FlatCAMObj, Gerber): # to cut on the right side of the left over copper i.e on the left side of the features. geom = self.isolation_geometry(offset) if invert: - try: - if type(geom) is MultiPolygon: - pl = [] - for p in geom: - pl.append(Polygon(p.exterior.coords[::-1], p.interiors)) - geom = MultiPolygon(pl) - elif type(geom) is Polygon: - geom = Polygon(geom.exterior.coords[::-1], geom.interiors) - except Exception as e: + if type(geom) is MultiPolygon: + pl = [] + for p in geom: + pl.append(Polygon(p.exterior.coords[::-1], p.interiors)) + geom = MultiPolygon(pl) + elif type(geom) is Polygon: + geom = Polygon(geom.exterior.coords[::-1], geom.interiors) + else: str("Unexpected Geometry") return geom From d8ea4a268cbff1900fee7aa8adf7ac11787eaa5d Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 31 May 2018 01:19:11 +0300 Subject: [PATCH 21/21] - hopefully this will solve the conflict --- FlatCAMObj.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FlatCAMObj.py b/FlatCAMObj.py index d4d2dec0..2516a339 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -519,7 +519,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber): elif type(geom) is Polygon: geom = Polygon(geom.exterior.coords[::-1], geom.interiors) else: - str("Unexpected Geometry") + raise str("Unexpected Geometry") return geom if combine: