- fixed bug in NCC Tool: after trying to add a tool already in the Tool Table when trying to change the Tool Type the GUI does not change

- final fix for app not quiting when running a script as argument, script that has the quit_flatcam Tcl command; fixed issue #360
- fixed issue #363. The Tcl command drillcncjob does not create tool cut, does not allow creation of gcode, it forces the usage of dwell and dwelltime parameters
This commit is contained in:
Marius Stanciu 2020-01-01 16:13:33 +02:00 committed by Marius
parent c8955e0a00
commit 3475ae00cd
10 changed files with 116 additions and 80 deletions

View File

@ -20,7 +20,6 @@ import shutil
import stat
from stat import S_IREAD, S_IRGRP, S_IROTH
import subprocess
import ctypes
# import tkinter as tk
@ -39,7 +38,7 @@ import gc
from xml.dom.minidom import parseString as parse_xml_string
from multiprocessing.connection import Listener, Client
from multiprocessing import Pool, cpu_count
from multiprocessing import Pool
import socket
from array import array
@ -241,6 +240,9 @@ class App(QtCore.QObject):
# signal emitted when jumping
jump_signal = pyqtSignal(tuple)
# close app signal
close_app_signal = pyqtSignal()
def __init__(self, user_defaults=True):
"""
Starts the application.
@ -2011,8 +2013,6 @@ class App(QtCore.QObject):
self.ui.pref_close_button.clicked.connect(self.on_pref_close_button)
self.ui.pref_defaults_button.clicked.connect(self.on_restore_defaults_preferences)
self.ui.pref_open_button.clicked.connect(self.on_preferences_open_folder)
self.ui.clear_btn.clicked.connect(self.on_gui_clear)
# #############################################################################
# ######################### GUI PREFERENCES SIGNALS ###########################
@ -2136,6 +2136,8 @@ class App(QtCore.QObject):
self.ui.grid_snap_btn.triggered.connect(self.on_grid_snap_triggered)
# signal to close the application
self.close_app_signal.connect(self.kill_app)
# #####################################################################################
# ########### FINISHED CONNECTING SIGNALS #############################################
# #####################################################################################
@ -2695,20 +2697,24 @@ class App(QtCore.QObject):
sys.exit(2)
if self.cmd_line_shellfile:
try:
if self.cmd_line_headless != 1:
if self.ui.shell_dock.isHidden():
self.ui.shell_dock.show()
try:
with open(self.cmd_line_shellfile, "r") as myfile:
if show_splash:
self.splash.showMessage('%s: %ssec\n%s' % (
_("Canvas initialization started.\n"
"Canvas initialization finished in"), '%.2f' % self.used_time,
_("Executing Tcl Script ...")),
alignment=Qt.AlignBottom | Qt.AlignLeft,
color=QtGui.QColor("gray"))
# if show_splash:
# self.splash.showMessage('%s: %ssec\n%s' % (
# _("Canvas initialization started.\n"
# "Canvas initialization finished in"), '%.2f' % self.used_time,
# _("Executing Tcl Script ...")),
# alignment=Qt.AlignBottom | Qt.AlignLeft,
# color=QtGui.QColor("gray"))
cmd_line_shellfile_text = myfile.read()
self.shell._sysShell.exec_command(cmd_line_shellfile_text)
if self.cmd_line_headless != 1:
self.shell._sysShell.exec_command(cmd_line_shellfile_text)
else:
self.shell._sysShell.exec_command(cmd_line_shellfile_text, no_echo=True)
except Exception as ext:
print("ERROR: ", ext)
sys.exit(2)
@ -3606,7 +3612,7 @@ class App(QtCore.QObject):
try:
if no_echo is False:
self.shell.open_proccessing() # Disables input box.
self.shell.open_processing() # Disables input box.
result = self.tcl.eval(str(tcl_command_string))
if result != 'None' and no_echo is False:
@ -3624,7 +3630,7 @@ class App(QtCore.QObject):
raise e
finally:
if no_echo is False:
self.shell.close_proccessing()
self.shell.close_processing()
pass
return result
@ -3978,58 +3984,13 @@ class App(QtCore.QObject):
json.dump(defaults_from_file, f, default=to_dict, indent=2, sort_keys=True)
f.close()
except Exception:
self.inform.emit('[ERROR_NOTCL] %s' % _("Failed to write defaults to file."))
self.inform.emit('[ERROR_NOTCL] %s %s' % (_("Failed to write defaults to file."), str(filename)))
return
if self.defaults["global_open_style"] is False:
self.file_opened.emit("preferences", filename)
self.file_saved.emit("preferences", filename)
self.inform.emit('[success] %s: %s' % (_("Exported preferences to"), filename))
def on_preferences_open_folder(self):
"""
Will open an Explorer window set to the folder path where the FlatCAM preferences files are usually saved.
:return: None
"""
self.report_usage("on_preferences_open_folder()")
if sys.platform == 'win32':
subprocess.Popen('explorer %s' % self.data_path)
elif sys.platform == 'darwin':
os.system('open "%s"' % self.data_path)
else:
subprocess.Popen(['xdg-open', self.data_path])
self.inform.emit('[success] %s' %
_("FlatCAM Preferences Folder opened."))
def on_gui_clear(self):
theme_settings = QtCore.QSettings("Open Source", "FlatCAM")
theme_settings.setValue('theme', 'white')
del theme_settings
resource_loc = 'share'
msgbox = QtWidgets.QMessageBox()
msgbox.setText(_("Are you sure you want to delete the GUI Settings? "
"\n")
)
msgbox.setWindowTitle(_("Clear GUI Settings"))
msgbox.setWindowIcon(QtGui.QIcon(resource_loc + '/trash32.png'))
bt_yes = msgbox.addButton(_('Yes'), QtWidgets.QMessageBox.YesRole)
bt_no = msgbox.addButton(_('No'), QtWidgets.QMessageBox.NoRole)
msgbox.setDefaultButton(bt_no)
msgbox.exec_()
response = msgbox.clickedButton()
if response == bt_yes:
settings = QSettings("Open Source", "FlatCAM")
for key in settings.allKeys():
settings.remove(key)
# This will write the setting to the platform specific storage.
del settings
def save_geometry(self, x, y, width, height, notebook_width):
"""
Will save the application geometry and positions in the defaults discitionary to be restored at the next
@ -4981,13 +4942,14 @@ class App(QtCore.QObject):
self.defaults["global_toolbar_view"] = tb_status
# Save update options
filename = data_path + "/current_defaults.FlatConfig"
try:
f = open(data_path + "/current_defaults.FlatConfig", "w")
f = open(filename, "w")
json.dump(defaults, f, default=to_dict, indent=2, sort_keys=True)
f.close()
except Exception as e:
log.debug("App.save_defaults() --> %s" % str(e))
self.inform.emit('[ERROR_NOTCL] %s' % _("Failed to write defaults to file."))
self.inform.emit('[ERROR_NOTCL] %s %s' % (_("Failed to write defaults to file."), str(filename)))
return
if not silent:
@ -5138,7 +5100,13 @@ class App(QtCore.QObject):
del stgs
log.debug("App.final_save() --> App UI state saved.")
self.close_app_signal.emit()
def kill_app(self):
QtWidgets.qApp.quit()
# When the main event loop is not started yet in which case the qApp.quit() will do nothing
# we use the following command
sys.exit(0)
def on_portable_checked(self, state):
"""
@ -10043,8 +10011,7 @@ class App(QtCore.QObject):
if filename == "":
if silent is False:
self.inform.emit('[WARNING_NOTCL] %s' %
_("Run TCL script cancelled."))
self.inform.emit('[WARNING_NOTCL] %s' % _("Run TCL script cancelled."))
else:
if self.cmd_line_headless != 1:
if self.ui.shell_dock.isHidden():

View File

@ -7252,7 +7252,7 @@ class FlatCAMScript(FlatCAMObj):
# execute the actual Tcl command
try:
self.app.shell.open_proccessing() # Disables input box.
self.app.shell.open_processing() # Disables input box.
result = self.app.tcl.eval(str(new_command))
if result != 'None':
@ -7270,7 +7270,7 @@ class FlatCAMScript(FlatCAMObj):
log.error("Exec command Exception: %s" % (result + '\n'))
self.app.shell.append_error('ERROR: ' + result + '\n')
self.app.shell.close_proccessing()
self.app.shell.close_processing()
def on_autocomplete_changed(self, state):
if state:

View File

@ -9,6 +9,13 @@ CAD program, and create G-Code for Isolation routing.
=================================================
1.01.2020
- fixed bug in NCC Tool: after trying to add a tool already in the Tool Table when trying to change the Tool Type the GUI does not change
- final fix for app not quiting when running a script as argument, script that has the quit_flatcam Tcl command; fixed issue #360
- fixed issue #363. The Tcl command drillcncjob does not create tool cut, does not allow creation of gcode, it forces the usage of dwell and dwelltime parameters
30.12.2019
- Buffer sub-tool in Transform Tool: added the possibility to apply a factor effectively scaling the aperture size thus the copper features sizes

View File

@ -2550,7 +2550,6 @@ class CNCjob(Geometry):
self.exc_cnc_tools[it[1]]['nr_slots'] = slot_no
self.exc_cnc_tools[it[1]]['offset_z'] = z_off
self.exc_cnc_tools[it[1]]['data'] = default_data
self.exc_cnc_tools[it[1]]['solid_geometry'] = deepcopy(sol_geo)
self.app.inform.emit(_("Creating a list of points to drill..."))

View File

@ -18,6 +18,9 @@ from matplotlib.backend_bases import KeyEvent as mpl_key_event
import webbrowser
from copy import deepcopy
from datetime import datetime
import subprocess
import os
import gettext
import FlatCAMTranslation as fcTranslate
import builtins
@ -2340,6 +2343,9 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
self.lock_toolbar(lock=lock_state)
self.lock_action.triggered[bool].connect(self.lock_toolbar)
self.pref_open_button.clicked.connect(self.on_preferences_open_folder)
self.clear_btn.clicked.connect(self.on_gui_clear)
# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# %%%%%%%%%%%%%%%%% GUI Building FINISHED %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -2360,6 +2366,47 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
return False
def on_preferences_open_folder(self):
"""
Will open an Explorer window set to the folder path where the FlatCAM preferences files are usually saved.
:return: None
"""
if sys.platform == 'win32':
subprocess.Popen('explorer %s' % self.app.data_path)
elif sys.platform == 'darwin':
os.system('open "%s"' % self.app.data_path)
else:
subprocess.Popen(['xdg-open', self.app.data_path])
self.app.inform.emit('[success] %s' % _("FlatCAM Preferences Folder opened."))
def on_gui_clear(self):
theme_settings = QtCore.QSettings("Open Source", "FlatCAM")
theme_settings.setValue('theme', 'white')
del theme_settings
resource_loc = self.app.resource_location
msgbox = QtWidgets.QMessageBox()
msgbox.setText(_("Are you sure you want to delete the GUI Settings? \n"))
msgbox.setWindowTitle(_("Clear GUI Settings"))
msgbox.setWindowIcon(QtGui.QIcon(resource_loc + '/trash32.png'))
bt_yes = msgbox.addButton(_('Yes'), QtWidgets.QMessageBox.YesRole)
bt_no = msgbox.addButton(_('No'), QtWidgets.QMessageBox.NoRole)
msgbox.setDefaultButton(bt_no)
msgbox.exec_()
response = msgbox.clickedButton()
if response == bt_yes:
settings = QSettings("Open Source", "FlatCAM")
for key in settings.allKeys():
settings.remove(key)
# This will write the setting to the platform specific storage.
del settings
def populate_toolbars(self):
"""
Will populate the App Toolbars with theie actions

