| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- # ##########################################################
- # FlatCAM: 2D Post-processing for Manufacturing #
- # http://flatcam.org #
- # Author: Juan Pablo Caram (c) #
- # Date: 2/5/2014 #
- # MIT Licence #
- # ##########################################################
- # ##########################################################
- # File modified by: Marius Stanciu #
- # ##########################################################
- from flatcamEditors.FlatCAMTextEditor import TextEditor
- from flatcamObjects.FlatCAMObj import *
- from flatcamGUI.ObjectUI import *
- import tkinter as tk
- import sys
- from copy import deepcopy
- import gettext
- import FlatCAMTranslation as fcTranslate
- import builtins
- fcTranslate.apply_language('strings')
- if '_' not in builtins.__dict__:
- _ = gettext.gettext
- class ScriptObject(FlatCAMObj):
- """
- Represents a TCL script object.
- """
- optionChanged = QtCore.pyqtSignal(str)
- ui_type = ScriptObjectUI
- def __init__(self, name):
- self.decimals = self.app.decimals
- log.debug("Creating a ScriptObject object...")
- FlatCAMObj.__init__(self, name)
- self.kind = "script"
- self.options.update({
- "plot": True,
- "type": 'Script',
- "source_file": '',
- })
- self.units = ''
- self.ser_attrs = ['options', 'kind', 'source_file']
- self.source_file = ''
- self.script_code = ''
- self.units_found = self.app.defaults['units']
- # self.script_editor_tab = TextEditor(app=self.app, plain_text=True)
- self.script_editor_tab = TextEditor(app=self.app, plain_text=True)
- def set_ui(self, ui):
- """
- Sets the Object UI in Selected Tab for the FlatCAM Script type of object.
- :param ui:
- :return:
- """
- FlatCAMObj.set_ui(self, ui)
- log.debug("ScriptObject.set_ui()")
- assert isinstance(self.ui, ScriptObjectUI), \
- "Expected a ScriptObjectUI, got %s" % type(self.ui)
- self.units = self.app.defaults['units'].upper()
- self.units_found = self.app.defaults['units']
- # Fill form fields only on object create
- self.to_form()
- # Show/Hide Advanced Options
- if self.app.defaults["global_app_level"] == 'b':
- self.ui.level.setText(_(
- '<span style="color:green;"><b>Basic</b></span>'
- ))
- else:
- self.ui.level.setText(_(
- '<span style="color:red;"><b>Advanced</b></span>'
- ))
- # tab_here = False
- # # try to not add too many times a tab that it is already installed
- # for idx in range(self.app.ui.plot_tab_area.count()):
- # if self.app.ui.plot_tab_area.widget(idx).objectName() == self.options['name']:
- # tab_here = True
- # break
- #
- # # add the tab if it is not already added
- # if tab_here is False:
- # self.app.ui.plot_tab_area.addTab(self.script_editor_tab, '%s' % _("Script Editor"))
- # self.script_editor_tab.setObjectName(self.options['name'])
- self.app.ui.plot_tab_area.addTab(self.script_editor_tab, '%s' % _("Script Editor"))
- self.script_editor_tab.setObjectName(self.options['name'])
- # first clear previous text in text editor (if any)
- # self.script_editor_tab.code_editor.clear()
- # self.script_editor_tab.code_editor.setReadOnly(False)
- self.ui.autocomplete_cb.set_value(self.app.defaults['script_autocompleter'])
- self.on_autocomplete_changed(state=self.app.defaults['script_autocompleter'])
- self.script_editor_tab.buttonRun.show()
- # Switch plot_area to CNCJob tab
- self.app.ui.plot_tab_area.setCurrentWidget(self.script_editor_tab)
- flt = "FlatCAM Scripts (*.FlatScript);;All Files (*.*)"
- self.script_editor_tab.buttonOpen.clicked.disconnect()
- self.script_editor_tab.buttonOpen.clicked.connect(lambda: self.script_editor_tab.handleOpen(filt=flt))
- self.script_editor_tab.buttonSave.clicked.disconnect()
- self.script_editor_tab.buttonSave.clicked.connect(lambda: self.script_editor_tab.handleSaveGCode(filt=flt))
- self.script_editor_tab.buttonRun.clicked.connect(self.handle_run_code)
- self.script_editor_tab.handleTextChanged()
- self.ui.autocomplete_cb.stateChanged.connect(self.on_autocomplete_changed)
- self.ser_attrs = ['options', 'kind', 'source_file']
- # ---------------------------------------------------- #
- # ----------- LOAD THE TEXT SOURCE FILE -------------- #
- # ---------------------------------------------------- #
- self.app.proc_container.view.set_busy(_("Loading..."))
- self.script_editor_tab.t_frame.hide()
- try:
- self.script_editor_tab.code_editor.setPlainText(self.source_file)
- # for line in self.source_file.splitlines():
- # QtWidgets.QApplication.processEvents()
- # self.script_editor_tab.code_editor.append(line)
- except Exception as e:
- log.debug("ScriptObject.set_ui() --> %s" % str(e))
- self.script_editor_tab.code_editor.moveCursor(QtGui.QTextCursor.End)
- self.script_editor_tab.t_frame.show()
- self.app.proc_container.view.set_idle()
- self.build_ui()
- def build_ui(self):
- FlatCAMObj.build_ui(self)
- def handle_run_code(self):
- # trying to run a Tcl command without having the Shell open will create some warnings because the Tcl Shell
- # tries to print on a hidden widget, therefore show the dock if hidden
- if self.app.ui.shell_dock.isHidden():
- self.app.ui.shell_dock.show()
- self.script_code = deepcopy(self.script_editor_tab.code_editor.toPlainText())
- old_line = ''
- for tcl_command_line in self.script_code.splitlines():
- # do not process lines starting with '#' = comment and empty lines
- if not tcl_command_line.startswith('#') and tcl_command_line != '':
- # id FlatCAM is run in Windows then replace all the slashes with
- # the UNIX style slash that TCL understands
- if sys.platform == 'win32':
- if "open" in tcl_command_line:
- tcl_command_line = tcl_command_line.replace('\\', '/')
- if old_line != '':
- new_command = old_line + tcl_command_line + '\n'
- else:
- new_command = tcl_command_line
- # execute the actual Tcl command
- try:
- self.app.shell.open_processing() # Disables input box.
- result = self.app.shell.tcl.eval(str(new_command))
- if result != 'None':
- self.app.shell.append_output(result + '\n')
- old_line = ''
- except tk.TclError:
- old_line = old_line + tcl_command_line + '\n'
- except Exception as e:
- log.debug("ScriptObject.handleRunCode() --> %s" % str(e))
- if old_line != '':
- # it means that the script finished with an error
- result = self.app.shell.tcl.eval("set errorInfo")
- log.error("Exec command Exception: %s\n" % result)
- self.app.shell.append_error('ERROR: %s\n '% result)
- self.app.shell.close_processing()
- def on_autocomplete_changed(self, state):
- if state:
- self.script_editor_tab.code_editor.completer_enable = True
- else:
- self.script_editor_tab.code_editor.completer_enable = False
- def to_dict(self):
- """
- Returns a representation of the object as a dictionary.
- Attributes to include are listed in ``self.ser_attrs``.
- :return: A dictionary-encoded copy of the object.
- :rtype: dict
- """
- d = {}
- for attr in self.ser_attrs:
- d[attr] = getattr(self, attr)
- return d
- def from_dict(self, d):
- """
- Sets object's attributes from a dictionary.
- Attributes to include are listed in ``self.ser_attrs``.
- This method will look only for only and all the
- attributes in ``self.ser_attrs``. They must all
- be present. Use only for deserializing saved
- objects.
- :param d: Dictionary of attributes to set in the object.
- :type d: dict
- :return: None
- """
- for attr in self.ser_attrs:
- setattr(self, attr, d[attr])
|