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

View File

@@ -165,7 +165,7 @@ class DblSidedTool(FlatCAMTool):
if not isinstance(fcobj, FlatCAMGerber) and \ if not isinstance(fcobj, FlatCAMGerber) and \
not isinstance(fcobj, FlatCAMExcellon) and \ not isinstance(fcobj, FlatCAMExcellon) and \
not isinstance(fcobj, FlatCAMGeometry): 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 return
axis = self.mirror_axis.get_value() axis = self.mirror_axis.get_value()

View File

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

View File

@@ -694,31 +694,23 @@ class FlatCAMDraw(QtCore.QObject):
self.drawing_toolbar.setDisabled(disabled) self.drawing_toolbar.setDisabled(disabled)
self.app.ui.addToolBar(self.drawing_toolbar) self.app.ui.addToolBar(self.drawing_toolbar)
self.select_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share:pointer32.png'), "Select 'Esc'") self.select_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share/pointer32.png'), "Select 'Esc'")
# Separator self.add_circle_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share/circle32.png'), 'Add Circle')
self.drawing_toolbar.addSeparator() self.add_arc_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share/arc32.png'), 'Add Arc')
self.add_circle_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share:circle32.png'), 'Add Circle') self.add_rectangle_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share/rectangle32.png'), 'Add Rectangle')
self.add_arc_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share:arc32.png'), 'Add Arc') self.add_polygon_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share/polygon32.png'), 'Add Polygon')
self.add_rectangle_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share:rectangle32.png'), 'Add Rectangle') self.add_path_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share/path32.png'), 'Add Path')
self.add_polygon_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share:polygon32.png'), 'Add Polygon') self.union_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share/union32.png'), 'Polygon Union')
self.add_path_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share:path32.png'), 'Add Path') 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')
# Separator self.cutpath_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share/cutpath32.png'), 'Cut Path')
self.drawing_toolbar.addSeparator() self.move_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share/move32.png'), "Move Objects 'm'")
self.union_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share:union32.png'), 'Polygon Union') self.copy_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share/copy32.png'), "Copy Objects 'c'")
self.intersection_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share:intersection32.png'), 'Polygon Intersection') self.delete_btn = self.drawing_toolbar.addAction(QtGui.QIcon('share/deleteshape32.png'), "Delete Shape '-'")
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')
# Separator
self.drawing_toolbar.addSeparator()
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 ### ### Snap Toolbar ###
self.snap_toolbar = QtGui.QToolBar("Grid 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 = QtGui.QLineEdit()
self.grid_gap_x_entry.setMaximumWidth(70) self.grid_gap_x_entry.setMaximumWidth(70)
self.grid_gap_x_entry.setToolTip("Grid X distance") self.grid_gap_x_entry.setToolTip("Grid X distance")
@@ -728,7 +720,7 @@ class FlatCAMDraw(QtCore.QObject):
self.grid_gap_y_entry.setToolTip("Grid Y distante") self.grid_gap_y_entry.setToolTip("Grid Y distante")
self.snap_toolbar.addWidget(self.grid_gap_y_entry) 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 = QtGui.QLineEdit()
self.snap_max_dist_entry.setMaximumWidth(70) self.snap_max_dist_entry.setMaximumWidth(70)
self.snap_max_dist_entry.setToolTip("Max. magnet distance") self.snap_max_dist_entry.setToolTip("Max. magnet distance")
@@ -740,23 +732,21 @@ class FlatCAMDraw(QtCore.QObject):
### Application menu ### ### Application menu ###
self.menu = QtGui.QMenu("Drawing") self.menu = QtGui.QMenu("Drawing")
self.app.ui.menu.insertMenu(self.app.ui.menutoolaction, self.menu) 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.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_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_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_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_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.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.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.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.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.cutpath_menuitem = self.menu.addAction(QtGui.QIcon('share/cutpath16.png'), 'Cut Path')
# Add Separator # self.move_menuitem = self.menu.addAction(QtGui.QIcon('share/move16.png'), "Move Objects 'm'")
self.menu.addSeparator() # self.copy_menuitem = self.menu.addAction(QtGui.QIcon('share/copy16.png'), "Copy Objects 'c'")
# self.move_menuitem = self.menu.addAction(QtGui.QIcon('share:move16.png'), "Move Objects 'm'") self.delete_menuitem = self.menu.addAction(QtGui.QIcon('share/deleteshape16.png'), "Delete Shape '-'")
# self.copy_menuitem = self.menu.addAction(QtGui.QIcon('share:copy16.png'), "Copy Objects 'c'") self.buffer_menuitem = self.menu.addAction(QtGui.QIcon('share/buffer16.png'), "Buffer selection 'b'")
self.delete_menuitem = self.menu.addAction(QtGui.QIcon('share:deleteshape16.png'), "Delete Shape '-'") self.paint_menuitem = self.menu.addAction(QtGui.QIcon('share/paint16.png'), "Paint selection")
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.menu.addSeparator()
self.paint_menuitem.triggered.connect(self.on_paint_tool) self.paint_menuitem.triggered.connect(self.on_paint_tool)
@@ -994,7 +984,7 @@ class FlatCAMDraw(QtCore.QObject):
self.tools[t]["button"].setChecked(False) self.tools[t]["button"].setChecked(False)
self.active_tool = self.tools[tool]["constructor"](self) 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: else:
self.app.log.debug("%s is NOT checked." % tool) self.app.log.debug("%s is NOT checked." % tool)
for t in self.tools: for t in self.tools:
@@ -1013,7 +1003,7 @@ class FlatCAMDraw(QtCore.QObject):
if self.active_tool is not None and event.button is 1: if self.active_tool is not None and event.button is 1:
# Dispatch event to active_tool # Dispatch event to active_tool
msg = self.active_tool.click(self.snap(event.xdata, event.ydata)) 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 it is a shape generating tool
if isinstance(self.active_tool, FCShapeTool) and self.active_tool.complete: if isinstance(self.active_tool, FCShapeTool) and self.active_tool.complete:
@@ -1125,14 +1115,14 @@ class FlatCAMDraw(QtCore.QObject):
self.active_tool.make() self.active_tool.make()
if self.active_tool.complete: if self.active_tool.complete:
self.on_shape_complete() self.on_shape_complete()
self.app.info("Done.") self.app.inform.emit("Done.")
return return
### Abort the current action ### Abort the current action
if event.key == 'escape': if event.key == 'escape':
# TODO: ...? # TODO: ...?
#self.on_tool_select("select") #self.on_tool_select("select")
self.app.info("Cancelled.") self.app.inform.emit("Cancelled.")
self.delete_utility_geometry() self.delete_utility_geometry()
@@ -1152,14 +1142,14 @@ class FlatCAMDraw(QtCore.QObject):
self.move_btn.setChecked(True) self.move_btn.setChecked(True)
self.on_tool_select('move') self.on_tool_select('move')
self.active_tool.set_origin(self.snap(event.xdata, event.ydata)) 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 ### Copy
if event.key == 'c': if event.key == 'c':
self.copy_btn.setChecked(True) self.copy_btn.setChecked(True)
self.on_tool_select('copy') self.on_tool_select('copy')
self.active_tool.set_origin(self.snap(event.xdata, event.ydata)) 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 ### Snap
if event.key == 'g': if event.key == 'g':
@@ -1176,7 +1166,7 @@ class FlatCAMDraw(QtCore.QObject):
if self.active_tool is not None: if self.active_tool is not None:
response = self.active_tool.on_key(event.key) response = self.active_tool.on_key(event.key)
if response is not None: if response is not None:
self.app.info(response) self.app.inform.emit(response)
def on_canvas_key_release(self, event): def on_canvas_key_release(self, event):
self.key = None self.key = None
@@ -1484,7 +1474,7 @@ class FlatCAMDraw(QtCore.QObject):
for param in [tooldia, overlap, margin]: for param in [tooldia, overlap, margin]:
if not isinstance(param, float): 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()) self.app.inform.emit("[warning] Invalid value for {}".format())
# Todo: Check for valid method. # Todo: Check for valid method.

View File

