appGCodeEditor.py 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. # ##########################################################
  2. # FlatCAM: 2D Post-processing for Manufacturing #
  3. # File Author: Marius Adrian Stanciu (c) #
  4. # Date: 07/22/2020 #
  5. # MIT Licence #
  6. # ##########################################################
  7. from appEditors.AppTextEditor import AppTextEditor
  8. from appObjects import FlatCAMCNCJob
  9. from appGUI.GUIElements import FCFileSaveDialog, FCEntry, FCTextAreaExtended, FCTextAreaLineNumber, FCButton
  10. from PyQt5 import QtWidgets, QtCore, QtGui
  11. # from io import StringIO
  12. import logging
  13. import gettext
  14. import appTranslation as fcTranslate
  15. import builtins
  16. fcTranslate.apply_language('strings')
  17. if '_' not in builtins.__dict__:
  18. _ = gettext.gettext
  19. log = logging.getLogger('base')
  20. class appGCodeEditor(QtCore.QObject):
  21. def __init__(self, app, parent=None):
  22. super().__init__(parent=parent)
  23. self.app = app
  24. self.plain_text = ''
  25. self.callback = lambda x: None
  26. self.ui = appGCodeEditorUI(app=self.app)
  27. # #################################################################################
  28. # ################### SIGNALS #####################################################
  29. # #################################################################################
  30. self.gcode_obj = None
  31. self.code_edited = ''
  32. def set_ui(self):
  33. pass
  34. def build_ui(self):
  35. pass
  36. def ui_connect(self):
  37. pass
  38. def ui_disconnect(self):
  39. pass
  40. def handleTextChanged(self):
  41. # enable = not self.ui.code_editor.document().isEmpty()
  42. # self.ui.buttonPrint.setEnabled(enable)
  43. # self.ui.buttonPreview.setEnabled(enable)
  44. self.buttonSave.setStyleSheet("QPushButton {color: red;}")
  45. self.buttonSave.setIcon(QtGui.QIcon(self.app.resource_location + '/save_as_red.png'))
  46. def edit_fcgcode(self, cnc_obj):
  47. assert isinstance(cnc_obj, FlatCAMCNCJob)
  48. self.gcode_obj = cnc_obj
  49. preamble = str(self.ui.prepend_text.get_value())
  50. postamble = str(self.ui.append_text.get_value())
  51. gcode_text = self.gcode_obj.source_file
  52. self.gcode_editor_tab.buttonSave.clicked.connect(self.on_update_source_file)
  53. self.app.inform.emit('[success] %s...' % _('Loaded Machine Code into Code Editor'))
  54. self.ui.gcode_editor_tab.load_text(self, gcode_text, move_to_start=True, clear_text=True)
  55. def update_gcode(self):
  56. my_gcode = self.ui.gcode_editor_tab.code_editor.toPlainText()
  57. self.gcode_obj.source_file = my_gcode
  58. self.ui.gcode_editor_tab.buttonSave.setStyleSheet("")
  59. self.ui.gcode_editor_tab.setIcon(QtGui.QIcon(self.app.resource_location + '/save_as.png'))
  60. def handleOpen(self, filt=None):
  61. self.app.defaults.report_usage("handleOpen()")
  62. if filt:
  63. _filter_ = filt
  64. else:
  65. _filter_ = "G-Code Files (*.nc);; G-Code Files (*.txt);; G-Code Files (*.tap);; G-Code Files (*.cnc);; " \
  66. "All Files (*.*)"
  67. path, _f = QtWidgets.QFileDialog.getOpenFileName(
  68. caption=_('Open file'), directory=self.app.get_last_folder(), filter=_filter_)
  69. if path:
  70. file = QtCore.QFile(path)
  71. if file.open(QtCore.QIODevice.ReadOnly):
  72. stream = QtCore.QTextStream(file)
  73. self.code_edited = stream.readAll()
  74. self.ui.gcode_editor_tab.load_text(self, self.code_edited, move_to_start=True, clear_text=True)
  75. file.close()
  76. class appGCodeEditorUI:
  77. def __init__(self, app):
  78. self.app = app
  79. # Number of decimals used by tools in this class
  80. self.decimals = self.app.decimals
  81. # ## Current application units in Upper Case
  82. self.units = self.app.defaults['units'].upper()
  83. # self.setSizePolicy(
  84. # QtWidgets.QSizePolicy.MinimumExpanding,
  85. # QtWidgets.QSizePolicy.MinimumExpanding
  86. # )
  87. self.layout = QtWidgets.QVBoxLayout()
  88. self.layout.setContentsMargins(0, 0, 0, 0)
  89. self.editor_frame = QtWidgets.QFrame()
  90. self.editor_frame.setContentsMargins(0, 0, 0, 0)
  91. self.layout.addWidget(self.editor_frame)
  92. self.editor_layout = QtWidgets.QGridLayout(self.editor_frame)
  93. self.editor_layout.setContentsMargins(2, 2, 2, 2)
  94. self.editor_frame.setLayout(self.editor_layout)
  95. # #############################################################################################################
  96. # ############# ADD a new TAB in the PLot Tab Area
  97. # #############################################################################################################
  98. self.gcode_editor_tab = AppTextEditor(app=self.app, plain_text=True)
  99. # add the tab if it was closed
  100. self.app.ui.plot_tab_area.addTab(self.gcode_editor_tab, '%s' % _("Code Editor"))
  101. self.gcode_editor_tab.setObjectName('code_editor_tab')
  102. # delete the absolute and relative position and messages in the infobar
  103. self.app.ui.position_label.setText("")
  104. self.app.ui.rel_position_label.setText("")
  105. self.gcode_editor_tab.code_editor.completer_enable = False
  106. self.gcode_editor_tab.buttonRun.hide()
  107. # Switch plot_area to CNCJob tab
  108. self.app.ui.plot_tab_area.setCurrentWidget(self.gcode_editor_tab)
  109. self.gcode_editor_tab.t_frame.hide()
  110. # then append the text from GCode to the text editor
  111. try:
  112. self.gcode_editor_tab.load_text(self.app.gcode_edited.getvalue(), move_to_start=True, clear_text=True)
  113. except Exception as e:
  114. log.debug('FlatCAMCNNJob.on_edit_code_click() -->%s' % str(e))
  115. self.app.inform.emit('[ERROR] %s %s' % ('FlatCAMCNNJob.on_edit_code_click() -->', str(e)))
  116. return
  117. self.gcode_editor_tab.t_frame.show()
  118. self.app.proc_container.view.set_idle()
  119. self.layout.addStretch()
  120. # Editor
  121. self.exit_editor_button = QtWidgets.QPushButton(_('Exit Editor'))
  122. self.exit_editor_button.setIcon(QtGui.QIcon(self.app.resource_location + '/power16.png'))
  123. self.exit_editor_button.setToolTip(
  124. _("Exit from Editor.")
  125. )
  126. self.exit_editor_button.setStyleSheet("""
  127. QPushButton
  128. {
  129. font-weight: bold;
  130. }
  131. """)
  132. self.layout.addWidget(self.exit_editor_button)
  133. # ############################ FINSIHED GUI ###################################
  134. # #############################################################################
  135. def confirmation_message(self, accepted, minval, maxval):
  136. if accepted is False:
  137. self.app.inform[str, bool].emit('[WARNING_NOTCL] %s: [%.*f, %.*f]' % (_("Edited value is out of range"),
  138. self.decimals,
  139. minval,
  140. self.decimals,
  141. maxval), False)
  142. else:
  143. self.app.inform[str, bool].emit('[success] %s' % _("Edited value is within limits."), False)
  144. def confirmation_message_int(self, accepted, minval, maxval):
  145. if accepted is False:
  146. self.app.inform[str, bool].emit('[WARNING_NOTCL] %s: [%d, %d]' %
  147. (_("Edited value is out of range"), minval, maxval), False)
  148. else:
  149. self.app.inform[str, bool].emit('[success] %s' % _("Edited value is within limits."), False)