Cleanup of TclCommand and migrated a few more commands to new architecture.
This commit is contained in:
@@ -3636,36 +3636,36 @@ class App(QtCore.QObject):
|
|||||||
except Exception, e:
|
except Exception, e:
|
||||||
return "ERROR: %s" % str(e)
|
return "ERROR: %s" % str(e)
|
||||||
|
|
||||||
def get_sys(param):
|
# def get_sys(param):
|
||||||
if param in self.defaults:
|
# if param in self.defaults:
|
||||||
return self.defaults[param]
|
# return self.defaults[param]
|
||||||
|
#
|
||||||
|
# return "ERROR: No such system parameter."
|
||||||
|
|
||||||
return "ERROR: No such system parameter."
|
# def set_sys(param, value):
|
||||||
|
# # tcl string to python keywords:
|
||||||
def set_sys(param, value):
|
# tcl2py = {
|
||||||
# tcl string to python keywords:
|
# "None": None,
|
||||||
tcl2py = {
|
# "none": None,
|
||||||
"None": None,
|
# "false": False,
|
||||||
"none": None,
|
# "False": False,
|
||||||
"false": False,
|
# "true": True,
|
||||||
"False": False,
|
# "True": True
|
||||||
"true": True,
|
# }
|
||||||
"True": True
|
#
|
||||||
}
|
# if param in self.defaults:
|
||||||
|
#
|
||||||
if param in self.defaults:
|
# try:
|
||||||
|
# value = tcl2py[value]
|
||||||
try:
|
# except KeyError:
|
||||||
value = tcl2py[value]
|
# pass
|
||||||
except KeyError:
|
#
|
||||||
pass
|
# self.defaults[param] = value
|
||||||
|
#
|
||||||
self.defaults[param] = value
|
# self.propagate_defaults()
|
||||||
|
# return "Ok"
|
||||||
self.propagate_defaults()
|
#
|
||||||
return "Ok"
|
# return "ERROR: No such system parameter."
|
||||||
|
|
||||||
return "ERROR: No such system parameter."
|
|
||||||
|
|
||||||
'''
|
'''
|
||||||
Howto implement TCL shell commands:
|
Howto implement TCL shell commands:
|
||||||
@@ -4085,22 +4085,25 @@ class App(QtCore.QObject):
|
|||||||
' name: Name of the gerber object.\n' +
|
' name: Name of the gerber object.\n' +
|
||||||
' outname: Name of the output geometry object.'
|
' outname: Name of the output geometry object.'
|
||||||
},
|
},
|
||||||
'get_sys': {
|
|
||||||
'fcn': get_sys,
|
# 'get_sys': {
|
||||||
'help': 'Get the value of a system parameter (FlatCAM constant)\n' +
|
# 'fcn': get_sys,
|
||||||
'> get_sys <sysparam>\n' +
|
# 'help': 'Get the value of a system parameter (FlatCAM constant)\n' +
|
||||||
' sysparam: Name of the parameter.'
|
# '> get_sys <sysparam>\n' +
|
||||||
},
|
# ' sysparam: Name of the parameter.'
|
||||||
'set_sys': {
|
# },
|
||||||
'fcn': set_sys,
|
# --- Migrated to new architecture ---
|
||||||
'help': 'Set the value of a system parameter (FlatCAM constant)\n' +
|
# 'set_sys': {
|
||||||
'> set_sys <sysparam> <paramvalue>\n' +
|
# 'fcn': set_sys,
|
||||||
' sysparam: Name of the parameter.\n' +
|
# 'help': 'Set the value of a system parameter (FlatCAM constant)\n' +
|
||||||
' paramvalue: Value to set.'
|
# '> set_sys <sysparam> <paramvalue>\n' +
|
||||||
}
|
# ' sysparam: Name of the parameter.\n' +
|
||||||
|
# ' paramvalue: Value to set.'
|
||||||
|
# }
|
||||||
}
|
}
|
||||||
|
|
||||||
#import/overwrite tcl commands as objects of TclCommand descendants
|
# Import/overwrite tcl commands as objects of TclCommand descendants
|
||||||
|
# This modifies the variable 'commands'.
|
||||||
tclCommands.register_all_commands(self, commands)
|
tclCommands.register_all_commands(self, commands)
|
||||||
|
|
||||||
# Add commands to the tcl interpreter
|
# Add commands to the tcl interpreter
|
||||||
|
|||||||
@@ -12,26 +12,28 @@ class TclCommand(object):
|
|||||||
# FlatCAMApp
|
# FlatCAMApp
|
||||||
app = None
|
app = None
|
||||||
|
|
||||||
# logger
|
# Logger
|
||||||
log = None
|
log = None
|
||||||
|
|
||||||
# array 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 = []
|
aliases = []
|
||||||
|
|
||||||
# dictionary of types from Tcl command, needs to be ordered
|
# Dictionary of types from Tcl command, needs to be ordered
|
||||||
# OrderedDict should be like collections.OrderedDict([(key,value),(key2,value2)])
|
# OrderedDict should be like collections.OrderedDict([(key,value),(key2,value2)])
|
||||||
arg_names = collections.OrderedDict([
|
arg_names = collections.OrderedDict([
|
||||||
('name', str)
|
('name', str)
|
||||||
])
|
])
|
||||||
|
|
||||||
# dictionary of types from Tcl command, needs to be ordered , this is for options like -optionname value
|
# dictionary of types from Tcl command, needs to be ordered.
|
||||||
|
# This is for options like -optionname value.
|
||||||
# OrderedDict should be like collections.OrderedDict([(key,value),(key2,value2)])
|
# OrderedDict should be like collections.OrderedDict([(key,value),(key2,value2)])
|
||||||
option_types = collections.OrderedDict()
|
option_types = collections.OrderedDict()
|
||||||
|
|
||||||
# array of mandatory options for current Tcl command: required = {'name','outname'}
|
# List of mandatory options for current Tcl command: required = {'name','outname'}
|
||||||
required = ['name']
|
required = ['name']
|
||||||
|
|
||||||
# structured help for current command, args needs to be ordered
|
# Structured help for current command, args needs to be ordered
|
||||||
# OrderedDict should be like collections.OrderedDict([(key,value),(key2,value2)])
|
# OrderedDict should be like collections.OrderedDict([(key,value),(key2,value2)])
|
||||||
help = {
|
help = {
|
||||||
'main': "undefined help.",
|
'main': "undefined help.",
|
||||||
@@ -42,21 +44,27 @@ class TclCommand(object):
|
|||||||
'examples': []
|
'examples': []
|
||||||
}
|
}
|
||||||
|
|
||||||
# original incoming arguments into command
|
# Original incoming arguments into command
|
||||||
original_args = None
|
original_args = None
|
||||||
|
|
||||||
def __init__(self, app):
|
def __init__(self, app):
|
||||||
self.app = app
|
self.app = app
|
||||||
|
|
||||||
if self.app is None:
|
if self.app is None:
|
||||||
raise TypeError('Expected app to be FlatCAMApp instance.')
|
raise TypeError('Expected app to be FlatCAMApp instance.')
|
||||||
|
|
||||||
if not isinstance(self.app, FlatCAMApp.App):
|
if not isinstance(self.app, FlatCAMApp.App):
|
||||||
raise TypeError('Expected FlatCAMApp, got %s.' % type(app))
|
raise TypeError('Expected FlatCAMApp, got %s.' % type(app))
|
||||||
|
|
||||||
self.log = self.app.log
|
self.log = self.app.log
|
||||||
|
|
||||||
def raise_tcl_error(self, text):
|
def raise_tcl_error(self, text):
|
||||||
"""
|
"""
|
||||||
this method pass exception from python into TCL as error, so we get stacktrace and reason
|
This method pass exception from python into TCL as error
|
||||||
this is only redirect to self.app.raise_tcl_error
|
so we get stacktrace and reason.
|
||||||
|
|
||||||
|
This is only redirect to self.app.raise_tcl_error
|
||||||
|
|
||||||
:param text: text of error
|
:param text: text of error
|
||||||
:return: none
|
:return: none
|
||||||
"""
|
"""
|
||||||
@@ -65,14 +73,17 @@ class TclCommand(object):
|
|||||||
|
|
||||||
def get_current_command(self):
|
def get_current_command(self):
|
||||||
"""
|
"""
|
||||||
get current command, we are not able to get it from TCL we have to reconstruct it
|
Get current command, we are not able to get it from TCL we have to reconstruct it.
|
||||||
|
|
||||||
:return: current command
|
:return: current command
|
||||||
"""
|
"""
|
||||||
command_string = []
|
|
||||||
command_string.append(self.aliases[0])
|
command_string = [self.aliases[0]]
|
||||||
|
|
||||||
if self.original_args is not None:
|
if self.original_args is not None:
|
||||||
for arg in self.original_args:
|
for arg in self.original_args:
|
||||||
command_string.append(arg)
|
command_string.append(arg)
|
||||||
|
|
||||||
return " ".join(command_string)
|
return " ".join(command_string)
|
||||||
|
|
||||||
def get_decorated_help(self):
|
def get_decorated_help(self):
|
||||||
@@ -83,22 +94,36 @@ class TclCommand(object):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def get_decorated_command(alias_name):
|
def get_decorated_command(alias_name):
|
||||||
|
|
||||||
command_string = []
|
command_string = []
|
||||||
|
|
||||||
for arg_key, arg_type in self.help['args'].items():
|
for arg_key, arg_type in 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)
|
||||||
|
|
||||||
def get_decorated_argument(help_key, help_text, in_command=False):
|
def get_decorated_argument(help_key, help_text, in_command=False):
|
||||||
|
"""
|
||||||
|
|
||||||
|
:param help_key: Name of the argument.
|
||||||
|
:param help_text:
|
||||||
|
:param in_command:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
option_symbol = ''
|
option_symbol = ''
|
||||||
|
|
||||||
if help_key in self.arg_names:
|
if help_key in self.arg_names:
|
||||||
arg_type = self.arg_names[help_key]
|
arg_type = self.arg_names[help_key]
|
||||||
type_name = str(arg_type.__name__)
|
type_name = str(arg_type.__name__)
|
||||||
in_command_name = "<" + type_name + ">"
|
#in_command_name = help_key + "<" + type_name + ">"
|
||||||
|
in_command_name = help_key
|
||||||
|
|
||||||
elif help_key in self.option_types:
|
elif help_key in self.option_types:
|
||||||
option_symbol = '-'
|
option_symbol = '-'
|
||||||
arg_type = self.option_types[help_key]
|
arg_type = self.option_types[help_key]
|
||||||
type_name = str(arg_type.__name__)
|
type_name = str(arg_type.__name__)
|
||||||
in_command_name = option_symbol + help_key + " <" + type_name + ">"
|
in_command_name = option_symbol + help_key + " <" + type_name + ">"
|
||||||
|
|
||||||
else:
|
else:
|
||||||
option_symbol = ''
|
option_symbol = ''
|
||||||
type_name = '?'
|
type_name = '?'
|
||||||
@@ -168,7 +193,7 @@ class TclCommand(object):
|
|||||||
|
|
||||||
def check_args(self, args):
|
def check_args(self, args):
|
||||||
"""
|
"""
|
||||||
Check arguments and options for right types
|
Check arguments and options for right types
|
||||||
|
|
||||||
:param args: arguments from tcl to check
|
:param args: arguments from tcl to check
|
||||||
:return: named_args, unnamed_args
|
:return: named_args, unnamed_args
|
||||||
@@ -214,29 +239,16 @@ class TclCommand(object):
|
|||||||
|
|
||||||
return named_args, unnamed_args
|
return named_args, unnamed_args
|
||||||
|
|
||||||
def raise_tcl_unknown_error(self, unknownException):
|
def raise_tcl_unknown_error(self, unknown_exception):
|
||||||
"""
|
"""
|
||||||
raise Exception if is different type than TclErrorException
|
raise Exception if is different type than TclErrorException
|
||||||
this is here mainly to show unknown errors inside TCL shell console
|
this is here mainly to show unknown errors inside TCL shell console
|
||||||
:param unknownException:
|
|
||||||
|
:param unknown_exception:
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#if not isinstance(unknownException, self.TclErrorException):
|
raise unknown_exception
|
||||||
# self.raise_tcl_error("Unknown error: %s" % str(unknownException))
|
|
||||||
#else:
|
|
||||||
raise unknownException
|
|
||||||
|
|
||||||
def raise_tcl_error(self, text):
|
|
||||||
"""
|
|
||||||
this method pass exception from python into TCL as error, so we get stacktrace and reason
|
|
||||||
:param text: text of error
|
|
||||||
:return: raise exception
|
|
||||||
"""
|
|
||||||
|
|
||||||
# becouse of signaling we cannot call error to TCL from here but when task is finished
|
|
||||||
# also nonsiglaned arwe handled here to better exception handling and diplay after command is finished
|
|
||||||
raise self.app.TclErrorException(text)
|
|
||||||
|
|
||||||
def execute_wrapper(self, *args):
|
def execute_wrapper(self, *args):
|
||||||
"""
|
"""
|
||||||
@@ -291,6 +303,10 @@ class TclCommandSignaled(TclCommand):
|
|||||||
it handles all neccessary stuff about blocking and passing exeptions
|
it handles all neccessary stuff about blocking and passing exeptions
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def execute(self, args, unnamed_args):
|
||||||
|
raise NotImplementedError("Please Implement this method")
|
||||||
|
|
||||||
output = None
|
output = None
|
||||||
|
|
||||||
def execute_call(self, args, unnamed_args):
|
def execute_call(self, args, unnamed_args):
|
||||||
|
|||||||
50
tclCommands/TclCommandGetSys.py
Normal file
50
tclCommands/TclCommandGetSys.py
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
from ObjectCollection import *
|
||||||
|
import TclCommand
|
||||||
|
|
||||||
|
|
||||||
|
class TclCommandGetSys(TclCommand.TclCommand):
|
||||||
|
"""
|
||||||
|
Tcl shell command to get the value of a system variable
|
||||||
|
|
||||||
|
example:
|
||||||
|
get_sys excellon_zeros
|
||||||
|
"""
|
||||||
|
|
||||||
|
# List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon)
|
||||||
|
aliases = ['get_sys', 'getsys']
|
||||||
|
|
||||||
|
# Dictionary of types from Tcl command, needs to be ordered
|
||||||
|
arg_names = collections.OrderedDict([
|
||||||
|
('name', str)
|
||||||
|
])
|
||||||
|
|
||||||
|
# Dictionary of types from Tcl command, needs to be ordered , this is for options like -optionname value
|
||||||
|
option_types = collections.OrderedDict([
|
||||||
|
|
||||||
|
])
|
||||||
|
|
||||||
|
# array of mandatory options for current Tcl command: required = {'name','outname'}
|
||||||
|
required = ['name']
|
||||||
|
|
||||||
|
# structured help for current command, args needs to be ordered
|
||||||
|
help = {
|
||||||
|
'main': "Returns the value of the system variable.",
|
||||||
|
'args': collections.OrderedDict([
|
||||||
|
('name', 'Name of the system variable.'),
|
||||||
|
]),
|
||||||
|
'examples': ['get_sys excellon_zeros']
|
||||||
|
}
|
||||||
|
|
||||||
|
def execute(self, args, unnamed_args):
|
||||||
|
"""
|
||||||
|
|
||||||
|
:param args:
|
||||||
|
:param unnamed_args:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
|
||||||
|
name = args['name']
|
||||||
|
|
||||||
|
if name in self.app.defaults:
|
||||||
|
return self.app.defaults[name]
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ class TclCommandJoinGeometry(TclCommand.TclCommand):
|
|||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
outname = args['name']
|
outname = args['outname']
|
||||||
obj_names = unnamed_args
|
obj_names = unnamed_args
|
||||||
|
|
||||||
objs = []
|
objs = []
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ class TclCommandOpenExcellon(TclCommand.TclCommandSignaled):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon)
|
# array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon)
|
||||||
aliases = ['open_gerber']
|
aliases = ['open_excellon']
|
||||||
|
|
||||||
# Dictionary of types from Tcl command, needs to be ordered.
|
# Dictionary of types from Tcl command, needs to be ordered.
|
||||||
# For positional arguments
|
# For positional arguments
|
||||||
@@ -45,4 +45,6 @@ class TclCommandOpenExcellon(TclCommand.TclCommandSignaled):
|
|||||||
:return: None or exception
|
:return: None or exception
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.app.open_excellon(args['filename'], **args)
|
filename = args.pop('filename')
|
||||||
|
|
||||||
|
self.app.open_excellon(filename, **args)
|
||||||
|
|||||||
73
tclCommands/TclCommandSetSys.py
Normal file
73
tclCommands/TclCommandSetSys.py
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
from ObjectCollection import *
|
||||||
|
import TclCommand
|
||||||
|
|
||||||
|
|
||||||
|
class TclCommandSetSys(TclCommand.TclCommand):
|
||||||
|
"""
|
||||||
|
Tcl shell command to set the value of a system variable
|
||||||
|
|
||||||
|
example:
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon)
|
||||||
|
aliases = ['set_sys', 'setsys']
|
||||||
|
|
||||||
|
# Dictionary of types from Tcl command, needs to be ordered
|
||||||
|
arg_names = collections.OrderedDict([
|
||||||
|
('name', str),
|
||||||
|
('value', str)
|
||||||
|
])
|
||||||
|
|
||||||
|
# Dictionary of types from Tcl command, needs to be ordered , this is for options like -optionname value
|
||||||
|
option_types = collections.OrderedDict([
|
||||||
|
|
||||||
|
])
|
||||||
|
|
||||||
|
# array of mandatory options for current Tcl command: required = {'name','outname'}
|
||||||
|
required = ['name', 'value']
|
||||||
|
|
||||||
|
# structured help for current command, args needs to be ordered
|
||||||
|
help = {
|
||||||
|
'main': "Sets the value of the system variable.",
|
||||||
|
'args': collections.OrderedDict([
|
||||||
|
('name', 'Name of the system variable.'),
|
||||||
|
('value', 'Value to set.')
|
||||||
|
]),
|
||||||
|
'examples': []
|
||||||
|
}
|
||||||
|
|
||||||
|
def execute(self, args, unnamed_args):
|
||||||
|
"""
|
||||||
|
|
||||||
|
:param args:
|
||||||
|
:param unnamed_args:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
|
||||||
|
param = args['name']
|
||||||
|
value = args['value']
|
||||||
|
|
||||||
|
# TCL string to python keywords:
|
||||||
|
tcl2py = {
|
||||||
|
"None": None,
|
||||||
|
"none": None,
|
||||||
|
"false": False,
|
||||||
|
"False": False,
|
||||||
|
"true": True,
|
||||||
|
"True": True
|
||||||
|
}
|
||||||
|
|
||||||
|
if param in self.app.defaults:
|
||||||
|
|
||||||
|
try:
|
||||||
|
value = tcl2py[value]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
self.app.defaults[param] = value
|
||||||
|
|
||||||
|
self.app.propagate_defaults()
|
||||||
|
|
||||||
|
self.raise_tcl_error("No such system parameter \"{}\".".format(param))
|
||||||
|
|
||||||
47
tclCommands/TclCommandVersion.py
Normal file
47
tclCommands/TclCommandVersion.py
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
from ObjectCollection import *
|
||||||
|
import TclCommand
|
||||||
|
|
||||||
|
|
||||||
|
class TclCommandVersion(TclCommand.TclCommand):
|
||||||
|
"""
|
||||||
|
Tcl shell command to check the program version.
|
||||||
|
|
||||||
|
example:
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon)
|
||||||
|
aliases = ['version']
|
||||||
|
|
||||||
|
# Dictionary of types from Tcl command, needs to be ordered
|
||||||
|
arg_names = collections.OrderedDict([
|
||||||
|
|
||||||
|
])
|
||||||
|
|
||||||
|
# Dictionary of types from Tcl command, needs to be ordered , this is for options like -optionname value
|
||||||
|
option_types = collections.OrderedDict([
|
||||||
|
|
||||||
|
])
|
||||||
|
|
||||||
|
# array of mandatory options for current Tcl command: required = {'name','outname'}
|
||||||
|
required = []
|
||||||
|
|
||||||
|
# structured help for current command, args needs to be ordered
|
||||||
|
help = {
|
||||||
|
'main': "Checks the program version.",
|
||||||
|
'args': collections.OrderedDict([
|
||||||
|
|
||||||
|
]),
|
||||||
|
'examples': []
|
||||||
|
}
|
||||||
|
|
||||||
|
def execute(self, args, unnamed_args):
|
||||||
|
"""
|
||||||
|
|
||||||
|
:param args:
|
||||||
|
:param unnamed_args:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.app.version_check()
|
||||||
|
|
||||||
@@ -19,6 +19,7 @@ import tclCommands.TclCommandExteriors
|
|||||||
import tclCommands.TclCommandGeoCutout
|
import tclCommands.TclCommandGeoCutout
|
||||||
import tclCommands.TclCommandGeoUnion
|
import tclCommands.TclCommandGeoUnion
|
||||||
import tclCommands.TclCommandGetNames
|
import tclCommands.TclCommandGetNames
|
||||||
|
import tclCommands.TclCommandGetSys
|
||||||
import tclCommands.TclCommandImportSvg
|
import tclCommands.TclCommandImportSvg
|
||||||
import tclCommands.TclCommandInteriors
|
import tclCommands.TclCommandInteriors
|
||||||
import tclCommands.TclCommandIsolate
|
import tclCommands.TclCommandIsolate
|
||||||
@@ -40,8 +41,10 @@ import tclCommands.TclCommandPlot
|
|||||||
import tclCommands.TclCommandSaveProject
|
import tclCommands.TclCommandSaveProject
|
||||||
import tclCommands.TclCommandScale
|
import tclCommands.TclCommandScale
|
||||||
import tclCommands.TclCommandSetActive
|
import tclCommands.TclCommandSetActive
|
||||||
|
import tclCommands.TclCommandSetSys
|
||||||
import tclCommands.TclCommandSubtractPoly
|
import tclCommands.TclCommandSubtractPoly
|
||||||
import tclCommands.TclCommandSubtractRectangle
|
import tclCommands.TclCommandSubtractRectangle
|
||||||
|
import tclCommands.TclCommandVersion
|
||||||
import tclCommands.TclCommandWriteGCode
|
import tclCommands.TclCommandWriteGCode
|
||||||
|
|
||||||
|
|
||||||
@@ -65,7 +68,7 @@ def register_all_commands(app, commands):
|
|||||||
I have no enough knowledge about python's anatomy. Would be nice to include all classes which are descendant etc.
|
I have no enough knowledge about python's anatomy. Would be nice to include all classes which are descendant etc.
|
||||||
|
|
||||||
:param app: FlatCAMApp
|
:param app: FlatCAMApp
|
||||||
:param commands: array of commands which should be modified
|
:param commands: List of commands being updated
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user