@@ -28,83 +28,79 @@ class FlatCAMGUI(QtGui.QMainWindow):
self.menufile = self.menu.addMenu('&File') self.menufile = self.menu.addMenu('&File')
# New # New
self.menufilenew = QtGui.QAction(QtGui.QIcon('share:file16.png'), '&New project', self) self.menufilenew = QtGui.QAction(QtGui.QIcon('share/file16.png'), '&New project', self)
self.menufile.addAction(self.menufilenew) self.menufile.addAction(self.menufilenew)
# 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 ...")
# Separator # Separator
self.menufile.addSeparator() self.menufile.addSeparator()
# Open gerber ... # 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) self.menufile.addAction(self.menufileopengerber)
# Open Excellon ... # 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) self.menufile.addAction(self.menufileopenexcellon)
# Open G-Code ... # 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) self.menufile.addAction(self.menufileopengcode)
# Open Project ... # 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) self.menufile.addAction(self.menufileopenproject)
# Separator # Separator
self.menufile.addSeparator() self.menufile.addSeparator()
# Import SVG ... # 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) self.menufile.addAction(self.menufileimportsvg)
# Export SVG ... # 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) self.menufile.addAction(self.menufileexportsvg)
# Separator # Separator
self.menufile.addSeparator() self.menufile.addSeparator()
# Save Project # 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) self.menufile.addAction(self.menufilesaveproject)
# Save Project As ... # 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) self.menufile.addAction(self.menufilesaveprojectas)
# Save Project Copy ... # 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) self.menufile.addAction(self.menufilesaveprojectcopy)
# Save Defaults # 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) self.menufile.addAction(self.menufilesavedefaults)
# Separator # Separator
self.menufile.addSeparator() self.menufile.addSeparator()
# Quit # 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)
self.menufile.addAction(self.exit_action)
# exitAction.setShortcut('Ctrl+Q') # exitAction.setShortcut('Ctrl+Q')
# exitAction.setStatusTip('Exit application') # exitAction.setStatusTip('Exit application')
#self.exit_action.triggered.connect(QtGui.qApp.quit) #self.exit_action.triggered.connect(QtGui.qApp.quit)
### Edit ### ### Edit ###
self.menuedit = self.menu.addMenu('&Edit') self.menuedit = self.menu.addMenu('&Edit')
self.menueditnew = self.menuedit.addAction(QtGui.QIcon('share:new_geo16.png'), 'New 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.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.menuedit.addAction(QtGui.QIcon('share/edit_ok16.png'), 'Update Geometry')
#self.menueditok.
# Separator #self.menueditcancel = self.menuedit.addAction(QtGui.QIcon('share/cancel_edit16.png'), "Cancel Edit")
self.menuedit.addSeparator() self.menueditjoin = self.menuedit.addAction(QtGui.QIcon('share/join16.png'), 'Join Geometry')
self.menueditdelete = self.menuedit.addAction(QtGui.QIcon('share/trash16.png'), 'Delete')
self.menueditjoin = self.menuedit.addAction(QtGui.QIcon('share:join16.png'), 'Join Geometry')
self.menueditdelete = self.menuedit.addAction(QtGui.QIcon('share:trash16.png'), 'Delete')
### Options ### ### Options ###
self.menuoptions = self.menu.addMenu('&Options') self.menuoptions = self.menu.addMenu('&Options')
@@ -118,58 +114,42 @@ class FlatCAMGUI(QtGui.QMainWindow):
### View ### ### View ###
self.menuview = self.menu.addMenu('&View') self.menuview = self.menu.addMenu('&View')
self.menuviewdisableall = self.menuview.addAction(QtGui.QIcon('share:clear_plot16.png'), 'Disable all plots') 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.menuviewdisableother = self.menuview.addAction(QtGui.QIcon('share/clear_plot16.png'),
'Disable all plots but this one') '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 ### ### Tool ###
self.menutool = QtGui.QMenu('&Tool') self.menutool = QtGui.QMenu('&Tool')
self.menutoolaction = self.menu.addMenu(self.menutool) 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 ### ### Help ###
self.menuhelp = self.menu.addMenu('&Help') self.menuhelp = self.menu.addMenu('&Help')
self.menuhelp_about = self.menuhelp.addAction(QtGui.QIcon('share:tv16.png'), 'About FlatCAM') 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_home = self.menuhelp.addAction(QtGui.QIcon('share/home16.png'), 'Home')
self.menuhelp_manual = self.menuhelp.addAction(QtGui.QIcon('share:globe16.png'), 'Manual') self.menuhelp_manual = self.menuhelp.addAction(QtGui.QIcon('share/globe16.png'), 'Manual')
############### ###############
### Toolbar ### ### Toolbar ###
############### ###############
self.toolbarfile = QtGui.QToolBar('File Toolbar')
self.addToolBar(self.toolbarfile)
self.open_gerber_btn = self.toolbarfile.addAction(QtGui.QIcon('share:flatcam_icon32.png'), "Open &Gerber")
self.open_exc_btn = self.toolbarfile.addAction(QtGui.QIcon('share:drill32.png'), "Open &Excellon")
self.open_gcode_btn = self.toolbarfile.addAction(QtGui.QIcon('share:cnc32.png'), "Open Gco&de")
self.save_btn = self.toolbarfile.addAction(QtGui.QIcon('share:floppy32.png'), 'Save Project &As ...')
self.toolbarview= QtGui.QToolBar('View Toolbar') self.toolbar = QtGui.QToolBar()
self.addToolBar(self.toolbarview) self.addToolBar(self.toolbar)
self.zoom_fit_btn = self.toolbarview.addAction(QtGui.QIcon('share:zoom_fit32.png'), "&Zoom Fit")
self.zoom_out_btn = self.toolbarview.addAction(QtGui.QIcon('share:zoom_out32.png'), "&Zoom Out")
self.zoom_in_btn = self.toolbarview.addAction(QtGui.QIcon('share:zoom_in32.png'), "&Zoom In")
# Separator
self.toolbarview.addSeparator()
self.clear_plot_btn = self.toolbarview.addAction(QtGui.QIcon('share:clear_plot32.png'), "&Clear Plot")
self.replot_btn = self.toolbarview.addAction(QtGui.QIcon('share:replot32.png'), "&Replot")
self.toolbareditobj = QtGui.QToolBar('Obj.Editor Toolbar') self.zoom_fit_btn = self.toolbar.addAction(QtGui.QIcon('share/zoom_fit32.png'), "&Zoom Fit")
self.addToolBar(self.toolbareditobj) self.zoom_out_btn = self.toolbar.addAction(QtGui.QIcon('share/zoom_out32.png'), "&Zoom Out")
self.newgeo_btn = self.toolbareditobj.addAction(QtGui.QIcon('share:new_geo32.png'), "New Blank Geometry") self.zoom_in_btn = self.toolbar.addAction(QtGui.QIcon('share/zoom_in32.png'), "&Zoom In")
self.editgeo_btn = self.toolbareditobj.addAction(QtGui.QIcon('share:edit32.png'), "Edit Geometry") self.clear_plot_btn = self.toolbar.addAction(QtGui.QIcon('share/clear_plot32.png'), "&Clear Plot")
self.updategeo_btn = self.toolbareditobj.addAction(QtGui.QIcon('share:edit_ok32.png'), "Update Geometry") 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.updategeo_btn.setEnabled(False)
#self.canceledit_btn = self.toolbar.addAction(QtGui.QIcon('share/cancel_edit32.png'), "Cancel Edit")
self.toolbaredit = QtGui.QToolBar('Edit Toolbar') self.delete_btn = self.toolbar.addAction(QtGui.QIcon('share/delete32.png'), "&Delete")
self.addToolBar(self.toolbaredit) self.shell_btn = self.toolbar.addAction(QtGui.QIcon('share/shell32.png'), "&Command Line")
self.delete_btn = self.toolbaredit.addAction(QtGui.QIcon('share:delete32.png'), "&Delete")
self.toolbartools = QtGui.QToolBar('Tools Toolbar')
self.addToolBar(self.toolbartools)
self.shell_btn = self.toolbartools.addAction(QtGui.QIcon('share:shell32.png'), "&Command Line")
self.measure_btn = self.toolbartools.addAction(QtGui.QIcon('share:measure32.png'), "&Measurement Tool")
################ ################
### Splitter ### ### Splitter ###
@@ -209,7 +189,7 @@ class FlatCAMGUI(QtGui.QMainWindow):
self.options_tab_layout.addLayout(hlay1) self.options_tab_layout.addLayout(hlay1)
self.icon = QtGui.QLabel() self.icon = QtGui.QLabel()
self.icon.setPixmap(QtGui.QPixmap('share:gear48.png')) self.icon.setPixmap(QtGui.QPixmap('share/gear48.png'))
hlay1.addWidget(self.icon) hlay1.addWidget(self.icon)
self.options_combo = QtGui.QComboBox() self.options_combo = QtGui.QComboBox()
@@ -277,12 +257,12 @@ class FlatCAMGUI(QtGui.QMainWindow):
### Icons ### ### Icons ###
############# #############
self.app_icon = QtGui.QIcon() self.app_icon = QtGui.QIcon()
self.app_icon.addFile('share:flatcam_icon16.png', QtCore.QSize(16, 16)) 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_icon24.png', QtCore.QSize(24, 24))
self.app_icon.addFile('share:flatcam_icon32.png', QtCore.QSize(32, 32)) 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_icon48.png', QtCore.QSize(48, 48))
self.app_icon.addFile('share:flatcam_icon128.png', QtCore.QSize(128, 128)) 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_icon256.png', QtCore.QSize(256, 256))
self.setWindowIcon(self.app_icon) self.setWindowIcon(self.app_icon)
self.setGeometry(100, 100, 1024, 650) self.setGeometry(100, 100, 1024, 650)
@@ -308,7 +288,7 @@ class FlatCAMActivityView(QtGui.QWidget):
self.icon = QtGui.QLabel(self) self.icon = QtGui.QLabel(self)
self.icon.setGeometry(0, 0, 12, 12) 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.icon.setMovie(self.movie)
#self.movie.start() #self.movie.start()
@@ -339,7 +319,7 @@ class FlatCAMInfoBar(QtGui.QWidget):
self.icon = QtGui.QLabel(self) self.icon = QtGui.QLabel(self)
self.icon.setGeometry(0, 0, 12, 12) 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) self.icon.setPixmap(self.pmap)
layout = QtGui.QHBoxLayout() layout = QtGui.QHBoxLayout()
@@ -364,13 +344,13 @@ class FlatCAMInfoBar(QtGui.QWidget):
level = str(level) level = str(level)
self.pmap.fill() self.pmap.fill()
if level == "error": if level == "error":
self.pmap = QtGui.QPixmap('share:redlight12.png') self.pmap = QtGui.QPixmap('share/redlight12.png')
elif level == "success": elif level == "success":
self.pmap = QtGui.QPixmap('share:greenlight12.png') self.pmap = QtGui.QPixmap('share/greenlight12.png')
elif level == "warning": elif level == "warning":
self.pmap = QtGui.QPixmap('share:yellowlight12.png') self.pmap = QtGui.QPixmap('share/yellowlight12.png')
else: else:
self.pmap = QtGui.QPixmap('share:graylight12.png') self.pmap = QtGui.QPixmap('share/graylight12.png')
self.icon.setPixmap(self.pmap) self.icon.setPixmap(self.pmap)
self.set_text_(text) self.set_text_(text)

View File

