- wip in the GCode Editor

This commit is contained in:
Marius Stanciu 2020-07-22 17:08:40 +03:00
parent 9e8ab610b4
commit cf78211a6f
9 changed files with 174 additions and 74 deletions

View File

@ -10,6 +10,7 @@ CHANGELOG for FlatCAM beta
22.07.2020
- working on a proper GCode Editor
- wip in the GCode Editor
21.07.2020

View File

@ -2569,7 +2569,7 @@ class AppExcEditor(QtCore.QObject):
self.set_ui()
# now that we hava data, create the appGUI interface and add it to the Tool Tab
# now that we have data, create the appGUI interface and add it to the Tool Tab
self.build_ui(first_run=True)
# we activate this after the initial build as we don't need to see the tool been populated

View File

@ -6,8 +6,8 @@
# ##########################################################
from appEditors.AppTextEditor import AppTextEditor
from appObjects import FlatCAMCNCJob
from appGUI.GUIElements import FCFileSaveDialog, FCEntry, FCTextAreaExtended, FCTextAreaLineNumber, FCButton
from appObjects.FlatCAMCNCJob import CNCJobObject
from appGUI.GUIElements import FCTextArea, FCEntry, FCButton
from PyQt5 import QtWidgets, QtCore, QtGui
# from io import StringIO
@ -25,7 +25,7 @@ if '_' not in builtins.__dict__:
log = logging.getLogger('base')
class appGCodeEditor(QtCore.QObject):
class AppGCodeEditor(QtCore.QObject):
def __init__(self, app, parent=None):
super().__init__(parent=parent)
@ -34,7 +34,7 @@ class appGCodeEditor(QtCore.QObject):
self.plain_text = ''
self.callback = lambda x: None
self.ui = appGCodeEditorUI(app=self.app)
self.ui = AppGCodeEditorUI(app=self.app)
# #################################################################################
# ################### SIGNALS #####################################################
@ -44,10 +44,44 @@ class appGCodeEditor(QtCore.QObject):
self.code_edited = ''
def set_ui(self):
pass
# #############################################################################################################
# ############# ADD a new TAB in the PLot Tab Area
# #############################################################################################################
self.ui.gcode_editor_tab = AppTextEditor(app=self.app, plain_text=True)
# add the tab if it was closed
self.app.ui.plot_tab_area.addTab(self.ui.gcode_editor_tab, '%s' % _("Code Editor"))
self.ui.gcode_editor_tab.setObjectName('code_editor_tab')
# delete the absolute and relative position and messages in the infobar
self.app.ui.position_label.setText("")
self.app.ui.rel_position_label.setText("")
self.ui.gcode_editor_tab.code_editor.completer_enable = False
self.ui.gcode_editor_tab.buttonRun.hide()
# Switch plot_area to CNCJob tab
self.app.ui.plot_tab_area.setCurrentWidget(self.ui.gcode_editor_tab)
self.ui.gcode_editor_tab.t_frame.hide()
self.ui.gcode_editor_tab.t_frame.show()
self.app.proc_container.view.set_idle()
# #############################################################################################################
# #############################################################################################################
self.ui.append_text.set_value(self.app.defaults["cncjob_append"])
self.ui.prepend_text.set_value(self.app.defaults["cncjob_prepend"])
self.ui.exit_editor_button.buttonSave.clicked.connect(self.update_fcgcode)
def build_ui(self):
pass
# Remove anything else in the GUI Selected Tab
self.app.ui.selected_scroll_area.takeWidget()
# Put ourselves in the GUI Selected Tab
self.app.ui.selected_scroll_area.setWidget(self.ui.edit_widget)
# Switch notebook to Selected page
self.app.ui.notebook.setCurrentWidget(self.app.ui.selected_tab)
def ui_connect(self):
pass
@ -64,35 +98,31 @@ class appGCodeEditor(QtCore.QObject):
self.buttonSave.setIcon(QtGui.QIcon(self.app.resource_location + '/save_as_red.png'))
def edit_fcgcode(self, cnc_obj):
assert isinstance(cnc_obj, FlatCAMCNCJob)
assert isinstance(cnc_obj, CNCJobObject)
self.gcode_obj = cnc_obj
preamble = str(self.ui.prepend_text.get_value())
postamble = str(self.ui.append_text.get_value())
gcode_text = self.gcode_obj.source_file
self.gcode_editor_tab.buttonSave.clicked.connect(self.on_update_source_file)
self.set_ui()
self.build_ui()
# then append the text from GCode to the text editor
self.ui.gcode_editor_tab.load_text(gcode_text, move_to_start=True, clear_text=True)
self.app.inform.emit('[success] %s...' % _('Loaded Machine Code into Code Editor'))
self.ui.gcode_editor_tab.load_text(self, gcode_text, move_to_start=True, clear_text=True)
def update_gcode(self):
def update_fcgcode(self):
preamble = str(self.ui.prepend_text.get_value())
postamble = str(self.ui.append_text.get_value())
my_gcode = self.ui.gcode_editor_tab.code_editor.toPlainText()
self.gcode_obj.source_file = my_gcode
self.ui.gcode_editor_tab.buttonSave.setStyleSheet("")
self.ui.gcode_editor_tab.setIcon(QtGui.QIcon(self.app.resource_location + '/save_as.png'))
def handleOpen(self, filt=None):
self.app.defaults.report_usage("handleOpen()")
def on_open_gcode(self):
if filt:
_filter_ = filt
else:
_filter_ = "G-Code Files (*.nc);; G-Code Files (*.txt);; G-Code Files (*.tap);; G-Code Files (*.cnc);; " \
"All Files (*.*)"
_filter_ = "G-Code Files (*.nc);; G-Code Files (*.txt);; G-Code Files (*.tap);; G-Code Files (*.cnc);; " \
"All Files (*.*)"
path, _f = QtWidgets.QFileDialog.getOpenFileName(
caption=_('Open file'), directory=self.app.get_last_folder(), filter=_filter_)
@ -102,11 +132,11 @@ class appGCodeEditor(QtCore.QObject):
if file.open(QtCore.QIODevice.ReadOnly):
stream = QtCore.QTextStream(file)
self.code_edited = stream.readAll()
self.ui.gcode_editor_tab.load_text(self, self.code_edited, move_to_start=True, clear_text=True)
self.ui.gcode_editor_tab.load_text(self.code_edited, move_to_start=True, clear_text=True)
file.close()
class appGCodeEditorUI:
class AppGCodeEditorUI:
def __init__(self, app):
self.app = app
@ -121,52 +151,96 @@ class appGCodeEditorUI:
# QtWidgets.QSizePolicy.MinimumExpanding
# )
self.layout = QtWidgets.QVBoxLayout()
self.layout.setContentsMargins(0, 0, 0, 0)
self.gcode_editor_tab = None
self.editor_frame = QtWidgets.QFrame()
self.editor_frame.setContentsMargins(0, 0, 0, 0)
self.layout.addWidget(self.editor_frame)
self.edit_widget = QtWidgets.QWidget()
# ## Box for custom widgets
# This gets populated in offspring implementations.
layout = QtWidgets.QVBoxLayout()
self.edit_widget.setLayout(layout)
self.editor_layout = QtWidgets.QGridLayout(self.editor_frame)
self.editor_layout.setContentsMargins(2, 2, 2, 2)
self.editor_frame.setLayout(self.editor_layout)
# add a frame and inside add a vertical box layout. Inside this vbox layout I add all the Drills widgets
# this way I can hide/show the frame
self.edit_frame = QtWidgets.QFrame()
self.edit_frame.setContentsMargins(0, 0, 0, 0)
layout.addWidget(self.edit_frame)
self.edit_box = QtWidgets.QVBoxLayout()
self.edit_box.setContentsMargins(0, 0, 0, 0)
self.edit_frame.setLayout(self.edit_box)
# #############################################################################################################
# ############# ADD a new TAB in the PLot Tab Area
# #############################################################################################################
self.gcode_editor_tab = AppTextEditor(app=self.app, plain_text=True)
# ## Page Title box (spacing between children)
self.title_box = QtWidgets.QHBoxLayout()
self.edit_box.addLayout(self.title_box)
# add the tab if it was closed
self.app.ui.plot_tab_area.addTab(self.gcode_editor_tab, '%s' % _("Code Editor"))
self.gcode_editor_tab.setObjectName('code_editor_tab')
# ## Page Title icon
pixmap = QtGui.QPixmap(self.app.resource_location + '/flatcam_icon32.png')
self.icon = QtWidgets.QLabel()
self.icon.setPixmap(pixmap)
self.title_box.addWidget(self.icon, stretch=0)
# delete the absolute and relative position and messages in the infobar
self.app.ui.position_label.setText("")
self.app.ui.rel_position_label.setText("")
# ## Title label
self.title_label = QtWidgets.QLabel("<font size=5><b>%s</b></font>" % _('GCode Editor'))
self.title_label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
self.title_box.addWidget(self.title_label, stretch=1)
self.gcode_editor_tab.code_editor.completer_enable = False
self.gcode_editor_tab.buttonRun.hide()
# ## Object name
self.name_box = QtWidgets.QHBoxLayout()
self.edit_box.addLayout(self.name_box)
name_label = QtWidgets.QLabel(_("Name:"))
self.name_box.addWidget(name_label)
self.name_entry = FCEntry()
self.name_box.addWidget(self.name_entry)
# Switch plot_area to CNCJob tab
self.app.ui.plot_tab_area.setCurrentWidget(self.gcode_editor_tab)
# Prepend text to GCode
prependlabel = QtWidgets.QLabel('%s:' % _('Prepend to CNC Code'))
prependlabel.setToolTip(
_("Type here any G-Code commands you would\n"
"like to add at the beginning of the G-Code file.")
)
self.edit_box.addWidget(prependlabel)
self.gcode_editor_tab.t_frame.hide()
# then append the text from GCode to the text editor
try:
self.gcode_editor_tab.load_text(self.app.gcode_edited.getvalue(), move_to_start=True, clear_text=True)
except Exception as e:
log.debug('FlatCAMCNNJob.on_edit_code_click() -->%s' % str(e))
self.app.inform.emit('[ERROR] %s %s' % ('FlatCAMCNNJob.on_edit_code_click() -->', str(e)))
return
self.prepend_text = FCTextArea()
self.prepend_text.setPlaceholderText(
_("Type here any G-Code commands you would\n"
"like to add at the beginning of the G-Code file.")
)
self.edit_box.addWidget(self.prepend_text)
self.gcode_editor_tab.t_frame.show()
self.app.proc_container.view.set_idle()
# Append text to GCode
appendlabel = QtWidgets.QLabel('%s:' % _('Append to CNC Code'))
appendlabel.setToolTip(
_("Type here any G-Code commands you would\n"
"like to append to the generated file.\n"
"I.e.: M2 (End of program)")
)
self.edit_box.addWidget(appendlabel)
self.layout.addStretch()
self.append_text = FCTextArea()
self.append_text.setPlaceholderText(
_("Type here any G-Code commands you would\n"
"like to append to the generated file.\n"
"I.e.: M2 (End of program)")
)
self.edit_box.addWidget(self.append_text)
h_lay = QtWidgets.QHBoxLayout()
h_lay.setAlignment(QtCore.Qt.AlignVCenter)
self.edit_box.addLayout(h_lay)
# GO Button
self.update_gcode_button = FCButton(_('Update Code'))
# self.update_gcode_button.setIcon(QtGui.QIcon(self.app.resource_location + '/save_as.png'))
self.update_gcode_button.setToolTip(
_("Update the Gcode in the Editor with the values\n"
"in the 'Prepend' and 'Append' text boxes.")
)
h_lay.addWidget(self.update_gcode_button)
layout.addStretch()
# Editor
self.exit_editor_button = QtWidgets.QPushButton(_('Exit Editor'))
self.exit_editor_button = FCButton(_('Exit Editor'))
self.exit_editor_button.setIcon(QtGui.QIcon(self.app.resource_location + '/power16.png'))
self.exit_editor_button.setToolTip(
_("Exit from Editor.")
@ -177,9 +251,9 @@ class appGCodeEditorUI:
font-weight: bold;
}
""")
self.layout.addWidget(self.exit_editor_button)
# ############################ FINSIHED GUI ###################################
# #############################################################################
layout.addWidget(self.exit_editor_button)
# ############################ FINSIHED GUI ##################################################################
# #############################################################################################################
def confirmation_message(self, accepted, minval, maxval):
if accepted is False:

View File

@ -595,8 +595,7 @@ class CNCJobObject(FlatCAMObj, CNCjob):
try:
self.gcode_editor_tab.load_text(self.app.gcode_edited.getvalue(), move_to_start=True, clear_text=True)
except Exception as e:
log.debug('FlatCAMCNNJob.on_edit_code_click() -->%s' % str(e))
self.app.inform.emit('[ERROR] %s %s' % ('FlatCAMCNNJob.on_edit_code_click() -->', str(e)))
log.debug('FlatCAMCNCJob.on_edit_code_click() -->%s' % str(e))
return
self.gcode_editor_tab.t_frame.show()

View File

@ -1881,6 +1881,7 @@ class GeometryObject(FlatCAMObj, Geometry):
job_obj.z_pdepth = float(self.app.defaults["geometry_z_pdepth"])
job_obj.feedrate_probe = float(self.app.defaults["geometry_feedrate_probe"])
total_gcode = ''
for tooluid_key in list(tools_dict.keys()):
tool_cnt += 1
@ -1970,6 +1971,8 @@ class GeometryObject(FlatCAMObj, Geometry):
else:
dia_cnc_dict['gcode'] = res
total_gcode += res
# tell gcode_parse from which point to start drawing the lines depending on what kind of
# object is the source of gcode
job_obj.toolchange_xy_type = "geometry"
@ -1993,6 +1996,8 @@ class GeometryObject(FlatCAMObj, Geometry):
})
dia_cnc_dict.clear()
job_obj.source_file = total_gcode
# Object initialization function for app.app_obj.new_object()
# RUNNING ON SEPARATE THREAD!
def job_init_multi_geometry(job_obj, app_obj):
@ -2031,6 +2036,7 @@ class GeometryObject(FlatCAMObj, Geometry):
self.app.inform.emit('[ERROR_NOTCL] %s...' % _('Cancelled. Empty file, it has no geometry'))
return 'fail'
total_gcode = ''
for tooluid_key in list(tools_dict.keys()):
tool_cnt += 1
dia_cnc_dict = deepcopy(tools_dict[tooluid_key])
@ -2123,6 +2129,7 @@ class GeometryObject(FlatCAMObj, Geometry):
return 'fail'
else:
dia_cnc_dict['gcode'] = res
total_gcode += res
self.app.inform.emit('[success] %s' % _("G-Code parsing in progress..."))
dia_cnc_dict['gcode_parsed'] = job_obj.gcode_parse()
@ -2149,6 +2156,8 @@ class GeometryObject(FlatCAMObj, Geometry):
})
dia_cnc_dict.clear()
job_obj.source_file = total_gcode
if use_thread:
# To be run in separate thread
def job_thread(a_obj):
@ -2288,17 +2297,18 @@ class GeometryObject(FlatCAMObj, Geometry):
# it seems that the tolerance needs to be a lot lower value than 0.01 and it was hardcoded initially
# to a value of 0.0005 which is 20 times less than 0.01
tol = float(self.app.defaults['global_tolerance']) / 20
job_obj.generate_from_geometry_2(
self, tooldia=tooldia, offset=offset, tolerance=tol,
z_cut=z_cut, z_move=z_move,
feedrate=feedrate, feedrate_z=feedrate_z, feedrate_rapid=feedrate_rapid,
spindlespeed=spindlespeed, dwell=dwell, dwelltime=dwelltime,
multidepth=multidepth, depthpercut=depthperpass,
toolchange=toolchange, toolchangez=toolchangez, toolchangexy=toolchangexy,
extracut=extracut, extracut_length=extracut_length, startz=startz, endz=endz, endxy=endxy,
pp_geometry_name=ppname_g
res = job_obj.generate_from_geometry_2(self, tooldia=tooldia, offset=offset, tolerance=tol,
z_cut=z_cut, z_move=z_move, feedrate=feedrate,
feedrate_z=feedrate_z, feedrate_rapid=feedrate_rapid,
spindlespeed=spindlespeed, dwell=dwell, dwelltime=dwelltime,
multidepth=multidepth, depthpercut=depthperpass,
toolchange=toolchange, toolchangez=toolchangez,
toolchangexy=toolchangexy,
extracut=extracut, extracut_length=extracut_length,
startz=startz, endz=endz, endxy=endxy,
pp_geometry_name=ppname_g
)
job_obj.source_file = res
# tell gcode_parse from which point to start drawing the lines depending on what kind of object is the
# source of gcode
job_obj.toolchange_xy_type = "geometry"

View File

@ -1797,6 +1797,7 @@ class ToolDrilling(AppTool, Excellon):
self.total_gcode_parsed += tool_gcode_parsed
job_obj.gcode = self.total_gcode
job_obj.source_file = self.total_gcode
job_obj.gcode_parsed = self.total_gcode_parsed
if job_obj.gcode == 'fail':
return 'fail'

View File

@ -913,6 +913,7 @@ class SolderPaste(AppTool):
job_obj.options['xmax'] = xmax
job_obj.options['ymax'] = ymax
total_gcode = ''
for tooluid_key, tooluid_value in obj.tools.items():
# find the tool_dia associated with the tooluid_key
tool_dia = tooluid_value['tooldia']
@ -934,6 +935,7 @@ class SolderPaste(AppTool):
return 'fail'
else:
tool_cnc_dict['gcode'] = res
total_gcode += res
# ## PARSE GCODE # ##
tool_cnc_dict['gcode_parsed'] = job_obj.gcode_parse()
@ -949,6 +951,8 @@ class SolderPaste(AppTool):
})
tool_cnc_dict.clear()
job_obj.source_file = total_gcode
if use_thread:
# To be run in separate thread
def job_thread(app_obj):

View File

@ -83,6 +83,7 @@ from appEditors.AppGeoEditor import AppGeoEditor
from appEditors.AppExcEditor import AppExcEditor
from appEditors.AppGerberEditor import AppGerberEditor
from appEditors.AppTextEditor import AppTextEditor
from appEditors.appGCodeEditor import AppGCodeEditor
from appParsers.ParseHPGL2 import HPGL2
# FlatCAM Workers
@ -1574,6 +1575,12 @@ class App(QtCore.QObject):
self.grb_editor = AppGerberEditor(self)
except Exception as es:
log.debug("app_Main.__init__() --> Gerber Editor Error: %s" % str(es))
try:
self.gcode_editor = AppGCodeEditor(self)
except Exception as es:
log.debug("app_Main.__init__() --> GCode Editor Error: %s" % str(es))
self.log.debug("Finished adding FlatCAM Editor's.")
self.set_ui_title(name=_("New Project - Not saved"))
@ -2226,7 +2233,10 @@ class App(QtCore.QObject):
if self.ui.splitter.sizes()[0] == 0:
self.ui.splitter.setSizes([1, 1])
edited_object.on_edit_code_click()
# set call source to the Editor we go into
self.call_source = 'gcode_editor'
self.gcode_editor.edit_fcgcode(edited_object)
return
# make sure that we can't select another object while in Editor Mode:

View File

@ -332,6 +332,7 @@ class TclCommandDrillcncjob(TclCommandSignaled):
job_obj.excellon_optimization_type = opt_type
ret_val = job_obj.generate_from_excellon_by_tool(obj, tools, use_ui=False)
job_obj.source_file = ret_val
if ret_val == 'fail':
return 'fail'