View File

@ -1007,7 +1007,8 @@ class NonCopperClear(FlatCAMTool, Gerber):
if float('%.*f' % (self.decimals, tool_dia)) in tool_dias:
if muted is None:
self.app.inform.emit('[WARNING_NOTCL] %s' % _("Adding tool cancelled. Tool already in Tool Table."))
self.tools_table.itemChanged.connect(self.on_tool_edit)
# self.tools_table.itemChanged.connect(self.on_tool_edit)
self.ui_connect()
return
else:
if muted is None:

View File

@ -468,7 +468,7 @@ class Properties(FlatCAMTool):
_("Depth of Cut"),
'%.*f %s' % (
self.decimals,
(obj.z_cut - obj.tool_offset[tool_dia]),
(obj.z_cut - abs(obj.tool_offset[tool_dia])),
self.app.defaults['units'].lower()
)
],

View File

@ -56,7 +56,7 @@ class TermWidget(QWidget):
self._history = [''] # current empty line
self._historyIndex = 0
def open_proccessing(self, detail=None):
def open_processing(self, detail=None):
"""
Open processing and disable using shell commands again until all commands are finished
@ -67,14 +67,14 @@ class TermWidget(QWidget):
self._edit.setTextColor(Qt.white)
self._edit.setTextBackgroundColor(Qt.darkGreen)
if detail is None:
self._edit.setPlainText(_("...proccessing..."))
self._edit.setPlainText(_("...processing..."))
else:
self._edit.setPlainText('%s [%s]' % (_("...proccessing..."), detail))
self._edit.setPlainText('%s [%s]' % (_("...processing..."), detail))
self._edit.setDisabled(True)
self._edit.setFocus()
def close_proccessing(self):
def close_processing(self):
"""
Close processing and enable using shell commands again
:return:

View File

@ -258,8 +258,8 @@ class TclCommand(object):
:return: raise exception
"""
# becouse of signaling we cannot call error to TCL from here but when task
# is finished also nonsignaled are handled here to better exception
# because of signaling we cannot call error to TCL from here but when task
# is finished also non-signaled are handled here to better exception
# handling and displayed after command is finished
raise self.app.TclErrorException(text)
@ -400,7 +400,7 @@ class TclCommandSignaled(TclCommand):
passed_timeout = self.app.defaults['global_background_timeout']
# set detail for processing, it will be there until next open or close
self.app.shell.open_proccessing(self.get_current_command())
self.app.shell.open_processing(self.get_current_command())
def handle_finished(obj):
self.app.shell_command_finished.disconnect(handle_finished)

View File

@ -48,7 +48,7 @@ class TclCommandDrillcncjob(TclCommandSignaled):
'args': collections.OrderedDict([
('name', 'Name of the source object.'),
('drilled_dias',
'Comma separated tool diameters of the drills to be drilled (example: 0.6, 1.0 or 3.125).'),
'Comma separated tool diameters of the drills to be drilled (example: 0.6,1.0 or 3.125). No space allowed'),
('drillz', 'Drill depth into material (example: -2.0).'),
('travelz', 'Travel distance above material (example: 2.0).'),
('feedrate', 'Drilling feed rate.'),
@ -74,7 +74,7 @@ class TclCommandDrillcncjob(TclCommandSignaled):
]),
'examples': ['drillcncjob test.TXT -drillz -1.5 -travelz 14 -feedrate 222 -feedrate_rapid 456 -spindlespeed 777'
' -toolchange True -toolchangez 33 -endz 22 -pp default\n'
'Usage of -feedrate_rapid matter only when the posptocessor is using it, like -marlin-.']
'Usage of -feedrate_rapid matter only when the preprocessor is using it, like -marlin-.']
}
def execute(self, args, unnamed_args):
@ -186,6 +186,9 @@ class TclCommandDrillcncjob(TclCommandSignaled):
if bool(args['dwell']) and args['dwelltime']:
job_obj.dwell = True
job_obj.dwelltime = float(args['dwelltime'])
else:
job_obj.dwell = obj.options["dwell"]
job_obj.dwelltime = float(obj.options["dwelltime"])
job_obj.spindlespeed = args["spindlespeed"] if "spindlespeed" in args else None
job_obj.pp_excellon_name = args["pp"] if "pp" in args and args["pp"] \
@ -209,6 +212,18 @@ class TclCommandDrillcncjob(TclCommandSignaled):
job_obj.generate_from_excellon_by_tool(obj, tools, drillz=drillz, toolchangez=toolchangez,
endz=endz,
toolchange=toolchange, excellon_optimization_type=opt_type)
for t_item in job_obj.exc_cnc_tools:
job_obj.exc_cnc_tools[t_item]['data']['offset'] = \
float(job_obj.exc_cnc_tools[t_item]['offset_z']) + float(drillz)
job_obj.exc_cnc_tools[t_item]['data']['ppname_e'] = obj.options['ppname_e']
# for now there is no tool offset support in this Tcl Command so we write the 0.0 value here
job_obj.tool_offset[t_item] = 0.0
print(job_obj.tool_offset)
job_obj.origin_kind = 'excellon'
job_obj.gcode_parse()
job_obj.create_geometry()