@@ -6,7 +6,7 @@
# MIT Licence # # MIT Licence #
############################################################ ############################################################
from cStringIO import StringIO from io import StringIO
from PyQt4 import QtCore from PyQt4 import QtCore
from copy import copy from copy import copy
from ObjectUI import * from ObjectUI import *
@@ -101,7 +101,7 @@ class FlatCAMObj(QtCore.QObject):
old_name = copy(self.options["name"]) old_name = copy(self.options["name"])
new_name = self.ui.name_entry.get_value() new_name = self.ui.name_entry.get_value()
self.options["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): def on_offset_button_click(self):
self.app.report_usage("obj_on_offset_button") self.app.report_usage("obj_on_offset_button")
@@ -221,7 +221,7 @@ class FlatCAMObj(QtCore.QObject):
try: try:
self.form_fields[option].set_value(self.options[option]) self.form_fields[option].set_value(self.options[option])
except KeyError: 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): def read_form_item(self, option):
""" """
@@ -473,7 +473,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
# Propagate options # Propagate options
follow_obj.options["cnctooldia"] = self.options["isotooldia"] follow_obj.options["cnctooldia"] = self.options["isotooldia"]
follow_obj.solid_geometry = self.solid_geometry 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? # TODO: Do something if this is None. Offer changing name?
self.app.new_object("geometry", follow_name, follow_init) self.app.new_object("geometry", follow_name, follow_init)
@@ -519,7 +519,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
elif type(geom) is Polygon: elif type(geom) is Polygon:
geom = Polygon(geom.exterior.coords[::-1], geom.interiors) geom = Polygon(geom.exterior.coords[::-1], geom.interiors)
else: else:
raise "Unexpected Geometry" raise str("Unexpected Geometry")
return geom return geom
if combine: if combine:
@@ -534,7 +534,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
offset = (2 * i + 1) / 2.0 * dia - i * overlap * dia offset = (2 * i + 1) / 2.0 * dia - i * overlap * dia
geom = generate_envelope (offset, i == 0) geom = generate_envelope (offset, i == 0)
geo_obj.solid_geometry.append(geom) 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? # TODO: Do something if this is None. Offer changing name?
self.app.new_object("geometry", iso_name, iso_init) self.app.new_object("geometry", iso_name, iso_init)
@@ -553,7 +553,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
# Propagate options # Propagate options
geo_obj.options["cnctooldia"] = self.options["isotooldia"] geo_obj.options["cnctooldia"] = self.options["isotooldia"]
geo_obj.solid_geometry = generate_envelope (offset, i == 0) 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? # TODO: Do something if this is None. Offer changing name?
self.app.new_object("geometry", iso_name, iso_init) self.app.new_object("geometry", iso_name, iso_init)
@@ -728,20 +728,20 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
exc_final.drills.append({"point": point, "tool": drill['tool']}) exc_final.drills.append({"point": point, "tool": drill['tool']})
toolsrework=dict() toolsrework=dict()
max_numeric_tool=0 max_numeric_tool=0
for toolname in exc.tools.iterkeys(): for toolname in list(exc.tools.copy().keys()):
numeric_tool=int(toolname) numeric_tool=int(toolname)
if numeric_tool>max_numeric_tool: if numeric_tool>max_numeric_tool:
max_numeric_tool=numeric_tool max_numeric_tool=numeric_tool
toolsrework[exc.tools[toolname]['C']]=toolname toolsrework[exc.tools[toolname]['C']]=toolname
#exc_final as last because names from final tools will be used #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.copy().keys()):
numeric_tool=int(toolname) numeric_tool=int(toolname)
if numeric_tool>max_numeric_tool: if numeric_tool>max_numeric_tool:
max_numeric_tool=numeric_tool max_numeric_tool=numeric_tool
toolsrework[exc_final.tools[toolname]['C']]=toolname toolsrework[exc_final.tools[toolname]['C']]=toolname
for toolvalues in toolsrework.iterkeys(): for toolvalues in list(toolsrework.copy().keys()):
if toolsrework[toolvalues] in exc_final.tools: if toolsrework[toolvalues] in exc_final.tools:
if exc_final.tools[toolsrework[toolvalues]]!={"C": toolvalues}: if exc_final.tools[toolsrework[toolvalues]]!={"C": toolvalues}:
exc_final.tools[str(max_numeric_tool+1)]={"C": toolvalues} exc_final.tools[str(max_numeric_tool+1)]={"C": toolvalues}
@@ -756,18 +756,29 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
# Populate tool list # Populate tool list
n = len(self.tools) n = len(self.tools)
self.ui.tools_table.setColumnCount(2) self.ui.tools_table.setColumnCount(3)
self.ui.tools_table.setHorizontalHeaderLabels(['#', 'Diameter']) self.ui.tools_table.setHorizontalHeaderLabels(['#', 'Diameter', 'Count'])
self.ui.tools_table.setRowCount(n) self.ui.tools_table.setRowCount(n)
self.ui.tools_table.setSortingEnabled(False) self.ui.tools_table.setSortingEnabled(False)
i = 0 i = 0
for tool in self.tools: 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 = QtGui.QTableWidgetItem(tool)
id.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) id.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
self.ui.tools_table.setItem(i, 0, id) # Tool name/id self.ui.tools_table.setItem(i, 0, id) # Tool name/id
dia = QtGui.QTableWidgetItem(str(self.tools[tool]['C'])) dia = QtGui.QTableWidgetItem(str(self.tools[tool]['C']))
dia.setFlags(QtCore.Qt.ItemIsEnabled) 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, 1, dia) # Diameter
self.ui.tools_table.setItem(i, 2, drill_count) # Number of drills per tool
i += 1 i += 1
# sort the tool diameter column # sort the tool diameter column
@@ -777,7 +788,11 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
self.ui.tools_table.resizeColumnsToContents() self.ui.tools_table.resizeColumnsToContents()
self.ui.tools_table.resizeRowsToContents() 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.verticalHeader().hide()
self.ui.tools_table.setSortingEnabled(True) self.ui.tools_table.setSortingEnabled(True)
@@ -846,7 +861,14 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
tooldia = self.options["tooldia"] tooldia = self.options["tooldia"]
# Sort tools by diameter. items() -> [('name', diameter), ...] # 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])
# 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": if tools == "all":
tools = [i[0] for i in sorted_tools] # List if ordered tool names. tools = [i[0] for i in sorted_tools] # List if ordered tool names.
@@ -1044,6 +1066,7 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
"tooldia": self.ui.tooldia_entry, "tooldia": self.ui.tooldia_entry,
"append": self.ui.append_text, "append": self.ui.append_text,
"prepend": self.ui.prepend_text, "prepend": self.ui.prepend_text,
"postprocess": self.ui.process_script,
"dwell": self.ui.dwell_cb, "dwell": self.ui.dwell_cb,
"dwelltime": self.ui.dwelltime_entry "dwelltime": self.ui.dwelltime_entry
}) })
@@ -1066,15 +1089,16 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
self.read_form() self.read_form()
try: 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"])) directory=self.app.defaults["last_folder"]))
except TypeError: 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()) preamble = str(self.ui.prepend_text.get_value())
postamble = str(self.ui.append_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): def dwell_generator(self, lines):
""" """
@@ -1110,7 +1134,7 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
raise StopIteration raise StopIteration
def export_gcode(self, filename, preamble='', postamble=''): def export_gcode(self, filename, preamble='', postamble='', processor=''):
lines = StringIO(self.gcode) lines = StringIO(self.gcode)
@@ -1279,11 +1303,11 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
return return
if self.options["selectmethod"] == "single": 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. # To be called after clicking on the plot.
def doit(event): def doit(event):
self.app.info("Painting polygon...") self.app.inform.emit("Painting polygon...")
self.app.plotcanvas.mpl_disconnect(subscription) self.app.plotcanvas.mpl_disconnect(subscription)
point = [event.xdata, event.ydata] point = [event.xdata, event.ydata]
self.paint_poly_single_click(point, tooldia, overlap, self.paint_poly_single_click(point, tooldia, overlap,
@@ -1351,9 +1375,9 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
geo_obj.options["cnctooldia"] = tooldia geo_obj.options["cnctooldia"] = tooldia
# Experimental... # Experimental...
print "Indexing...", print("Indexing...")
geo_obj.make_index() geo_obj.make_index()
print "Done" print("Done")
self.app.inform.emit("Done.") self.app.inform.emit("Done.")
@@ -1437,9 +1461,9 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
geo_obj.options["cnctooldia"] = tooldia geo_obj.options["cnctooldia"] = tooldia
# Experimental... # Experimental...
print "Indexing...", print("Indexing...")
geo_obj.make_index() geo_obj.make_index()
print "Done" print("Done")
self.app.inform.emit("Done.") self.app.inform.emit("Done.")

View File

@@ -81,7 +81,7 @@ class LengthEntry(QtGui.QLineEdit):
def returnPressed(self, *args, **kwargs): def returnPressed(self, *args, **kwargs):
val = self.get_value() val = self.get_value()
if val is not None: if val is not None:
self.set_text(QtCore.QString(str(val))) self.set_text(str(val))
else: else:
log.warning("Could not interpret entry: %s" % self.get_text()) log.warning("Could not interpret entry: %s" % self.get_text())
@@ -105,7 +105,7 @@ class LengthEntry(QtGui.QLineEdit):
return None return None
def set_value(self, val): def set_value(self, val):
self.setText(QtCore.QString(str(val))) self.setText(str(val))
class FloatEntry(QtGui.QLineEdit): class FloatEntry(QtGui.QLineEdit):
@@ -115,7 +115,7 @@ class FloatEntry(QtGui.QLineEdit):
def returnPressed(self, *args, **kwargs): def returnPressed(self, *args, **kwargs):
val = self.get_value() val = self.get_value()
if val is not None: if val is not None:
self.set_text(QtCore.QString(str(val))) self.set_text(str(val))
else: else:
log.warning("Could not interpret entry: %s" % self.text()) log.warning("Could not interpret entry: %s" % self.text())
@@ -151,10 +151,10 @@ class IntEntry(QtGui.QLineEdit):
def set_value(self, val): def set_value(self, val):
if val == self.empty_val and self.allow_empty: if val == self.empty_val and self.allow_empty:
self.setText(QtCore.QString("")) self.setText("")
return return
self.setText(QtCore.QString(str(val))) self.setText(str(val))
class FCEntry(QtGui.QLineEdit): class FCEntry(QtGui.QLineEdit):
@@ -165,7 +165,7 @@ class FCEntry(QtGui.QLineEdit):
return str(self.text()) return str(self.text())
def set_value(self, val): def set_value(self, val):
self.setText(QtCore.QString(str(val))) self.setText(str(val))
class EvalEntry(QtGui.QLineEdit): class EvalEntry(QtGui.QLineEdit):
@@ -175,7 +175,7 @@ class EvalEntry(QtGui.QLineEdit):
def returnPressed(self, *args, **kwargs): def returnPressed(self, *args, **kwargs):
val = self.get_value() val = self.get_value()
if val is not None: if val is not None:
self.setText(QtCore.QString(str(val))) self.setText(str(val))
else: else:
log.warning("Could not interpret entry: %s" % self.get_text()) log.warning("Could not interpret entry: %s" % self.get_text())
@@ -188,12 +188,12 @@ class EvalEntry(QtGui.QLineEdit):
return None return None
def set_value(self, val): def set_value(self, val):
self.setText(QtCore.QString(str(val))) self.setText(str(val))
class FCCheckBox(QtGui.QCheckBox): class FCCheckBox(QtGui.QCheckBox):
def __init__(self, label='', parent=None): 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): def get_value(self):
return self.isChecked() return self.isChecked()

View File

@@ -6,7 +6,6 @@
# MIT Licence # # MIT Licence #
############################################################ ############################################################
#from PyQt4.QtCore import QModelIndex
from FlatCAMObj import * from FlatCAMObj import *
import inspect # TODO: Remove import inspect # TODO: Remove
import FlatCAMApp import FlatCAMApp
@@ -47,6 +46,7 @@ class ObjectCollection():
def __init__(self, parent=None): def __init__(self, parent=None):
#QtCore.QAbstractListModel.__init__(self, parent=parent) #QtCore.QAbstractListModel.__init__(self, parent=parent)
### Icons for the list view ### Icons for the list view
self.icons = {} self.icons = {}
for kind in ObjectCollection.icon_files: for kind in ObjectCollection.icon_files:
@@ -70,7 +70,6 @@ class ObjectCollection():
self.model = QtGui.QStandardItemModel(self.view) self.model = QtGui.QStandardItemModel(self.view)
self.view.setModel(self.model) self.view.setModel(self.model)
self.model.itemChanged.connect(self.on_item_changed) self.model.itemChanged.connect(self.on_item_changed)
#self.view.setModel(self)
self.click_modifier = None self.click_modifier = None
@@ -102,7 +101,7 @@ class ObjectCollection():
def print_list(self): def print_list(self):
for obj in self.object_list: for obj in self.object_list:
print obj print(obj)
def on_mouse_down(self, event): def on_mouse_down(self, event):
FlatCAMApp.App.log.debug("Mouse button pressed on list") FlatCAMApp.App.log.debug("Mouse button pressed on list")
@@ -163,12 +162,16 @@ class ObjectCollection():
# Create the model item to insert into the QListView # Create the model item to insert into the QListView
icon = QtGui.QIcon(self.icons[obj.kind])#self.icons["gerber"]) 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)
# The item is checkable, to add the checkbox.
item.setCheckable(True) item.setCheckable(True)
if obj.options["plot"] == True: if obj.options["plot"] is True:
item.setCheckState(2)#Qt.Checked) item.setCheckState(2) #Qt.Checked)
else: else:
item.setCheckState(0) #Qt.Unchecked) item.setCheckState(0) #Qt.Unchecked)
self.model.appendRow(item) self.model.appendRow(item)
@@ -289,7 +292,7 @@ class ObjectCollection():
:param name: Name of the FlatCAM Object :param name: Name of the FlatCAM Object
:return: None :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) self.view.selectionModel().select(iobj, QtGui.QItemSelectionModel.Select)
def set_inactive(self, name): def set_inactive(self, name):
@@ -300,7 +303,7 @@ class ObjectCollection():
:param name: Name of the FlatCAM Object :param name: Name of the FlatCAM Object
:return: None :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) self.view.selectionModel().select(iobj, QtGui.QItemSelectionModel.Deselect)
def set_all_inactive(self): def set_all_inactive(self):

View File

@@ -11,7 +11,7 @@ class ObjectUI(QtGui.QWidget):
put UI elements in ObjectUI.custom_box (QtGui.QLayout). 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) QtGui.QWidget.__init__(self, parent=parent)
layout = QtGui.QVBoxLayout() layout = QtGui.QVBoxLayout()
@@ -117,7 +117,7 @@ class CNCObjectUI(ObjectUI):
be placed in ``self.custom_box`` to preserve the layout. 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. # Scale and offset are not available for CNCJob objects.
# Hiding from the GUI. # Hiding from the GUI.
@@ -196,6 +196,17 @@ class CNCObjectUI(ObjectUI):
self.append_text = FCTextArea() self.append_text = FCTextArea()
self.custom_box.addWidget(self.append_text) 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.process_script = FCTextArea()
self.custom_box.addWidget(self.process_script)
# Dwell # Dwell
grid1 = QtGui.QGridLayout() grid1 = QtGui.QGridLayout()
self.custom_box.addLayout(grid1) self.custom_box.addLayout(grid1)
@@ -231,7 +242,7 @@ class GeometryObjectUI(ObjectUI):
""" """
def __init__(self, parent=None): 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 ## Plot options
self.plot_options_label = QtGui.QLabel("<b>Plot Options:</b>") self.plot_options_label = QtGui.QLabel("<b>Plot Options:</b>")
@@ -450,7 +461,7 @@ class ExcellonObjectUI(ObjectUI):
def __init__(self, parent=None): def __init__(self, parent=None):
ObjectUI.__init__(self, title='Excellon Object', ObjectUI.__init__(self, title='Excellon Object',
icon_file='share:drill32.png', icon_file='share/drill32.png',
parent=parent) parent=parent)
#### Plot options #### #### Plot options ####
@@ -814,4 +825,4 @@ class GerberObjectUI(ObjectUI):
# #
# #
# if __name__ == '__main__': # if __name__ == '__main__':
# main() # main()

View File

@@ -43,8 +43,8 @@ source_suffix = '.rst'
master_doc = 'index' master_doc = 'index'
# General information about the project. # General information about the project.
project = u'FlatCAM Bugs' project = 'FlatCAM Bugs'
copyright = u'2014, Juan Pablo Caram' copyright = '2014, Juan Pablo Caram'
# The version info for the project you're documenting, acts as replacement for # The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the # |version| and |release|, also used in various other places throughout the
@@ -196,8 +196,8 @@ latex_elements = {
# (source start file, target name, title, # (source start file, target name, title,
# author, documentclass [howto, manual, or own class]). # author, documentclass [howto, manual, or own class]).
latex_documents = [ latex_documents = [
('index', 'FlatCAMBugs.tex', u'FlatCAM Bugs Documentation', ('index', 'FlatCAMBugs.tex', 'FlatCAM Bugs Documentation',
u'Juan Pablo Caram', 'manual'), 'Juan Pablo Caram', 'manual'),
] ]
# The name of an image file (relative to this directory) to place at the top of # 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 # One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section). # (source start file, name, description, authors, manual section).
man_pages = [ man_pages = [
('index', 'flatcambugs', u'FlatCAM Bugs Documentation', ('index', 'flatcambugs', 'FlatCAM Bugs Documentation',
[u'Juan Pablo Caram'], 1) ['Juan Pablo Caram'], 1)
] ]
# If true, show URL addresses after external links. # If true, show URL addresses after external links.
@@ -240,8 +240,8 @@ man_pages = [
# (source start file, target name, title, author, # (source start file, target name, title, author,
# dir menu entry, description, category) # dir menu entry, description, category)
texinfo_documents = [ texinfo_documents = [
('index', 'FlatCAMBugs', u'FlatCAM Bugs Documentation', ('index', 'FlatCAMBugs', 'FlatCAM Bugs Documentation',
u'Juan Pablo Caram', 'FlatCAMBugs', 'One line description of project.', 'Juan Pablo Caram', 'FlatCAMBugs', 'One line description of project.',
'Miscellaneous'), 'Miscellaneous'),
] ]

View File

@@ -9,7 +9,7 @@
#from scipy import optimize #from scipy import optimize
#import traceback #import traceback
from cStringIO import StringIO from io import StringIO
from numpy import arctan2, Inf, array, sqrt, pi, ceil, sin, cos, dot, float32, \ from numpy import arctan2, Inf, array, sqrt, pi, ceil, sin, cos, dot, float32, \
transpose transpose
from numpy.linalg import solve, norm from numpy.linalg import solve, norm
@@ -2360,7 +2360,7 @@ class Gerber (Geometry):
else: else:
self.solid_geometry = self.solid_geometry.difference(new_poly) self.solid_geometry = self.solid_geometry.difference(new_poly)
except Exception, err: except Exception as err:
ex_type, ex, tb = sys.exc_info() ex_type, ex, tb = sys.exc_info()
traceback.print_tb(tb) traceback.print_tb(tb)
#print traceback.format_exc() #print traceback.format_exc()
@@ -2972,14 +2972,18 @@ class CNCjob(Geometry):
# Tools # Tools
# Sort tools by diameter. items() -> [('name', diameter), ...] # 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": if tools == "all":
tools = [i[0] for i in sorted_tools] # List if ordered tool names. tools = [i[0] for i in sorted_tools] # List if ordered tool names.
log.debug("Tools 'all' and sorted are: %s" % str(tools)) log.debug("Tools 'all' and sorted are: %s" % str(tools))
else: else:
selected_tools = [x.strip() for x in tools.split(",")] 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 # 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] 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: :param pt:
:return: :return:
""" """
return self.rti.nearest(pt, objects=True).next() return next(self.rti.nearest(pt, objects=True))
class FlatCAMRTreeStorage(FlatCAMRTree): class FlatCAMRTreeStorage(FlatCAMRTree):

View File

@@ -8,10 +8,10 @@ class PolygonTestCase(unittest.TestCase):
MultiPoint([(-5, 0), (5, 0)]).buffer(3.0)) MultiPoint([(-5, 0), (5, 0)]).buffer(3.0))
def test_patch(self): def test_patch(self):
patch = PolygonPatch(self.polygon) patch = PolygonPatch(self.polygon)
self.failUnlessEqual(str(type(patch)), self.assertEqual(str(type(patch)),
"<class 'matplotlib.patches.PathPatch'>") "<class 'matplotlib.patches.PathPatch'>")
path = patch.get_path() 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): class JSONPolygonTestCase(unittest.TestCase):
polygon = Point(0, 0).buffer(10.0).difference( polygon = Point(0, 0).buffer(10.0).difference(
@@ -19,10 +19,10 @@ class JSONPolygonTestCase(unittest.TestCase):
def test_patch(self): def test_patch(self):
geo = self.polygon.__geo_interface__ geo = self.polygon.__geo_interface__
patch = PolygonPatch(geo) patch = PolygonPatch(geo)
self.failUnlessEqual(str(type(patch)), self.assertEqual(str(type(patch)),
"<class 'matplotlib.patches.PathPatch'>") "<class 'matplotlib.patches.PathPatch'>")
path = patch.get_path() 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 GeoInterfacePolygonTestCase(unittest.TestCase):
class GeoThing: class GeoThing:
@@ -32,7 +32,7 @@ class GeoInterfacePolygonTestCase(unittest.TestCase):
MultiPoint([(-5, 0), (5, 0)]).buffer(3.0)).__geo_interface__ MultiPoint([(-5, 0), (5, 0)]).buffer(3.0)).__geo_interface__
def test_patch(self): def test_patch(self):
patch = PolygonPatch(self.thing) patch = PolygonPatch(self.thing)
self.failUnlessEqual(str(type(patch)), self.assertEqual(str(type(patch)),
"<class 'matplotlib.patches.PathPatch'>") "<class 'matplotlib.patches.PathPatch'>")
path = patch.get_path() path = patch.get_path()
self.failUnless(len(path.vertices) == len(path.codes) == 198) self.assertTrue(len(path.vertices) == len(path.codes) == 198)

View File

@@ -45,8 +45,8 @@ source_suffix = '.rst'
master_doc = 'index' master_doc = 'index'
# General information about the project. # General information about the project.
project = u'Cirkuix' project = 'Cirkuix'
copyright = u'2014, Juan Pablo Caram' copyright = '2014, Juan Pablo Caram'
# The version info for the project you're documenting, acts as replacement for # The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the # |version| and |release|, also used in various other places throughout the
@@ -203,8 +203,8 @@ latex_elements = {
# (source start file, target name, title, # (source start file, target name, title,
# author, documentclass [howto, manual, or own class]). # author, documentclass [howto, manual, or own class]).
latex_documents = [ latex_documents = [
('index', 'Cirkuix.tex', u'Cirkuix Documentation', ('index', 'Cirkuix.tex', 'Cirkuix Documentation',
u'Juan Pablo Caram', 'manual'), 'Juan Pablo Caram', 'manual'),
] ]
# The name of an image file (relative to this directory) to place at the top of # 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 # One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section). # (source start file, name, description, authors, manual section).
man_pages = [ man_pages = [
('index', 'cirkuix', u'Cirkuix Documentation', ('index', 'cirkuix', 'Cirkuix Documentation',
[u'Juan Pablo Caram'], 1) ['Juan Pablo Caram'], 1)
] ]
# If true, show URL addresses after external links. # If true, show URL addresses after external links.
@@ -247,8 +247,8 @@ man_pages = [
# (source start file, target name, title, author, # (source start file, target name, title, author,
# dir menu entry, description, category) # dir menu entry, description, category)
texinfo_documents = [ texinfo_documents = [
('index', 'Cirkuix', u'Cirkuix Documentation', ('index', 'Cirkuix', 'Cirkuix Documentation',
u'Juan Pablo Caram', 'Cirkuix', 'One line description of project.', 'Juan Pablo Caram', 'Cirkuix', 'One line description of project.',
'Miscellaneous'), 'Miscellaneous'),
] ]

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
############################################################ ############################################################
# FlatCAM: 2D Post-processing for Manufacturing # # FlatCAM: 2D Post-processing for Manufacturing #
# http://flatcam.org # # http://flatcam.org #
@@ -30,6 +30,6 @@ debug_trace()
# NOTE: Never talk to the GUI from threads! This is why I commented the above. # NOTE: Never talk to the GUI from threads! This is why I commented the above.
app = QtGui.QApplication(sys.argv) 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() fc = App()
sys.exit(app.exec_()) sys.exit(app.exec_())

View File

@@ -43,16 +43,16 @@ if sys.platform == "win32":
buildOptions = dict( buildOptions = dict(
compressed=False, compressed=False,
include_files=include_files, include_files=include_files,
icon='share:flatcam_icon48.ico', icon='share/flatcam_icon48.ico',
# excludes=['PyQt4', 'tk', 'tcl'] # excludes=['PyQt4', 'tk', 'tcl']
excludes=['scipy.lib.lapack.flapack.pyd', excludes=['scipy.lib.lapack.flapack.pyd',
'scipy.lib.blas.fblas.pyd', 'scipy.lib.blas.fblas.pyd',
'QtOpenGL4.dll'] '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( setup(
name="FlatCAM", name="FlatCAM",

View File

@@ -1,34 +1,34 @@
#import sys #import sys
import platform import platform
print "Platform", platform.system(), platform.release() print(("Platform", platform.system(), platform.release()))
print "Distro", platform.dist() print(("Distro", platform.dist()))
print "Python", platform.python_version() print(("Python", platform.python_version()))
import rtree import rtree
print "rtree", rtree.__version__ print(("rtree", rtree.__version__))
import shapely import shapely
import shapely.geos import shapely.geos
print "shapely", shapely.__version__ print(("shapely", shapely.__version__))
print "GEOS library", shapely.geos.geos_version print(("GEOS library", shapely.geos.geos_version))
from PyQt4 import Qt from PyQt4 import Qt
print "Qt", Qt.qVersion() print(("Qt", Qt.qVersion()))
import numpy import numpy
print "Numpy", numpy.__version__ print(("Numpy", numpy.__version__))
import matplotlib import matplotlib
print "MatPlotLib", matplotlib.__version__ print(("MatPlotLib", matplotlib.__version__))
print "MPL Numpy", matplotlib.__version__numpy__ print(("MPL Numpy", matplotlib.__version__numpy__))

View File

@@ -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) current_y = parse_gerber_number(match.group(3), frac_digits)
if distance(coords, (current_x, current_y)) <= tol: 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: except Exception as e:
print str(e) print((str(e)))
print line_num, ":", line.strip('\n\r') print((line_num, ":", line.strip('\n\r')))
if __name__ == "__main__": if __name__ == "__main__":

View File

@@ -521,6 +521,6 @@ if __name__ == "__main__":
tree = ET.parse('tests/svg/drawing.svg') tree = ET.parse('tests/svg/drawing.svg')
root = tree.getroot() root = tree.getroot()
ns = re.search(r'\{(.*)\}', root.tag).group(1) ns = re.search(r'\{(.*)\}', root.tag).group(1)
print ns print(ns)
for geo in getsvggeo(root): for geo in getsvggeo(root):
print geo print(geo)

View File

@@ -5,6 +5,7 @@ import abc
import collections import collections
from PyQt4 import QtCore from PyQt4 import QtCore
from contextlib import contextmanager from contextlib import contextmanager
from FlatCAMObj import FlatCAMGerber, FlatCAMExcellon, FlatCAMGeometry, FlatCAMCNCjob, FlatCAMObj
class TclCommand(object): class TclCommand(object):
@@ -97,7 +98,7 @@ class TclCommand(object):
command_string = [] 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)) command_string.append(get_decorated_argument(arg_key, arg_type, True))
return "> " + alias_name + " " + " ".join(command_string) return "> " + alias_name + " " + " ".join(command_string)
@@ -147,7 +148,7 @@ class TclCommand(object):
for alias in self.aliases: for alias in self.aliases:
help_string.append(get_decorated_command(alias)) 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)) 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) # timeout is unique for signaled commands (this is not best oop practice, but much easier for now)
@@ -206,13 +207,13 @@ class TclCommand(object):
# check arguments # check arguments
idx = 0 idx = 0
arg_names_items = self.arg_names.items() arg_names_items = list(self.arg_names.items())
for argument in arguments: for argument in arguments:
if len(self.arg_names) > idx: if len(self.arg_names) > idx:
key, arg_type = arg_names_items[idx] key, arg_type = arg_names_items[idx]
try: try:
named_args[key] = arg_type(argument) 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'." self.raise_tcl_error("Cannot cast named argument '%s' to type %s with exception '%s'."
% (key, arg_type, str(e))) % (key, arg_type, str(e)))
else: else:
@@ -228,7 +229,7 @@ class TclCommand(object):
named_args[key] = self.option_types[key](options[key]) named_args[key] = self.option_types[key](options[key])
else: else:
named_args[key] = int(options[key]) 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'." self.raise_tcl_error("Cannot cast argument '-%s' to type '%s' with exception '%s'."
% (key, self.option_types[key], str(e))) % (key, self.option_types[key], str(e)))
@@ -292,7 +293,7 @@ class TclCommandSignaled(TclCommand):
""" """
!!! I left it here only for demonstration !!! !!! I left it here only for demonstration !!!
Go to TclCommandCncjob and into class definition put Go to TclCommandCncjob and into class definition put
class TclCommandCncjob(TclCommand.TclCommandSignaled): class TclCommandCncjob(TclCommandSignaled):
also change also change
obj.generatecncjob(use_thread = False, **args) obj.generatecncjob(use_thread = False, **args)
to to

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandAddCircle(TclCommand.TclCommand): class TclCommandAddCircle(TclCommand):
""" """
Tcl shell command to creates a circle in the given Geometry object. Tcl shell command to creates a circle in the given Geometry object.

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandAddPolygon(TclCommand.TclCommandSignaled): class TclCommandAddPolygon(TclCommandSignaled):
""" """
Tcl shell command to create a polygon in the given Geometry object Tcl shell command to create a polygon in the given Geometry object
""" """

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandAddPolyline(TclCommand.TclCommandSignaled): class TclCommandAddPolyline(TclCommandSignaled):
""" """
Tcl shell command to create a polyline in the given Geometry object Tcl shell command to create a polyline in the given Geometry object
""" """

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandAddRectangle(TclCommand.TclCommandSignaled): class TclCommandAddRectangle(TclCommandSignaled):
""" """
Tcl shell command to add a rectange to the given Geometry object. Tcl shell command to add a rectange to the given Geometry object.
""" """

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandAlignDrill(TclCommand.TclCommandSignaled): class TclCommandAlignDrill(TclCommandSignaled):
""" """
Tcl shell command to create excellon with drills for aligment. Tcl shell command to create excellon with drills for aligment.
""" """
@@ -180,7 +179,7 @@ class TclCommandAlignDrill(TclCommand.TclCommandSignaled):
name + "_aligndrill", name + "_aligndrill",
alligndrill_init_me) alligndrill_init_me)
except Exception, e: except Exception as e:
return "Operation failed: %s" % str(e) return "Operation failed: %s" % str(e)
else: else:
@@ -195,7 +194,7 @@ class TclCommandAlignDrill(TclCommand.TclCommandSignaled):
px = dist px = dist
py = dist py = dist
obj.app.new_object("excellon", name + "_alligndrill", alligndrill_init_me) obj.app.new_object("excellon", name + "_alligndrill", alligndrill_init_me)
except Exception, e: except Exception as e:
return "Operation failed: %s" % str(e) return "Operation failed: %s" % str(e)
return 'Ok' return 'Ok'

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandAlignDrillGrid(TclCommand.TclCommandSignaled): class TclCommandAlignDrillGrid(TclCommandSignaled):
""" """
Tcl shell command to create an Excellon object Tcl shell command to create an Excellon object
with drills for aligment grid. with drills for aligment grid.

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandCncjob(TclCommand.TclCommandSignaled): class TclCommandCncjob(TclCommandSignaled):
""" """
Tcl shell command to Generates a CNC Job from a Geometry Object. Tcl shell command to Generates a CNC Job from a Geometry Object.

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandCutout(TclCommand.TclCommand): class TclCommandCutout(TclCommand):
""" """
Tcl shell command to create a board cutout geometry. Tcl shell command to create a board cutout geometry.
@@ -95,5 +94,5 @@ class TclCommandCutout(TclCommand.TclCommand):
try: try:
obj.app.new_object("geometry", name + "_cutout", geo_init_me) obj.app.new_object("geometry", name + "_cutout", geo_init_me)
except Exception, e: except Exception as e:
return "Operation failed: %s" % str(e) return "Operation failed: %s" % str(e)

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandDelete(TclCommand.TclCommand): class TclCommandDelete(TclCommand):
""" """
Tcl shell command to delete an object. Tcl shell command to delete an object.

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandDrillcncjob(TclCommand.TclCommandSignaled): class TclCommandDrillcncjob(TclCommandSignaled):
""" """
Tcl shell command to Generates a Drill CNC Job from a Excellon Object. Tcl shell command to Generates a Drill CNC Job from a Excellon Object.
""" """

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandExportGcode(TclCommand.TclCommandSignaled): class TclCommandExportGcode(TclCommandSignaled):
""" """
Tcl shell command to export gcode as tcl output for "set X [export_gcode ...]" Tcl shell command to export gcode as tcl output for "set X [export_gcode ...]"

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandExportSVG(TclCommand.TclCommand): class TclCommandExportSVG(TclCommand):
""" """
Tcl shell command to export a Geometry Object as an SVG File. Tcl shell command to export a Geometry Object as an SVG File.

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandExteriors(TclCommand.TclCommandSignaled): class TclCommandExteriors(TclCommandSignaled):
""" """
Tcl shell command to get exteriors of polygons Tcl shell command to get exteriors of polygons
""" """
@@ -54,7 +53,7 @@ class TclCommandExteriors(TclCommand.TclCommandSignaled):
if obj is None: if obj is None:
self.raise_tcl_error("Object not found: %s" % name) 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))) self.raise_tcl_error('Expected Geometry, got %s %s.' % (name, type(obj)))
def geo_init(geo_obj, app_obj): def geo_init(geo_obj, app_obj):

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandGeoCutout(TclCommand.TclCommandSignaled): class TclCommandGeoCutout(TclCommandSignaled):
""" """
Tcl shell command to cut holding gaps from geometry. Tcl shell command to cut holding gaps from geometry.
""" """

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandGeoUnion(TclCommand.TclCommand): class TclCommandGeoUnion(TclCommand):
""" """
Tcl shell command to run a union (addition) operation on the Tcl shell command to run a union (addition) operation on the
components of a geometry object. components of a geometry object.

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandGetNames(TclCommand.TclCommand): class TclCommandGetNames(TclCommand):
""" """
Tcl shell command to set an object as active in the GUI. Tcl shell command to set an object as active in the GUI.

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandGetSys(TclCommand.TclCommand): class TclCommandGetSys(TclCommand):
""" """
Tcl shell command to get the value of a system variable Tcl shell command to get the value of a system variable

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandImportSvg(TclCommand.TclCommandSignaled): class TclCommandImportSvg(TclCommandSignaled):
""" """
Tcl shell command to import an SVG file as a Geometry Object. Tcl shell command to import an SVG file as a Geometry Object.
""" """

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandInteriors(TclCommand.TclCommandSignaled): class TclCommandInteriors(TclCommandSignaled):
""" """
Tcl shell command to get interiors of polygons Tcl shell command to get interiors of polygons
""" """

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandIsolate(TclCommand.TclCommandSignaled): class TclCommandIsolate(TclCommandSignaled):
""" """
Tcl shell command to Creates isolation routing geometry for the given Gerber. Tcl shell command to Creates isolation routing geometry for the given Gerber.

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandJoinExcellon(TclCommand.TclCommand): class TclCommandJoinExcellon(TclCommand):
""" """
Tcl shell command to merge Excellon objects. Tcl shell command to merge Excellon objects.

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandJoinGeometry(TclCommand.TclCommand): class TclCommandJoinGeometry(TclCommand):
""" """
Tcl shell command to merge Excellon objects. Tcl shell command to merge Excellon objects.

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandMillHoles(TclCommand.TclCommandSignaled): class TclCommandMillHoles(TclCommandSignaled):
""" """
Tcl shell command to Create Geometry Object for milling holes from Excellon. Tcl shell command to Create Geometry Object for milling holes from Excellon.

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandMirror(TclCommand.TclCommandSignaled): class TclCommandMirror(TclCommandSignaled):
""" """
Tcl shell command to mirror an object. Tcl shell command to mirror an object.
""" """
@@ -90,7 +89,7 @@ class TclCommandMirror(TclCommand.TclCommandSignaled):
obj.mirror(axis, [px, py]) obj.mirror(axis, [px, py])
obj.plot() obj.plot()
except Exception, e: except Exception as e:
return "Operation failed: %s" % str(e) return "Operation failed: %s" % str(e)
else: else:
@@ -104,5 +103,5 @@ class TclCommandMirror(TclCommand.TclCommandSignaled):
try: try:
obj.mirror(axis, [dist, dist]) obj.mirror(axis, [dist, dist])
obj.plot() obj.plot()
except Exception, e: except Exception as e:
return "Operation failed: %s" % str(e) return "Operation failed: %s" % str(e)

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandNew(TclCommand.TclCommand): class TclCommandNew(TclCommand):
""" """
Tcl shell command to starts a new project. Clears objects from memory Tcl shell command to starts a new project. Clears objects from memory
""" """

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandNewGeometry(TclCommand.TclCommandSignaled): class TclCommandNewGeometry(TclCommandSignaled):
""" """
Tcl shell command to subtract polygon from the given Geometry object. Tcl shell command to subtract polygon from the given Geometry object.
""" """

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandOffset(TclCommand.TclCommand): class TclCommandOffset(TclCommand):
""" """
Tcl shell command to change the position of the object. Tcl shell command to change the position of the object.

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandOpenExcellon(TclCommand.TclCommandSignaled): class TclCommandOpenExcellon(TclCommandSignaled):
""" """
Tcl shell command to open an Excellon file. Tcl shell command to open an Excellon file.
""" """

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandOpenGCode(TclCommand.TclCommandSignaled): class TclCommandOpenGCode(TclCommandSignaled):
""" """
Tcl shell command to open a G-Code file. Tcl shell command to open a G-Code file.
""" """

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandOpenGerber(TclCommand.TclCommandSignaled): class TclCommandOpenGerber(TclCommandSignaled):
""" """
Tcl shell command to opens a Gerber file Tcl shell command to opens a Gerber file
""" """
@@ -48,7 +47,7 @@ class TclCommandOpenGerber(TclCommand.TclCommandSignaled):
# How the object should be initialized # How the object should be initialized
def obj_init(gerber_obj, app_obj): 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))) self.raise_tcl_error('Expected FlatCAMGerber, got %s %s.' % (outname, type(gerber_obj)))
# Opening the file happens here # Opening the file happens here
@@ -61,7 +60,7 @@ class TclCommandOpenGerber(TclCommand.TclCommandSignaled):
app_obj.progress.emit(0) app_obj.progress.emit(0)
self.raise_tcl_error('Failed to open file: %s' % filename) 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.inform.emit("[error] Failed to parse file: %s, %s " % (filename, str(e)))
app_obj.progress.emit(0) app_obj.progress.emit(0)
self.log.error(str(e)) self.log.error(str(e))

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandOpenProject(TclCommand.TclCommandSignaled): class TclCommandOpenProject(TclCommandSignaled):
""" """
Tcl shell command to open a FlatCAM project. Tcl shell command to open a FlatCAM project.
""" """

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandOptions(TclCommand.TclCommandSignaled): class TclCommandOptions(TclCommandSignaled):
""" """
Tcl shell command to open an Excellon file. Tcl shell command to open an Excellon file.
""" """

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandPaint(TclCommand.TclCommandSignaled): class TclCommandPaint(TclCommandSignaled):
""" """
Paint the interior of polygons Paint the interior of polygons
""" """

View File

@@ -1,10 +1,8 @@
from ObjectCollection import *
from copy import copy,deepcopy from copy import copy,deepcopy
from tclCommands.TclCommand import *
import TclCommand
class TclCommandPanelize(TclCommand.TclCommand): class TclCommandPanelize(TclCommand):
""" """
Tcl shell command to pannelize an object. Tcl shell command to pannelize an object.
@@ -13,7 +11,7 @@ class TclCommandPanelize(TclCommand.TclCommand):
""" """
# List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) # 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 # Dictionary of types from Tcl command, needs to be ordered
arg_names = collections.OrderedDict([ arg_names = collections.OrderedDict([
@@ -130,10 +128,9 @@ class TclCommandPanelize(TclCommand.TclCommand):
for col in range(args['columns']): for col in range(args['columns']):
local_outname = outname + ".tmp." + str(col) + "." + str(row) local_outname = outname + ".tmp." + str(col) + "." + str(row)
if isinstance(obj, FlatCAMExcellon): 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: else:
self.app.new_object("geometry", local_outname, initialize_local) self.app.new_object("geometry", local_outname, initialize_local, plot=False)
currentx += lenghtx currentx += lenghtx
currenty += lenghty currenty += lenghty

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandPlot(TclCommand.TclCommand): class TclCommandPlot(TclCommand):
""" """
Tcl shell command to update the plot on the user interface. Tcl shell command to update the plot on the user interface.

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandSaveProject(TclCommand.TclCommandSignaled): class TclCommandSaveProject(TclCommandSignaled):
""" """
Tcl shell command to save the FlatCAM project to file. Tcl shell command to save the FlatCAM project to file.
""" """

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandScale(TclCommand.TclCommand): class TclCommandScale(TclCommand):
""" """
Tcl shell command to resizes the object by a factor. Tcl shell command to resizes the object by a factor.

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandSetActive(TclCommand.TclCommand): class TclCommandSetActive(TclCommand):
""" """
Tcl shell command to set an object as active in the GUI. Tcl shell command to set an object as active in the GUI.

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandSetSys(TclCommand.TclCommand): class TclCommandSetSys(TclCommand):
""" """
Tcl shell command to set the value of a system variable Tcl shell command to set the value of a system variable

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandSubtractPoly(TclCommand.TclCommandSignaled): class TclCommandSubtractPoly(TclCommandSignaled):
""" """
Tcl shell command to create a new empty Geometry object. Tcl shell command to create a new empty Geometry object.
""" """

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandSubtractRectangle(TclCommand.TclCommandSignaled): class TclCommandSubtractRectangle(TclCommandSignaled):
""" """
Tcl shell command to subtract a rectange from the given Geometry object. Tcl shell command to subtract a rectange from the given Geometry object.
""" """

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandVersion(TclCommand.TclCommand): class TclCommandVersion(TclCommand):
""" """
Tcl shell command to check the program version. Tcl shell command to check the program version.

View File

@@ -1,8 +1,7 @@
from ObjectCollection import * from tclCommands.TclCommand import *
import TclCommand
class TclCommandWriteGCode(TclCommand.TclCommandSignaled): class TclCommandWriteGCode(TclCommandSignaled):
""" """
Tcl shell command to save the G-code of a CNC Job object to file. Tcl shell command to save the G-code of a CNC Job object to file.
""" """

View File

@@ -72,9 +72,9 @@ def register_all_commands(app, commands):
:return: None :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': if key != 'tclCommands.TclCommand':
class_name = key.split('.')[1] class_name = key.split('.')[1]
class_type = getattr(mod, class_name) class_type = getattr(mod, class_name)

View File

@@ -3,7 +3,7 @@ Terminal emulator widget.
Shows intput and output text. Allows to enter commands. Supports history. Shows intput and output text. Allows to enter commands. Supports history.
""" """
import cgi import html
from PyQt4.QtCore import pyqtSignal, Qt from PyQt4.QtCore import pyqtSignal, Qt
from PyQt4.QtGui import QColor, QKeySequence, QLineEdit, QPalette, \ from PyQt4.QtGui import QColor, QKeySequence, QLineEdit, QPalette, \
QSizePolicy, QTextCursor, QTextEdit, \ QSizePolicy, QTextCursor, QTextEdit, \
@@ -151,7 +151,7 @@ class TermWidget(QWidget):
""" """
assert style in ('in', 'out', 'err') assert style in ('in', 'out', 'err')
text = cgi.escape(text) text = html.escape(text)
text = text.replace('\n', '<br/>') text = text.replace('\n', '<br/>')
if style == 'in': if style == 'in':

View File

@@ -1,9 +1,9 @@
from __future__ import division
import matplotlib import matplotlib
matplotlib.use('Agg') matplotlib.use('Agg')
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import numpy as np import numpy as np
import cStringIO import io
from matplotlib.backends.backend_agg import FigureCanvasAgg from matplotlib.backends.backend_agg import FigureCanvasAgg
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg
from matplotlib.figure import Figure from matplotlib.figure import Figure

View File

@@ -8,7 +8,7 @@ class MyObj():
pass pass
def __del__(self): def __del__(self):
print "##### Destroyed ######" print("##### Destroyed ######")
def parse(): def parse():

View File

@@ -26,12 +26,12 @@ for geo in geoms:
current_pt = (0, 0) current_pt = (0, 0)
pt, geo = s.nearest(current_pt) pt, geo = s.nearest(current_pt)
while geo is not None: while geo is not None:
print pt, geo print((pt, geo))
print "OBJECTS BEFORE:", s.objects print(("OBJECTS BEFORE:", s.objects))
#geo.coords = list(geo.coords[::-1]) #geo.coords = list(geo.coords[::-1])
s.remove(geo) s.remove(geo)
print "OBJECTS AFTER:", s.objects print(("OBJECTS AFTER:", s.objects))
current_pt = geo.coords[-1] current_pt = geo.coords[-1]
pt, geo = s.nearest(current_pt) pt, geo = s.nearest(current_pt)

View File

@@ -13,12 +13,12 @@ rt = rtindex.Index(properties=p)
# If interleaved is True, the coordinates must be in # If interleaved is True, the coordinates must be in
# the form [xmin, ymin, ..., kmin, xmax, ymax, ..., kmax]. # the form [xmin, ymin, ..., kmin, xmax, ymax, ..., kmax].
print rt.interleaved print((rt.interleaved))
[rt.add(0, pt2rect(pt)) for pt in pts] [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: for pt in pts:
rt.delete(0, pt2rect(pt)) 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))]))

View File

@@ -36,18 +36,18 @@ class ExcellonFlowTestCase(unittest.TestCase):
def test_flow(self): def test_flow(self):
# Names of available objects. # Names of available objects.
names = self.fc.collection.get_names() names = self.fc.collection.get_names()
print names print(names)
#-------------------------------------- #--------------------------------------
# Total of 1 objects. # Total of 1 objects.
#-------------------------------------- #--------------------------------------
self.assertEquals(len(names), 1, self.assertEqual(len(names), 1,
"Expected 1 object, found %d" % len(names)) "Expected 1 object, found %d" % len(names))
#-------------------------------------- #--------------------------------------
# Object's name matches the file name. # 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])) "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. # TODO: Open GUI with double-click on object.
# Opens the Object's GUI, populates it. # Opens the Object's GUI, populates it.
excellon_obj.build_ui() excellon_obj.build_ui()
for option, value in excellon_obj.options.iteritems(): for option, value in list(excellon_obj.options.items()):
try: try:
form_field = excellon_obj.form_fields[option] form_field = excellon_obj.form_fields[option]
except KeyError: except KeyError:
print ("**********************************************************\n" print(("**********************************************************\n"
"* WARNING: Option '{}' has no form field\n" "* WARNING: Option '{}' has no form field\n"
"**********************************************************" "**********************************************************"
"".format(option)) "".format(option)))
continue continue
self.assertEqual(value, form_field.get_value(), self.assertEqual(value, form_field.get_value(),
"Option '{}' == {} but form has {}".format( "Option '{}' == {} but form has {}".format(
@@ -87,7 +87,7 @@ class ExcellonFlowTestCase(unittest.TestCase):
form_field = excellon_obj.form_fields['feedrate'] form_field = excellon_obj.form_fields['feedrate']
value = form_field.get_value() value = form_field.get_value()
form_field.set_value(value * 1.1) # Increase by 10% form_field.set_value(value * 1.1) # Increase by 10%
print "'feedrate' == {}".format(value) print(("'feedrate' == {}".format(value)))
#-------------------------------------------------- #--------------------------------------------------
# Create GCode using all tools. # Create GCode using all tools.
@@ -119,7 +119,7 @@ class ExcellonFlowTestCase(unittest.TestCase):
self.assertEqual(value, form_value, self.assertEqual(value, form_value,
"Form value for '{}' == {} was not read into options" "Form value for '{}' == {} was not read into options"
"which has {}".format('feedrate', form_value, value)) "which has {}".format('feedrate', form_value, value))
print "'feedrate' == {}".format(value) print(("'feedrate' == {}".format(value)))
#--------------------------------------------- #---------------------------------------------
# Check that only 1 object has been created. # Check that only 1 object has been created.
@@ -160,4 +160,4 @@ class ExcellonFlowTestCase(unittest.TestCase):
self.assertTrue(os.path.isfile(output_filename)) self.assertTrue(os.path.isfile(output_filename))
os.remove(output_filename) os.remove(output_filename)
print names print(names)

View File

@@ -36,18 +36,18 @@ class GerberFlowTestCase(unittest.TestCase):
def test_flow(self): def test_flow(self):
# Names of available objects. # Names of available objects.
names = self.fc.collection.get_names() names = self.fc.collection.get_names()
print names print(names)
#-------------------------------------- #--------------------------------------
# Total of 1 objects. # Total of 1 objects.
#-------------------------------------- #--------------------------------------
self.assertEquals(len(names), 1, self.assertEqual(len(names), 1,
"Expected 1 object, found %d" % len(names)) "Expected 1 object, found %d" % len(names))
#-------------------------------------- #--------------------------------------
# Object's name matches the file name. # 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])) "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. # TODO: Open GUI with double-click on object.
# Opens the Object's GUI, populates it. # Opens the Object's GUI, populates it.
gerber_obj.build_ui() gerber_obj.build_ui()
for option, value in gerber_obj.options.iteritems(): for option, value in list(gerber_obj.options.items()):
try: try:
form_field = gerber_obj.form_fields[option] form_field = gerber_obj.form_fields[option]
except KeyError: except KeyError:
print ("**********************************************************\n" print(("**********************************************************\n"
"* WARNING: Option '{}' has no form field\n" "* WARNING: Option '{}' has no form field\n"
"**********************************************************" "**********************************************************"
"".format(option)) "".format(option)))
continue continue
self.assertEqual(value, form_field.get_value(), self.assertEqual(value, form_field.get_value(),
"Option '{}' == {} but form has {}".format( "Option '{}' == {} but form has {}".format(
@@ -87,7 +87,7 @@ class GerberFlowTestCase(unittest.TestCase):
form_field = gerber_obj.form_fields['isotooldia'] form_field = gerber_obj.form_fields['isotooldia']
value = form_field.get_value() value = form_field.get_value()
form_field.set_value(value * 1.1) # Increase by 10% form_field.set_value(value * 1.1) # Increase by 10%
print "'isotooldia' == {}".format(value) print(("'isotooldia' == {}".format(value)))
#-------------------------------------------------- #--------------------------------------------------
# Create isolation routing using default values # Create isolation routing using default values
@@ -110,7 +110,7 @@ class GerberFlowTestCase(unittest.TestCase):
self.assertEqual(value, form_value, self.assertEqual(value, form_value,
"Form value for '{}' == {} was not read into options" "Form value for '{}' == {} was not read into options"
"which has {}".format('isotooldia', form_value, value)) "which has {}".format('isotooldia', form_value, value))
print "'isotooldia' == {}".format(value) print(("'isotooldia' == {}".format(value)))
#--------------------------------------------- #---------------------------------------------
# Check that only 1 object has been created. # Check that only 1 object has been created.
@@ -187,4 +187,4 @@ class GerberFlowTestCase(unittest.TestCase):
self.assertTrue(os.path.isfile(output_filename)) self.assertTrue(os.path.isfile(output_filename))
os.remove(output_filename) os.remove(output_filename)
print names print(names)

View File

@@ -75,66 +75,66 @@ class PaintConnectTest(PaintTestCase):
self.boundary = Polygon([[0, 0], [0, 5], [5, 5], [5, 0]]) self.boundary = Polygon([[0, 0], [0, 5], [5, 5], [5, 0]])
def test_jump(self): def test_jump(self):
print "Test: WALK Expected" print("Test: WALK Expected")
paths = [ paths = [
LineString([[0.5, 2], [2, 4.5]]), LineString([[0.5, 2], [2, 4.5]]),
LineString([[2, 0.5], [4.5, 2]]) LineString([[2, 0.5], [4.5, 2]])
] ]
for p in paths: for p in paths:
print p print(p)
tooldia = 1.0 tooldia = 1.0
print "--" print("--")
result = Geometry.paint_connect(mkstorage(deepcopy(paths)), self.boundary, tooldia) result = Geometry.paint_connect(mkstorage(deepcopy(paths)), self.boundary, tooldia)
result = list(result.get_objects()) result = list(result.get_objects())
for r in result: for r in result:
print r print(r)
self.assertEqual(len(result), 1) self.assertEqual(len(result), 1)
# self.plot_summary_A(paths, tooldia, result, "WALK expected.") # self.plot_summary_A(paths, tooldia, result, "WALK expected.")
def test_no_jump1(self): def test_no_jump1(self):
print "Test: FLY Expected" print("Test: FLY Expected")
paths = [ paths = [
LineString([[0, 2], [2, 5]]), LineString([[0, 2], [2, 5]]),
LineString([[2, 0], [5, 2]]) LineString([[2, 0], [5, 2]])
] ]
for p in paths: for p in paths:
print p print(p)
tooldia = 1.0 tooldia = 1.0
print "--" print("--")
result = Geometry.paint_connect(mkstorage(deepcopy(paths)), self.boundary, tooldia) result = Geometry.paint_connect(mkstorage(deepcopy(paths)), self.boundary, tooldia)
result = list(result.get_objects()) result = list(result.get_objects())
for r in result: for r in result:
print r print(r)
self.assertEqual(len(result), len(paths)) self.assertEqual(len(result), len(paths))
# self.plot_summary_A(paths, tooldia, result, "FLY Expected") # self.plot_summary_A(paths, tooldia, result, "FLY Expected")
def test_no_jump2(self): def test_no_jump2(self):
print "Test: FLY Expected" print("Test: FLY Expected")
paths = [ paths = [
LineString([[0.5, 2], [2, 4.5]]), LineString([[0.5, 2], [2, 4.5]]),
LineString([[2, 0.5], [4.5, 2]]) LineString([[2, 0.5], [4.5, 2]])
] ]
for p in paths: for p in paths:
print p print(p)
tooldia = 1.1 tooldia = 1.1
print "--" print("--")
result = Geometry.paint_connect(mkstorage(deepcopy(paths)), self.boundary, tooldia) result = Geometry.paint_connect(mkstorage(deepcopy(paths)), self.boundary, tooldia)
result = list(result.get_objects()) result = list(result.get_objects())
for r in result: for r in result:
print r print(r)
self.assertEqual(len(result), len(paths)) self.assertEqual(len(result), len(paths))
@@ -153,22 +153,22 @@ class PaintConnectTest2(PaintTestCase):
) )
def test_no_jump3(self): def test_no_jump3(self):
print "TEST: No jump expected" print("TEST: No jump expected")
paths = [ paths = [
LineString([[0.5, 1], [1.5, 3]]), LineString([[0.5, 1], [1.5, 3]]),
LineString([[4, 1], [4, 4]]) LineString([[4, 1], [4, 4]])
] ]
for p in paths: for p in paths:
print p print(p)
tooldia = 1.0 tooldia = 1.0
print "--" print("--")
result = Geometry.paint_connect(mkstorage(deepcopy(paths)), self.boundary, tooldia) result = Geometry.paint_connect(mkstorage(deepcopy(paths)), self.boundary, tooldia)
result = list(result.get_objects()) result = list(result.get_objects())
for r in result: for r in result:
print r print(r)
self.assertEqual(len(result), len(paths)) self.assertEqual(len(result), len(paths))
@@ -182,26 +182,26 @@ class PaintConnectTest3(PaintTestCase):
def setUp(self): def setUp(self):
self.boundary = Polygon([[0, 0], [0, 5], [5, 5], [5, 0]]) self.boundary = Polygon([[0, 0], [0, 5], [5, 5], [5, 0]])
print "TEST w/ LinearRings" print("TEST w/ LinearRings")
def test_jump2(self): def test_jump2(self):
print "Test: WALK Expected" print("Test: WALK Expected")
paths = [ paths = [
LineString([[0.5, 2], [2, 4.5]]), LineString([[0.5, 2], [2, 4.5]]),
LineString([[2, 0.5], [4.5, 2]]), LineString([[2, 0.5], [4.5, 2]]),
self.boundary.buffer(-0.5).exterior self.boundary.buffer(-0.5).exterior
] ]
for p in paths: for p in paths:
print p print(p)
tooldia = 1.0 tooldia = 1.0
print "--" print("--")
result = Geometry.paint_connect(mkstorage(deepcopy(paths)), self.boundary, tooldia) result = Geometry.paint_connect(mkstorage(deepcopy(paths)), self.boundary, tooldia)
result = list(result.get_objects()) result = list(result.get_objects())
for r in result: for r in result:
print r print(r)
self.assertEqual(len(result), 1) self.assertEqual(len(result), 1)

View File

@@ -20,7 +20,7 @@ def mkstorage(paths):
class PathConnectTest1(unittest.TestCase): class PathConnectTest1(unittest.TestCase):
def setUp(self): def setUp(self):
print "PathConnectTest1.setUp()" print("PathConnectTest1.setUp()")
pass pass
def test_simple_connect(self): def test_simple_connect(self):
@@ -68,8 +68,8 @@ class PathConnectTest1(unittest.TestCase):
[2 + offset_x, 1 + offset_y]]))) [2 + offset_x, 1 + offset_y]])))
def test_ring_interfere_connect(self): def test_ring_interfere_connect(self):
print print()
print "TEST STARTING ..." print("TEST STARTING ...")
paths = [ paths = [
LineString([[0, 0], [1, 1]]), LineString([[0, 0], [1, 1]]),

View File

@@ -30,9 +30,9 @@ class PolyPaintTestCase(unittest.TestCase):
def test_poly_paint_svg_all(self): def test_poly_paint_svg_all(self):
print "*********************************" print("*********************************")
print "* svg_all *" print("* svg_all *")
print "*********************************" print("*********************************")
# Clear workspace # Clear workspace
self.fc.on_file_new() self.fc.on_file_new()
@@ -69,9 +69,9 @@ class PolyPaintTestCase(unittest.TestCase):
def test_poly_paint_svg_click(self): def test_poly_paint_svg_click(self):
print "*********************************" print("*********************************")
print "* svg_click *" print("* svg_click *")
print "*********************************" print("*********************************")
# Clear workspace # Clear workspace
self.fc.on_file_new() self.fc.on_file_new()
@@ -109,9 +109,9 @@ class PolyPaintTestCase(unittest.TestCase):
def test_poly_paint_noncopper_all(self): def test_poly_paint_noncopper_all(self):
print "*********************************" print("*********************************")
print "* noncopper_all *" print("* noncopper_all *")
print "*********************************" print("*********************************")
# Clear workspace # Clear workspace
self.fc.on_file_new() self.fc.on_file_new()
@@ -165,9 +165,9 @@ class PolyPaintTestCase(unittest.TestCase):
def test_poly_paint_noncopper_click(self): def test_poly_paint_noncopper_click(self):
print "*********************************" print("*********************************")
print "* noncopper_click *" print("* noncopper_click *")
print "*********************************" print("*********************************")
# Clear workspace # Clear workspace
self.fc.on_file_new() self.fc.on_file_new()

View File

@@ -29,18 +29,18 @@ class SVGFlowTestCase(unittest.TestCase):
self.fc.import_svg('tests/svg/' + self.filename) self.fc.import_svg('tests/svg/' + self.filename)
names = self.fc.collection.get_names() names = self.fc.collection.get_names()
print names print(names)
#-------------------------------------- #--------------------------------------
# Total of 1 objects. # Total of 1 objects.
#-------------------------------------- #--------------------------------------
self.assertEquals(len(names), 1, self.assertEqual(len(names), 1,
"Expected 1 object, found %d" % len(names)) "Expected 1 object, found %d" % len(names))
#-------------------------------------- #--------------------------------------
# Object's name matches the file name. # 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])) "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. # TODO: Open GUI with double-click on object.
# Opens the Object's GUI, populates it. # Opens the Object's GUI, populates it.
geo_obj.build_ui() geo_obj.build_ui()
for option, value in geo_obj.options.iteritems(): for option, value in list(geo_obj.options.items()):
try: try:
form_field = geo_obj.form_fields[option] form_field = geo_obj.form_fields[option]
except KeyError: except KeyError:
print ("**********************************************************\n" print(("**********************************************************\n"
"* WARNING: Option '{}' has no form field\n" "* WARNING: Option '{}' has no form field\n"
"**********************************************************" "**********************************************************"
"".format(option)) "".format(option)))
continue continue
self.assertEqual(value, form_field.get_value(), self.assertEqual(value, form_field.get_value(),
"Option '{}' == {} but form has {}".format( "Option '{}' == {} but form has {}".format(
@@ -126,4 +126,4 @@ class SVGFlowTestCase(unittest.TestCase):
self.assertTrue(os.path.isfile(output_filename)) self.assertTrue(os.path.isfile(output_filename))
os.remove(output_filename) os.remove(output_filename)
print names print(names)

View File

@@ -2,17 +2,17 @@ import pkgutil
import sys import sys
# allowed command tests (please append them alphabetically ordered) # allowed command tests (please append them alphabetically ordered)
from test_TclCommandAddPolygon import * from .test_TclCommandAddPolygon import *
from test_TclCommandAddPolyline import * from .test_TclCommandAddPolyline import *
from test_TclCommandCncjob import * from .test_TclCommandCncjob import *
from test_TclCommandDrillcncjob import * from .test_TclCommandDrillcncjob import *
from test_TclCommandExportGcode import * from .test_TclCommandExportGcode import *
from test_TclCommandExteriors import * from .test_TclCommandExteriors import *
from test_TclCommandImportSvg import * from .test_TclCommandImportSvg import *
from test_TclCommandInteriors import * from .test_TclCommandInteriors import *
from test_TclCommandIsolate import * from .test_TclCommandIsolate import *
from test_TclCommandNew import * from .test_TclCommandNew import *
from test_TclCommandNewGeometry import * from .test_TclCommandNewGeometry import *
from test_TclCommandOpenExcellon import * from .test_TclCommandOpenExcellon import *
from test_TclCommandOpenGerber import * from .test_TclCommandOpenGerber import *
from test_TclCommandPaintPolygon import * from .test_TclCommandPaintPolygon import *

View File

@@ -1,5 +1,5 @@
from FlatCAMObj import FlatCAMGerber, FlatCAMGeometry, FlatCAMObj from FlatCAMObj import FlatCAMGerber, FlatCAMGeometry, FlatCAMObj
from test_TclCommandIsolate import * from .test_TclCommandIsolate import *
def test_cncjob(self): def test_cncjob(self):
""" """

View File

@@ -1,5 +1,5 @@
from FlatCAMObj import FlatCAMObj from FlatCAMObj import FlatCAMObj
from test_TclCommandOpenExcellon import * from .test_TclCommandOpenExcellon import *
def test_drillcncjob(self): def test_drillcncjob(self):

View File

@@ -1,8 +1,8 @@
import os import os
import tempfile import tempfile
from test_TclCommandCncjob import * from .test_TclCommandCncjob import *
from test_TclCommandDrillcncjob import * from .test_TclCommandDrillcncjob import *
def test_export_gcodecncjob(self): def test_export_gcodecncjob(self):

View File

@@ -82,7 +82,7 @@ class TclShellTest(unittest.TestCase):
# Units must be IN # Units must be IN
#---------------------------------------- #----------------------------------------
units = self.fc.exec_command_test('get_sys units') units = self.fc.exec_command_test('get_sys units')
self.assertEquals(units, "IN") self.assertEqual(units, "IN")
# MM # MM
self.fc.exec_command_test('set_sys units MM') self.fc.exec_command_test('set_sys units MM')
@@ -92,7 +92,7 @@ class TclShellTest(unittest.TestCase):
# Units must be MM # Units must be MM
#---------------------------------------- #----------------------------------------
units = self.fc.exec_command_test('get_sys units') units = self.fc.exec_command_test('get_sys units')
self.assertEquals(units, "MM") self.assertEqual(units, "MM")
def test_gerber_flow(self): def test_gerber_flow(self):
""" """