jpcgt/flatcam/Beta слито с Beta

This commit is contained in:
Camellan 2019-09-17 01:32:51 +04:00
commit 5569c68670
45 changed files with 1029 additions and 548 deletions

View File

@ -124,6 +124,10 @@ class App(QtCore.QObject):
# Manual URL
manual_url = "http://flatcam.org/manual/index.html"
video_url = "https://www.youtube.com/playlist?list=PLVvP2SYRpx-AQgNlfoxw93tXUXon7G94_"
gerber_spec_url ="https://www.ucamco.com/files/downloads/file/81/The_Gerber_File_Format_specification." \
"pdf?7ac957791daba2cdf4c2c913f67a43da"
excellon_spec_url = "https://www.ucamco.com/files/downloads/file/305/the_xnc_file_format_specification.pdf"
bug_report_url = "https://bitbucket.org/jpcgt/flatcam/issues?status=new&status=open"
# this variable will hold the project status
# if True it will mean that the project was modified and not saved
@ -401,20 +405,15 @@ class App(QtCore.QObject):
"global_portable": self.ui.general_defaults_form.general_app_group.portability_cb,
"global_language": self.ui.general_defaults_form.general_app_group.language_cb,
"global_shell_at_startup": self.ui.general_defaults_form.general_app_group.shell_startup_cb,
"global_version_check": self.ui.general_defaults_form.general_app_group.version_check_cb,
"global_send_stats": self.ui.general_defaults_form.general_app_group.send_stats_cb,
"global_pan_button": self.ui.general_defaults_form.general_app_group.pan_button_radio,
"global_mselect_key": self.ui.general_defaults_form.general_app_group.mselect_radio,
"global_project_at_startup": self.ui.general_defaults_form.general_app_group.project_startup_cb,
"global_project_autohide": self.ui.general_defaults_form.general_app_group.project_autohide_cb,
"global_toggle_tooltips": self.ui.general_defaults_form.general_app_group.toggle_tooltips_cb,
"global_worker_number": self.ui.general_defaults_form.general_app_group.worker_number_sb,
"global_tolerance": self.ui.general_defaults_form.general_app_group.tol_entry,
"global_open_style": self.ui.general_defaults_form.general_app_group.open_style_cb,
"global_delete_confirmation": self.ui.general_defaults_form.general_app_group.delete_conf_cb,
"global_compression_level": self.ui.general_defaults_form.general_app_group.compress_combo,
"global_save_compressed": self.ui.general_defaults_form.general_app_group.save_type_cb,
@ -442,15 +441,17 @@ class App(QtCore.QObject):
"global_layout": self.ui.general_defaults_form.general_gui_set_group.layout_combo,
"global_hover": self.ui.general_defaults_form.general_gui_set_group.hover_cb,
"global_selection_shape": self.ui.general_defaults_form.general_gui_set_group.selection_cb,
"global_shell_at_startup": self.ui.general_defaults_form.general_gui_set_group.shell_startup_cb,
"global_project_at_startup": self.ui.general_defaults_form.general_gui_set_group.project_startup_cb,
"global_project_autohide": self.ui.general_defaults_form.general_gui_set_group.project_autohide_cb,
"global_toggle_tooltips": self.ui.general_defaults_form.general_gui_set_group.toggle_tooltips_cb,
"global_delete_confirmation": self.ui.general_defaults_form.general_gui_set_group.delete_conf_cb,
# Gerber General
"gerber_plot": self.ui.gerber_defaults_form.gerber_gen_group.plot_cb,
"gerber_solid": self.ui.gerber_defaults_form.gerber_gen_group.solid_cb,
"gerber_multicolored": self.ui.gerber_defaults_form.gerber_gen_group.multicolored_cb,
"gerber_circle_steps": self.ui.gerber_defaults_form.gerber_gen_group.circle_steps_entry,
"gerber_buffering": self.ui.gerber_defaults_form.gerber_gen_group.buffering_radio,
"gerber_simplification": self.ui.gerber_defaults_form.gerber_gen_group.simplify_cb,
"gerber_simp_tolerance": self.ui.gerber_defaults_form.gerber_gen_group.simplification_tol_spinner,
# Gerber Options
"gerber_isotooldia": self.ui.gerber_defaults_form.gerber_opt_group.iso_tool_dia_entry,
@ -468,6 +469,9 @@ class App(QtCore.QObject):
# "gerber_aperture_scale_factor": self.ui.gerber_defaults_form.gerber_adv_opt_group.scale_aperture_entry,
# "gerber_aperture_buffer_factor": self.ui.gerber_defaults_form.gerber_adv_opt_group.buffer_aperture_entry,
"gerber_follow": self.ui.gerber_defaults_form.gerber_adv_opt_group.follow_cb,
"gerber_buffering": self.ui.gerber_defaults_form.gerber_adv_opt_group.buffering_radio,
"gerber_simplification": self.ui.gerber_defaults_form.gerber_adv_opt_group.simplify_cb,
"gerber_simp_tolerance": self.ui.gerber_defaults_form.gerber_adv_opt_group.simplification_tol_spinner,
# Gerber Export
"gerber_exp_units": self.ui.gerber_defaults_form.gerber_exp_group.gerber_units_radio,
@ -513,9 +517,9 @@ class App(QtCore.QObject):
# Excellon Options
"excellon_drillz": self.ui.excellon_defaults_form.excellon_opt_group.cutz_entry,
"excellon_travelz": self.ui.excellon_defaults_form.excellon_opt_group.travelz_entry,
"excellon_endz": self.ui.excellon_defaults_form.excellon_opt_group.eendz_entry,
"excellon_feedrate": self.ui.excellon_defaults_form.excellon_opt_group.feedrate_entry,
"excellon_spindlespeed": self.ui.excellon_defaults_form.excellon_opt_group.spindlespeed_entry,
"excellon_spindledir": self.ui.excellon_defaults_form.excellon_opt_group.spindledir_radio,
"excellon_dwell": self.ui.excellon_defaults_form.excellon_opt_group.dwell_cb,
"excellon_dwelltime": self.ui.excellon_defaults_form.excellon_opt_group.dwelltime_entry,
"excellon_toolchange": self.ui.excellon_defaults_form.excellon_opt_group.toolchange_cb,
@ -529,10 +533,10 @@ class App(QtCore.QObject):
"excellon_offset": self.ui.excellon_defaults_form.excellon_adv_opt_group.offset_entry,
"excellon_toolchangexy": self.ui.excellon_defaults_form.excellon_adv_opt_group.toolchangexy_entry,
"excellon_startz": self.ui.excellon_defaults_form.excellon_adv_opt_group.estartz_entry,
"excellon_endz": self.ui.excellon_defaults_form.excellon_adv_opt_group.eendz_entry,
"excellon_feedrate_rapid": self.ui.excellon_defaults_form.excellon_adv_opt_group.feedrate_rapid_entry,
"excellon_z_pdepth": self.ui.excellon_defaults_form.excellon_adv_opt_group.pdepth_entry,
"excellon_feedrate_probe": self.ui.excellon_defaults_form.excellon_adv_opt_group.feedrate_probe_entry,
"excellon_spindledir": self.ui.excellon_defaults_form.excellon_adv_opt_group.spindledir_radio,
"excellon_f_plunge": self.ui.excellon_defaults_form.excellon_adv_opt_group.fplunge_cb,
"excellon_f_retract": self.ui.excellon_defaults_form.excellon_adv_opt_group.fretract_cb,
@ -585,23 +589,23 @@ class App(QtCore.QObject):
"geometry_feedrate": self.ui.geometry_defaults_form.geometry_opt_group.cncfeedrate_entry,
"geometry_feedrate_z": self.ui.geometry_defaults_form.geometry_opt_group.cncplunge_entry,
"geometry_spindlespeed": self.ui.geometry_defaults_form.geometry_opt_group.cncspindlespeed_entry,
"geometry_spindledir": self.ui.geometry_defaults_form.geometry_opt_group.spindledir_radio,
"geometry_dwell": self.ui.geometry_defaults_form.geometry_opt_group.dwell_cb,
"geometry_dwelltime": self.ui.geometry_defaults_form.geometry_opt_group.dwelltime_entry,
"geometry_ppname_g": self.ui.geometry_defaults_form.geometry_opt_group.pp_geometry_name_cb,
"geometry_toolchange": self.ui.geometry_defaults_form.geometry_opt_group.toolchange_cb,
"geometry_toolchangez": self.ui.geometry_defaults_form.geometry_opt_group.toolchangez_entry,
"geometry_endz": self.ui.geometry_defaults_form.geometry_opt_group.gendz_entry,
"geometry_depthperpass": self.ui.geometry_defaults_form.geometry_opt_group.depthperpass_entry,
"geometry_multidepth": self.ui.geometry_defaults_form.geometry_opt_group.multidepth_cb,
# Geometry Advanced Options
"geometry_toolchangexy": self.ui.geometry_defaults_form.geometry_adv_opt_group.toolchangexy_entry,
"geometry_startz": self.ui.geometry_defaults_form.geometry_adv_opt_group.gstartz_entry,
"geometry_endz": self.ui.geometry_defaults_form.geometry_adv_opt_group.gendz_entry,
"geometry_feedrate_rapid": self.ui.geometry_defaults_form.geometry_adv_opt_group.cncfeedrate_rapid_entry,
"geometry_extracut": self.ui.geometry_defaults_form.geometry_adv_opt_group.extracut_cb,
"geometry_z_pdepth": self.ui.geometry_defaults_form.geometry_adv_opt_group.pdepth_entry,
"geometry_feedrate_probe": self.ui.geometry_defaults_form.geometry_adv_opt_group.feedrate_probe_entry,
"geometry_spindledir": self.ui.geometry_defaults_form.geometry_adv_opt_group.spindledir_radio,
"geometry_f_plunge": self.ui.geometry_defaults_form.geometry_adv_opt_group.fplunge_cb,
"geometry_segx": self.ui.geometry_defaults_form.geometry_adv_opt_group.segx_entry,
"geometry_segy": self.ui.geometry_defaults_form.geometry_adv_opt_group.segy_entry,
@ -613,8 +617,6 @@ class App(QtCore.QObject):
"cncjob_plot": self.ui.cncjob_defaults_form.cncjob_gen_group.plot_cb,
"cncjob_plot_kind": self.ui.cncjob_defaults_form.cncjob_gen_group.cncplot_method_radio,
"cncjob_annotation": self.ui.cncjob_defaults_form.cncjob_gen_group.annotation_cb,
"cncjob_annotation_fontsize": self.ui.cncjob_defaults_form.cncjob_gen_group.annotation_fontsize_sp,
"cncjob_annotation_fontcolor": self.ui.cncjob_defaults_form.cncjob_gen_group.annotation_fontcolor_entry,
"cncjob_tooldia": self.ui.cncjob_defaults_form.cncjob_gen_group.tooldia_entry,
"cncjob_coords_type": self.ui.cncjob_defaults_form.cncjob_gen_group.coords_type_radio,
@ -629,6 +631,8 @@ class App(QtCore.QObject):
# CNC Job Advanced Options
"cncjob_toolchange_macro": self.ui.cncjob_defaults_form.cncjob_adv_opt_group.toolchange_text,
"cncjob_toolchange_macro_enable": self.ui.cncjob_defaults_form.cncjob_adv_opt_group.toolchange_cb,
"cncjob_annotation_fontsize": self.ui.cncjob_defaults_form.cncjob_adv_opt_group.annotation_fontsize_sp,
"cncjob_annotation_fontcolor": self.ui.cncjob_defaults_form.cncjob_adv_opt_group.annotation_fontcolor_entry,
# NCC Tool
"tools_ncctools": self.ui.tools_defaults_form.tools_ncc_group.ncc_tool_dia_entry,
@ -677,6 +681,7 @@ class App(QtCore.QObject):
"tools_film_type": self.ui.tools_defaults_form.tools_film_group.film_type_radio,
"tools_film_boundary": self.ui.tools_defaults_form.tools_film_group.film_boundary_entry,
"tools_film_scale": self.ui.tools_defaults_form.tools_film_group.film_scale_entry,
"tools_film_color": self.ui.tools_defaults_form.tools_film_group.film_color_entry,
# Panelize Tool
"tools_panelize_spacing_columns": self.ui.tools_defaults_form.tools_panelize_group.pspacing_columns,
@ -846,6 +851,22 @@ class App(QtCore.QObject):
"global_point_clipboard_format": "(%.4f, %.4f)",
"global_zdownrate": None,
# autocomplete keywords
"global_autocomplete_keywords":
['all', 'angle_x', 'angle_y', 'axis', 'axisoffset', 'box', 'center_x', 'center_y',
'columns', 'combine', 'connect', 'contour', 'depthperpass', 'dia', 'diatol', 'dist',
'drilled_dias', 'drillz', 'pp',
'gridoffsety', 'gridx', 'gridy', 'has_offset', 'holes', 'margin', 'method',
'milled_dias',
'minoffset', 'multidepth', 'name', 'offset', 'opt_type', 'order', 'outname',
'overlap', 'passes', 'postamble', 'ppname_e', 'ppname_g', 'preamble', 'radius', 'ref',
'rest', 'rows', 'scale_factor', 'spacing_columns', 'spacing_rows', 'spindlespeed',
'use_threads', 'value', 'x', 'x0', 'x1', 'y', 'y0', 'y1', 'z_cut', 'z_move',
'default', 'feedrate_z', 'grbl_11', 'grbl_laser', 'hpgl', 'line_xyz', 'marlin',
'Paste_1', 'Repetier', 'Toolchange_Custom', 'Roland_MDX_20', 'Toolchange_manual',
'Toolchange_Probe_MACH3', 'dwell', 'dwelltime', 'toolchange_xy', 'iso_type',
'Desktop', 'FlatPrj', 'FlatConfig', 'Users', 'Documents', 'My Documents', 'Marius'
],
# General GUI Settings
"global_hover": False,
"global_selection_shape": True,
@ -857,9 +878,6 @@ class App(QtCore.QObject):
"gerber_multicolored": False,
"gerber_circle_steps": 128,
"gerber_use_buffer_for_union": True,
"gerber_buffering": "full",
"gerber_simplification": False,
"gerber_simp_tolerance": 0.0005,
# Gerber Options
"gerber_isotooldia": 0.00787402,
@ -877,6 +895,9 @@ class App(QtCore.QObject):
"gerber_aperture_scale_factor": 1.0,
"gerber_aperture_buffer_factor": 0.0,
"gerber_follow": False,
"gerber_buffering": "full",
"gerber_simplification": False,
"gerber_simp_tolerance": 0.0005,
# Gerber Export
"gerber_exp_units": 'IN',
@ -917,9 +938,9 @@ class App(QtCore.QObject):
# Excellon Options
"excellon_drillz": -0.0590551,
"excellon_travelz": 0.0787402,
"excellon_endz": 0.5,
"excellon_feedrate": 3.14961,
"excellon_spindlespeed": None,
"excellon_spindledir": 'CW',
"excellon_dwell": False,
"excellon_dwelltime": 1,
"excellon_toolchange": False,
@ -933,10 +954,10 @@ class App(QtCore.QObject):
"excellon_offset": 0.0,
"excellon_toolchangexy": "0.0, 0.0",
"excellon_startz": None,
"excellon_endz": 0.5,
"excellon_feedrate_rapid": 31.4961,
"excellon_z_pdepth": -0.02,
"excellon_feedrate_probe": 3.14961,
"excellon_spindledir": 'CW',
"excellon_f_plunge": False,
"excellon_f_retract": False,
@ -983,10 +1004,10 @@ class App(QtCore.QObject):
"geometry_travelz": 0.0787402,
"geometry_toolchange": False,
"geometry_toolchangez": 0.5,
"geometry_endz": 0.5,
"geometry_feedrate": 3.14961,
"geometry_feedrate_z": 3.14961,
"geometry_spindlespeed": None,
"geometry_spindledir": 'CW',
"geometry_dwell": False,
"geometry_dwelltime": 1,
"geometry_ppname_g": 'default',
@ -994,11 +1015,11 @@ class App(QtCore.QObject):
# Geometry Advanced Options
"geometry_toolchangexy": "0.0, 0.0",
"geometry_startz": None,
"geometry_endz": 0.5,
"geometry_feedrate_rapid": 3.14961,
"geometry_extracut": False,
"geometry_z_pdepth": -0.02,
"geometry_f_plunge": False,
"geometry_spindledir": 'CW',
"geometry_feedrate_probe": 3.14961,
"geometry_segx": 0.0,
"geometry_segy": 0.0,
@ -1010,8 +1031,6 @@ class App(QtCore.QObject):
"cncjob_plot": True,
"cncjob_plot_kind": 'all',
"cncjob_annotation": True,
"cncjob_annotation_fontsize": 9,
"cncjob_annotation_fontcolor": '#990000',
"cncjob_tooldia": 0.0393701,
"cncjob_coords_type": "G90",
"cncjob_coords_decimals": 4,
@ -1025,7 +1044,10 @@ class App(QtCore.QObject):
# CNC Job Advanced Options
"cncjob_toolchange_macro": "",
"cncjob_toolchange_macro_enable": False,
"cncjob_annotation_fontsize": 9,
"cncjob_annotation_fontcolor": '#990000',
# NCC Tool
"tools_ncctools": "0.0393701, 0.019685",
"tools_nccorder": 'rev',
"tools_nccoverlap": 0.015748,
@ -1044,6 +1066,7 @@ class App(QtCore.QObject):
"tools_ncctipdia": 0.00393701,
"tools_ncctipangle": 30,
# Cutout Tool
"tools_cutouttooldia": 0.0944882,
"tools_cutoutkind": "single",
"tools_cutoutmargin": 0.00393701,
@ -1051,6 +1074,7 @@ class App(QtCore.QObject):
"tools_gaps_ff": "4",
"tools_cutout_convexshape": False,
# Paint Tool
"tools_painttooldia": 0.023622,
"tools_paintorder": 'rev',
"tools_paintoverlap": 0.015748,
@ -1061,14 +1085,18 @@ class App(QtCore.QObject):
"tools_paintcontour": True,
"tools_paint_plotting": 'normal',
# 2-Sided Tool
"tools_2sided_mirror_axis": "X",
"tools_2sided_axis_loc": "point",
"tools_2sided_drilldia": 0.0393701,
# Film Tool
"tools_film_type": 'neg',
"tools_film_boundary": 0.0393701,
"tools_film_scale": 0,
"tools_film_color": '#000000',
# Panel Tool
"tools_panelize_spacing_columns": 0,
"tools_panelize_spacing_rows": 0,
"tools_panelize_columns": 1,
@ -1078,6 +1106,7 @@ class App(QtCore.QObject):
"tools_panelize_constrainy": 0.0,
"tools_panelize_panel_type": 'gerber',
# Calculators Tool
"tools_calc_vshape_tip_dia": 0.007874,
"tools_calc_vshape_tip_angle": 30,
"tools_calc_vshape_cut_z": 0.000787,
@ -1086,6 +1115,7 @@ class App(QtCore.QObject):
"tools_calc_electro_cdensity": 13.0,
"tools_calc_electro_growth": 10.0,
# Transform Tool
"tools_transform_rotate": 90,
"tools_transform_skew_x": 0.0,
"tools_transform_skew_y": 0.0,
@ -1098,6 +1128,7 @@ class App(QtCore.QObject):
"tools_transform_mirror_reference": False,
"tools_transform_mirror_point": (0, 0),
# SolderPaste Tool
"tools_solderpaste_tools": "0.0393701, 0.011811",
"tools_solderpaste_new": 0.011811,
"tools_solderpaste_z_start": 0.00019685039,
@ -1115,6 +1146,7 @@ class App(QtCore.QObject):
"tools_solderpaste_dwellrev": 1,
"tools_solderpaste_pp": 'Paste_1',
# Subtract Tool
"tools_sub_close_paths": True,
# file associations
@ -1204,9 +1236,9 @@ class App(QtCore.QObject):
"excellon_drillz": self.ui.excellon_options_form.excellon_opt_group.cutz_entry,
"excellon_travelz": self.ui.excellon_options_form.excellon_opt_group.travelz_entry,
"excellon_endz": self.ui.excellon_options_form.excellon_opt_group.eendz_entry,
"excellon_feedrate": self.ui.excellon_options_form.excellon_opt_group.feedrate_entry,
"excellon_spindlespeed": self.ui.excellon_options_form.excellon_opt_group.spindlespeed_entry,
"excellon_spindledir": self.ui.excellon_options_form.excellon_opt_group.spindledir_radio,
"excellon_dwell": self.ui.excellon_options_form.excellon_opt_group.dwell_cb,
"excellon_dwelltime": self.ui.excellon_options_form.excellon_opt_group.dwelltime_entry,
"excellon_toolchange": self.ui.excellon_options_form.excellon_opt_group.toolchange_cb,
@ -1218,7 +1250,7 @@ class App(QtCore.QObject):
"excellon_toolchangexy": self.ui.excellon_options_form.excellon_adv_opt_group.toolchangexy_entry,
"excellon_f_plunge": self.ui.excellon_options_form.excellon_adv_opt_group.fplunge_cb,
"excellon_startz": self.ui.excellon_options_form.excellon_adv_opt_group.estartz_entry,
"excellon_endz": self.ui.excellon_options_form.excellon_adv_opt_group.eendz_entry,
"excellon_spindledir": self.ui.excellon_options_form.excellon_adv_opt_group.spindledir_radio,
"geometry_plot": self.ui.geometry_options_form.geometry_gen_group.plot_cb,
"geometry_cnctooldia": self.ui.geometry_options_form.geometry_gen_group.cnctooldia_entry,
@ -1228,12 +1260,12 @@ class App(QtCore.QObject):
"geometry_feedrate": self.ui.geometry_options_form.geometry_opt_group.cncfeedrate_entry,
"geometry_feedrate_z": self.ui.geometry_options_form.geometry_opt_group.cncplunge_entry,
"geometry_spindlespeed": self.ui.geometry_options_form.geometry_opt_group.cncspindlespeed_entry,
"geometry_spindledir": self.ui.geometry_options_form.geometry_opt_group.spindledir_radio,
"geometry_dwell": self.ui.geometry_options_form.geometry_opt_group.dwell_cb,
"geometry_dwelltime": self.ui.geometry_options_form.geometry_opt_group.dwelltime_entry,
"geometry_ppname_g": self.ui.geometry_options_form.geometry_opt_group.pp_geometry_name_cb,
"geometry_toolchange": self.ui.geometry_options_form.geometry_opt_group.toolchange_cb,
"geometry_toolchangez": self.ui.geometry_options_form.geometry_opt_group.toolchangez_entry,
"geometry_endz": self.ui.geometry_options_form.geometry_opt_group.gendz_entry,
"geometry_depthperpass": self.ui.geometry_options_form.geometry_opt_group.depthperpass_entry,
"geometry_multidepth": self.ui.geometry_options_form.geometry_opt_group.multidepth_cb,
@ -1241,9 +1273,9 @@ class App(QtCore.QObject):
"geometry_segy": self.ui.geometry_options_form.geometry_adv_opt_group.segy_entry,
"geometry_feedrate_rapid": self.ui.geometry_options_form.geometry_adv_opt_group.cncfeedrate_rapid_entry,
"geometry_f_plunge": self.ui.geometry_options_form.geometry_adv_opt_group.fplunge_cb,
"geometry_spindledir": self.ui.geometry_options_form.geometry_adv_opt_group.spindledir_radio,
"geometry_toolchangexy": self.ui.geometry_options_form.geometry_adv_opt_group.toolchangexy_entry,
"geometry_startz": self.ui.geometry_options_form.geometry_adv_opt_group.gstartz_entry,
"geometry_endz": self.ui.geometry_options_form.geometry_adv_opt_group.gendz_entry,
"geometry_extracut": self.ui.geometry_options_form.geometry_adv_opt_group.extracut_cb,
"cncjob_plot": self.ui.cncjob_options_form.cncjob_gen_group.plot_cb,
@ -1487,10 +1519,17 @@ class App(QtCore.QObject):
"background-color:%s" % str(self.defaults['global_proj_item_dis_color'])[:7])
# Init the Annotation CNC Job color
self.ui.cncjob_defaults_form.cncjob_gen_group.annotation_fontcolor_entry.set_value(
self.ui.cncjob_defaults_form.cncjob_adv_opt_group.annotation_fontcolor_entry.set_value(
self.defaults['cncjob_annotation_fontcolor'])
self.ui.cncjob_defaults_form.cncjob_gen_group.annotation_fontcolor_button.setStyleSheet(
self.ui.cncjob_defaults_form.cncjob_adv_opt_group.annotation_fontcolor_button.setStyleSheet(
"background-color:%s" % str(self.defaults['cncjob_annotation_fontcolor'])[:7])
# Init the Tool Film color
self.ui.tools_defaults_form.tools_film_group.film_color_entry.set_value(
self.defaults['tools_film_color'])
self.ui.tools_defaults_form.tools_film_group.film_color_button.setStyleSheet(
"background-color:%s" % str(self.defaults['tools_film_color'])[:7])
# ### End of Data ####
# ###############################################
@ -1671,6 +1710,9 @@ class App(QtCore.QObject):
self.ui.menuhelp_about.triggered.connect(self.on_about)
self.ui.menuhelp_home.triggered.connect(lambda: webbrowser.open(self.app_url))
self.ui.menuhelp_manual.triggered.connect(lambda: webbrowser.open(self.manual_url))
self.ui.menuhelp_report_bug.triggered.connect(lambda: webbrowser.open(self.bug_report_url))
self.ui.menuhelp_exc_spec.triggered.connect(lambda: webbrowser.open(self.excellon_spec_url))
self.ui.menuhelp_gerber_spec.triggered.connect(lambda: webbrowser.open(self.gerber_spec_url))
self.ui.menuhelp_videohelp.triggered.connect(lambda: webbrowser.open(self.video_url))
self.ui.menuhelp_shortcut_list.triggered.connect(self.on_shortcut_list)
@ -1809,11 +1851,17 @@ class App(QtCore.QObject):
# ########## CNC Job related signals #############
self.ui.cncjob_defaults_form.cncjob_adv_opt_group.tc_variable_combo.currentIndexChanged[str].connect(
self.on_cnc_custom_parameters)
self.ui.cncjob_defaults_form.cncjob_gen_group.annotation_fontcolor_entry.editingFinished.connect(
self.ui.cncjob_defaults_form.cncjob_adv_opt_group.annotation_fontcolor_entry.editingFinished.connect(
self.on_annotation_fontcolor_entry)
self.ui.cncjob_defaults_form.cncjob_gen_group.annotation_fontcolor_button.clicked.connect(
self.ui.cncjob_defaults_form.cncjob_adv_opt_group.annotation_fontcolor_button.clicked.connect(
self.on_annotation_fontcolor_button)
# ########## Tools related signals #############
self.ui.tools_defaults_form.tools_film_group.film_color_entry.editingFinished.connect(
self.on_film_color_entry)
self.ui.tools_defaults_form.tools_film_group.film_color_button.clicked.connect(
self.on_film_color_button)
# ########## Modify G-CODE Plot Area TAB ###########
self.ui.code_editor.textChanged.connect(self.handleTextChanged)
self.ui.buttonOpen.clicked.connect(self.handleOpen)
@ -1830,7 +1878,7 @@ class App(QtCore.QObject):
self.collection.view.activated.connect(self.on_row_activated)
# Monitor the checkbox from the Application Defaults Tab and show the TCL shell or not depending on it's value
self.ui.general_defaults_form.general_app_group.shell_startup_cb.clicked.connect(self.on_toggle_shell)
self.ui.general_defaults_form.general_gui_set_group.shell_startup_cb.clicked.connect(self.on_toggle_shell)
# Make sure that when the Excellon loading parameters are changed, the change is reflected in the
# Export Excellon parameters.
@ -1900,27 +1948,13 @@ class App(QtCore.QObject):
'mirror', 'ncc',
'ncc_clear', 'ncr', 'new', 'new_geometry', 'non_copper_regions', 'offset',
'open_excellon', 'open_gcode', 'open_gerber', 'open_project', 'options', 'paint',
'pan', 'panel', 'panelize', 'plot', 'save', 'save_project', 'save_sys', 'scale',
'pan', 'panel', 'panelize', 'plot_all', 'plot_objects', 'save', 'save_project',
'save_sys', 'scale',
'set_active', 'set_sys', 'setsys', 'skew', 'subtract_poly', 'subtract_rectangle',
'version', 'write_gcode'
]
self.ordinary_keywords = ['all', 'angle_x', 'angle_y', 'axis', 'axisoffset', 'box', 'center_x', 'center_y',
'columns', 'combine', 'connect', 'contour', 'depthperpass', 'dia', 'diatol', 'dist',
'drilled_dias', 'drillz', 'pp',
'endz', 'extracut', 'factor', 'False', 'false', 'feedrate', 'feedrate_rapid',
'filename', 'follow', 'gaps', 'gapsize', 'grid', 'gridoffset', 'gridoffsetx',
'gridoffsety', 'gridx', 'gridy', 'has_offset', 'holes', 'margin', 'method',
'milled_dias',
'minoffset', 'multidepth', 'name', 'offset', 'opt_type', 'order', 'outname',
'overlap', 'passes', 'postamble', 'ppname_e', 'ppname_g', 'preamble', 'radius', 'ref',
'rest', 'rows', 'scale_factor', 'spacing_columns', 'spacing_rows', 'spindlespeed',
'toolchange', 'toolchangez', 'tooldia', 'tools', 'travelz', 'True', 'true', 'type',
'use_threads', 'value', 'x', 'x0', 'x1', 'y', 'y0', 'y1', 'z_cut', 'z_move',
'default', 'feedrate_z', 'grbl_11', 'grbl_laser', 'hpgl', 'line_xyz', 'marlin',
'Paste_1', 'Repetier', 'Toolchange_Custom', 'Roland_MDX_20', 'Toolchange_manual',
'Toolchange_Probe_MACH3', 'dwell', 'dwelltime', 'toolchange_xy'
]
self.ordinary_keywords = self.defaults["global_autocomplete_keywords"]
self.tcl_keywords = [
'after', 'append', 'apply', 'argc', 'argv', 'argv0', 'array', 'attemptckalloc', 'attemptckrealloc',
@ -2255,6 +2289,10 @@ class App(QtCore.QObject):
# Variable to store the GCODE that was edited
self.gcode_edited = ""
# reference for the self.ui.code_editor
self.reference_code_editor = None
self.script_code = ''
# if Preferences are changed in the Edit -> Preferences tab the value will be set to True
self.preferences_changed_flag = False
@ -3064,8 +3102,8 @@ class App(QtCore.QObject):
result = self.exec_command_test(text, False)
# MS: added this method call so the geometry is updated once the TCL command is executed
if no_plot is None:
self.plot_all()
# if no_plot is None:
# self.plot_all()
return result
@ -5554,8 +5592,8 @@ class App(QtCore.QObject):
def on_annotation_fontcolor_entry(self):
self.defaults['cncjob_annotation_fontcolor'] = \
self.ui.cncjob_defaults_form.cncjob_gen_group.annotation_fontcolor_entry.get_value()
self.ui.cncjob_defaults_form.cncjob_gen_group.annotation_fontcolor_button.setStyleSheet(
self.ui.cncjob_defaults_form.cncjob_adv_opt_group.annotation_fontcolor_entry.get_value()
self.ui.cncjob_defaults_form.cncjob_adv_opt_group.annotation_fontcolor_button.setStyleSheet(
"background-color:%s" % str(self.defaults['cncjob_annotation_fontcolor']))
def on_annotation_fontcolor_button(self):
@ -5567,12 +5605,38 @@ class App(QtCore.QObject):
if annotation_color.isValid() is False:
return
self.ui.cncjob_defaults_form.cncjob_gen_group.annotation_fontcolor_button.setStyleSheet(
self.ui.cncjob_defaults_form.cncjob_adv_opt_group.annotation_fontcolor_button.setStyleSheet(
"background-color:%s" % str(annotation_color.name()))
new_val_sel = str(annotation_color.name())
self.ui.cncjob_defaults_form.cncjob_gen_group.annotation_fontcolor_entry.set_value(new_val_sel)
self.defaults['global_proj_item_dis_color'] = new_val_sel
self.ui.cncjob_defaults_form.cncjob_adv_opt_group.annotation_fontcolor_entry.set_value(new_val_sel)
self.defaults['cncjob_annotation_fontcolor'] = new_val_sel
def on_film_color_entry(self):
self.defaults['tools_film_color'] = \
self.ui.tools_defaults_form.tools_film_group.film_color_entry.get_value()
self.ui.tools_defaults_form.tools_film_group.film_color_button.setStyleSheet(
"background-color:%s" % str(self.defaults['tools_film_color']))
def on_film_color_button(self):
current_color = QtGui.QColor(self.defaults['tools_film_color'])
c_dialog = QtWidgets.QColorDialog()
film_color = c_dialog.getColor(initial=current_color)
if film_color.isValid() is False:
return
# if new color is different then mark that the Preferences are changed
if film_color != current_color:
self.on_preferences_edited()
self.ui.tools_defaults_form.tools_film_group.film_color_button.setStyleSheet(
"background-color:%s" % str(film_color.name()))
new_val_sel = str(film_color.name())
self.ui.tools_defaults_form.tools_film_group.film_color_entry.set_value(new_val_sel)
self.defaults['tools_film_color'] = new_val_sel
def on_splash_changed(self, state):
settings = QSettings("Open Source", "FlatCAM")
@ -5915,11 +5979,11 @@ class App(QtCore.QObject):
if self.ui.shell_dock.isHidden():
self.ui.shell_dock.show()
script_code = self.ui.code_editor.toPlainText()
self.script_code = deepcopy(self.ui.code_editor.toPlainText())
# self.shell._sysShell.exec_command(script_code)
old_line = ''
for tcl_command_line in script_code.splitlines():
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
@ -5942,17 +6006,16 @@ class App(QtCore.QObject):
self.shell.append_output(result + '\n')
old_line = ''
except tk.TclError as e:
except tk.TclError:
old_line = old_line + tcl_command_line + '\n'
except Exception as e:
log.debug("App.handleRunCode() --> %s" % str(e))
if old_line != '':
# it means that the script finished with an error
result = self.tcl.eval("set errorInfo")
self.log.error("Exec command Exception: %s" % (result + '\n'))
self.shell.append_error('ERROR: ' + result + '\n')
else:
# success! plot all objects
self.plot_all()
self.shell.close_proccessing()
@ -7522,7 +7585,7 @@ class App(QtCore.QObject):
self.inform.emit('[success] %s...' %
_("New Project created"))
def on_file_new(self):
def on_file_new(self, cli=None):
"""
Callback for menu item File->New. Returns the application to its
startup state. This method is thread-safe.
@ -7582,15 +7645,16 @@ class App(QtCore.QObject):
# Init Tools
self.init_tools()
# Close any Tabs opened in the Plot Tab Area section
for index in range(self.ui.plot_tab_area.count()):
self.ui.plot_tab_area.closeTab(index)
# for whatever reason previous command does not close the last tab so I do it manually
self.ui.plot_tab_area.closeTab(0)
if cli is None:
# Close any Tabs opened in the Plot Tab Area section
for index in range(self.ui.plot_tab_area.count()):
self.ui.plot_tab_area.closeTab(index)
# for whatever reason previous command does not close the last tab so I do it manually
self.ui.plot_tab_area.closeTab(0)
# # And then add again the Plot Area
self.ui.plot_tab_area.addTab(self.ui.plot_tab, "Plot Area")
self.ui.plot_tab_area.protectTab(0)
# # And then add again the Plot Area
self.ui.plot_tab_area.addTab(self.ui.plot_tab, "Plot Area")
self.ui.plot_tab_area.protectTab(0)
# take the focus of the Notebook on Project Tab.
self.ui.notebook.setCurrentWidget(self.ui.project_tab)
@ -8201,6 +8265,9 @@ class App(QtCore.QObject):
self.ui.code_editor.completer_enable = False
self.ui.buttonRun.hide()
# make sure to keep a reference to the code editor
self.reference_code_editor = self.ui.code_editor
# Switch plot_area to CNCJob tab
self.ui.plot_tab_area.setCurrentWidget(self.ui.cncjob_tab)
@ -8219,20 +8286,37 @@ class App(QtCore.QObject):
if obj.kind == 'gerber':
flt = "Gerber Files (*.GBR);;All Files (*.*)"
else:
elif obj.kind == 'excellon':
flt = "Excellon Files (*.DRL);;All Files (*.*)"
elif obj.kind == 'cncjob':
"GCode Files (*.NC);;All Files (*.*)"
else:
flt = "All Files (*.*)"
self.init_code_editor(name=_("Source Editor"))
self.ui.buttonOpen.clicked.connect(lambda: self.handleOpen(filt=flt))
self.ui.buttonSave.clicked.connect(lambda: self.handleSaveGCode(filt=flt))
# then append the text from GCode to the text editor
try:
file = StringIO(obj.source_file)
except AttributeError:
self.inform.emit('[WARNING_NOTCL] %s' %
_("There is no selected object for which to see it's source file code."))
return 'fail'
if obj.kind == 'cncjob':
try:
file = obj.export_gcode(
preamble=self.defaults["cncjob_prepend"],
postamble=self.defaults["cncjob_append"],
to_file=True)
if file == 'fail':
return 'fail'
except AttributeError:
self.inform.emit('[WARNING_NOTCL] %s' %
_("There is no selected object for which to see it's source file code."))
return 'fail'
else:
try:
file = StringIO(obj.source_file)
except AttributeError:
self.inform.emit('[WARNING_NOTCL] %s' %
_("There is no selected object for which to see it's source file code."))
return 'fail'
self.ui.cncjob_frame.hide()
try:
@ -8289,6 +8373,10 @@ class App(QtCore.QObject):
self.ui.buttonOpen.clicked.connect(lambda: self.handleOpen(filt=flt))
self.ui.buttonSave.clicked.connect(lambda: self.handleSaveGCode(filt=flt))
self.ui.buttonRun.show()
try:
self.ui.buttonRun.clicked.disconnect(self.handleRunCode)
except TypeError:
pass
self.ui.buttonRun.clicked.connect(self.handleRunCode)
self.handleTextChanged()
@ -8556,8 +8644,6 @@ class App(QtCore.QObject):
def make_negative_film():
exported_svg = obj.export_svg(scale_factor=scale_factor)
self.progress.emit(40)
# Determine bounding area for svg export
bounds = box.bounds()
size = box.size()
@ -8583,8 +8669,6 @@ class App(QtCore.QObject):
svg_header += '<g transform="scale(1,-1)">'
svg_footer = '</g> </svg>'
self.progress.emit(60)
# Change the attributes of the exported SVG
# We don't need stroke-width - wrong, we do when we have lines with certain width
# We set opacity to maximum
@ -8613,7 +8697,6 @@ class App(QtCore.QObject):
exported_svg = ET.tostring(root)
svg_elem = svg_header + str(exported_svg) + svg_footer
self.progress.emit(80)
# Parse the xml through a xml parser just to add line feeds
# and to make it look more pretty for the output
@ -8627,7 +8710,6 @@ class App(QtCore.QObject):
"Most likely another app is holding the file open and not accessible."))
return 'fail'
self.progress.emit(100)
if self.defaults["global_open_style"] is False:
self.file_opened.emit("SVG", filename)
self.file_saved.emit("SVG", filename)
@ -8649,7 +8731,7 @@ class App(QtCore.QObject):
else:
make_negative_film()
def export_svg_black(self, obj_name, box_name, filename, scale_factor=0.00, use_thread=True):
def export_svg_positive(self, obj_name, box_name, filename, scale_factor=0.00, use_thread=True):
"""
Exports a Geometry Object to an SVG file in positive black.
@ -8660,7 +8742,7 @@ class App(QtCore.QObject):
:param use_thread: if to be run in a separate thread; boolean
:return:
"""
self.report_usage("export_svg_black()")
self.report_usage("export_svg_positive()")
if filename is None:
filename = self.defaults["global_last_save_folder"]
@ -8684,7 +8766,7 @@ class App(QtCore.QObject):
(_("No object Box. Using instead"), obj))
box = obj
def make_black_film():
def make_positive_film():
exported_svg = obj.export_svg(scale_factor=scale_factor)
self.progress.emit(40)
@ -8695,9 +8777,9 @@ class App(QtCore.QObject):
# We set the colour to WHITE
root = ET.fromstring(exported_svg)
for child in root:
child.set('fill', '#000000')
child.set('fill', str(self.defaults['tools_film_color']))
child.set('opacity', '1.0')
child.set('stroke', '#000000')
child.set('stroke', str(self.defaults['tools_film_color']))
exported_svg = ET.tostring(root)
@ -8765,7 +8847,7 @@ class App(QtCore.QObject):
def job_thread_film(app_obj):
try:
make_black_film()
make_positive_film()
except Exception as e:
proc.done()
return
@ -8773,7 +8855,7 @@ class App(QtCore.QObject):
self.worker_task.emit({'fcn': job_thread_film, 'params': [self]})
else:
make_black_film()
make_positive_film()
def save_source_file(self, obj_name, filename, use_thread=True):
"""
@ -9375,7 +9457,7 @@ class App(QtCore.QObject):
self.inform.emit('[success] %s: %s' %
(_("Opened"), filename))
def open_excellon(self, filename, outname=None):
def open_excellon(self, filename, outname=None, plot=True):
"""
Opens an Excellon file, parses it and creates a new object for
it in the program. Thread-safe.
@ -9429,7 +9511,7 @@ class App(QtCore.QObject):
# Object name
name = outname or filename.split('/')[-1].split('\\')[-1]
ret_val = self.new_object("excellon", name, obj_init, autoselected=False)
ret_val = self.new_object("excellon", name, obj_init, autoselected=False, plot=plot)
if ret_val == 'fail':
self.inform.emit('[ERROR_NOTCL] %s' %
_('Open Excellon file failed. Probable not an Excellon file.'))
@ -9442,7 +9524,7 @@ class App(QtCore.QObject):
self.inform.emit('[success] %s: %s' %
(_("Opened"), filename))
def open_gcode(self, filename, outname=None):
def open_gcode(self, filename, outname=None, plot=True):
"""
Opens a G-gcode file, parses it and creates a new object for
it in the program. Thread-safe.
@ -9494,7 +9576,7 @@ class App(QtCore.QObject):
name = outname or filename.split('/')[-1].split('\\')[-1]
# New object creation and file processing
ret = self.new_object("cncjob", name, obj_init, autoselected=False)
ret = self.new_object("cncjob", name, obj_init, autoselected=False, plot=plot)
if ret == 'fail':
self.inform.emit('[ERROR_NOTCL] %s' %
_("Failed to create CNCJob Object. Probable not a GCode file.\n "
@ -9542,7 +9624,7 @@ class App(QtCore.QObject):
(_("Failed to open config file"), filename))
return
def open_project(self, filename, run_from_arg=None):
def open_project(self, filename, run_from_arg=None, plot=True, cli=None):
"""
Loads a project from the specified file.
@ -9551,16 +9633,21 @@ class App(QtCore.QObject):
3) Calls on_file_new()
4) Updates options
5) Calls new_object() with the object's from_dict() as init method.
6) Calls plot_all()
6) Calls plot_all() if plot=True
:param filename: Name of the file from which to load.
:type filename: str
:param run_from_arg: True if run for arguments
:param plot: If True plot all objects in the project
:param cli: run from command line
:return: None
"""
App.log.debug("Opening project: " + filename)
self.set_ui_title(name=_("Loading Project ... Please Wait ..."))
# for some reason, setting ui_title does not work when this method is called from Tcl Shell
# it's because the TclCommand is run in another thread (it inherit TclCommandSignaled)
if cli is None:
self.set_ui_title(name=_("Loading Project ... Please Wait ..."))
# Open and parse an uncompressed Project file
try:
@ -9583,7 +9670,6 @@ class App(QtCore.QObject):
with lzma.open(filename) as f:
file_content = f.read().decode('utf-8')
d = json.loads(file_content, object_hook=dict2obj)
except Exception as e:
App.log.error("Failed to open project file: %s with error: %s" % (filename, str(e)))
self.inform.emit('[ERROR_NOTCL] %s: %s' %
@ -9594,13 +9680,19 @@ class App(QtCore.QObject):
# # NOT THREAD SAFE # ##
if run_from_arg is True:
pass
elif cli is True:
self.delete_selection_shape()
else:
self.on_file_new()
# Project options
self.options.update(d['options'])
self.project_filename = filename
self.set_screen_units(self.options["units"])
# for some reason, setting ui_title does not work when this method is called from Tcl Shell
# it's because the TclCommand is run in another thread (it inherit TclCommandSignaled)
if cli is None:
self.set_screen_units(self.options["units"])
# Re create objects
App.log.debug(" **************** Started PROEJCT loading... **************** ")
@ -9608,24 +9700,31 @@ class App(QtCore.QObject):
for obj in d['objs']:
def obj_init(obj_inst, app_inst):
obj_inst.from_dict(obj)
App.log.debug("Recreating from opened project an %s object: %s" %
(obj['kind'].capitalize(), obj['options']['name']))
self.set_ui_title(name="{} {}: {}".format(_("Loading Project ... restoring"),
obj['kind'].upper(),
obj['options']['name']
)
)
# for some reason, setting ui_title does not work when this method is called from Tcl Shell
# it's because the TclCommand is run in another thread (it inherit TclCommandSignaled)
if cli is None:
self.set_ui_title(name="{} {}: {}".format(_("Loading Project ... restoring"),
obj['kind'].upper(),
obj['options']['name']
)
)
self.new_object(obj['kind'], obj['options']['name'], obj_init, active=False, fit=False, plot=True)
self.new_object(obj['kind'], obj['options']['name'], obj_init, active=False, fit=False, plot=plot)
# self.plot_all()
self.inform.emit('[success] %s: %s' %
(_("Project loaded from"), filename))
self.should_we_save = False
self.file_opened.emit("project", filename)
self.set_ui_title(name=self.project_filename)
# for some reason, setting ui_title does not work when this method is called from Tcl Shell
# it's because the TclCommand is run in another thread (it inherit TclCommandSignaled)
if cli is None:
self.set_ui_title(name=self.project_filename)
App.log.debug(" **************** Finished PROJECT loading... **************** ")

View File

@ -600,7 +600,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
# Show/Hide Advanced Options
if self.app.defaults["global_app_level"] == 'b':
self.ui.level.setText(_(
'<span style="color:green;"><b>Basic</b></span>'
'<span style="color:green;"><b>%s</b></span>' % _('Basic')
))
self.ui.apertures_table_label.hide()
self.ui.aperture_table_visibility_cb.hide()
@ -613,7 +613,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
self.ui.except_cb.hide()
else:
self.ui.level.setText(_(
'<span style="color:red;"><b>Advanced</b></span>'
'<span style="color:red;"><b>%s</b></span>' % _('Advanced')
))
if self.app.defaults["gerber_buffering"] == 'no':
@ -923,8 +923,8 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
except Exception as e:
return "Operation failed: %s" % str(e)
def isolate(self, iso_type=None, dia=None, passes=None, overlap=None,
outname=None, combine=None, milling_type=None, follow=None):
def isolate(self, iso_type=None, dia=None, passes=None, overlap=None, outname=None, combine=None,
milling_type=None, follow=None, plot=True):
"""
Creates an isolation routing geometry object in the project.
@ -947,13 +947,13 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
combine = bool(combine)
if milling_type is None:
milling_type = self.options["milling_type"]
if iso_type is None:
self.iso_type = 2
else:
self.iso_type = iso_type
base_name = self.options["name"] + "_iso"
base_name = outname or base_name
base_name = self.options["name"]
def generate_envelope(offset, invert, envelope_iso_type=2, follow=None, passes=0):
# isolation_geometry produces an envelope that is going on the left of the geometry
@ -1061,12 +1061,15 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
return new_geometry
if combine:
if self.iso_type == 0:
iso_name = self.options["name"] + "_ext_iso"
elif self.iso_type == 1:
iso_name = self.options["name"] + "_int_iso"
if outname is None:
if self.iso_type == 0:
iso_name = base_name + "_ext_iso"
elif self.iso_type == 1:
iso_name = base_name + "_int_iso"
else:
iso_name = base_name + "_iso"
else:
iso_name = base_name
iso_name = outname
# TODO: This is ugly. Create way to pass data into init function.
def iso_init(geo_obj, app_obj):
@ -1161,25 +1164,31 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
geo_obj.solid_geometry = area_subtraction(geo_obj.solid_geometry)
# TODO: Do something if this is None. Offer changing name?
self.app.new_object("geometry", iso_name, iso_init)
self.app.new_object("geometry", iso_name, iso_init, plot=plot)
else:
for i in range(passes):
offset = dia * ((2 * i + 1) / 2.0) - (i * overlap * dia)
if passes > 1:
if self.iso_type == 0:
iso_name = self.options["name"] + "_ext_iso" + str(i + 1)
elif self.iso_type == 1:
iso_name = self.options["name"] + "_int_iso" + str(i + 1)
if outname is None:
if self.iso_type == 0:
iso_name = base_name + "_ext_iso" + str(i + 1)
elif self.iso_type == 1:
iso_name = base_name + "_int_iso" + str(i + 1)
else:
iso_name = base_name + "_iso" + str(i + 1)
else:
iso_name = base_name + str(i + 1)
iso_name = outname
else:
if self.iso_type == 0:
iso_name = self.options["name"] + "_ext_iso"
elif self.iso_type == 1:
iso_name = self.options["name"] + "_int_iso"
if outname is None:
if self.iso_type == 0:
iso_name = base_name + "_ext_iso"
elif self.iso_type == 1:
iso_name = base_name + "_int_iso"
else:
iso_name = base_name + "_iso"
else:
iso_name = base_name
iso_name = outname
# TODO: This is ugly. Create way to pass data into init function.
def iso_init(geo_obj, app_obj):
@ -1230,7 +1239,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
geo_obj.solid_geometry = area_subtraction(geo_obj.solid_geometry)
# TODO: Do something if this is None. Offer changing name?
self.app.new_object("geometry", iso_name, iso_init)
self.app.new_object("geometry", iso_name, iso_init, plot=plot)
def on_plot_cb_click(self, *args):
if self.muted_ui:
@ -2316,14 +2325,12 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
# Show/Hide Advanced Options
if self.app.defaults["global_app_level"] == 'b':
self.ui.level.setText(_(
'<span style="color:green;"><b>Basic</b></span>'
'<span style="color:green;"><b>%s</b></span>' % _('Basic')
))
self.ui.tools_table.setColumnHidden(4, True)
self.ui.estartz_label.hide()
self.ui.estartz_entry.hide()
self.ui.eendz_label.hide()
self.ui.eendz_entry.hide()
self.ui.feedrate_rapid_label.hide()
self.ui.feedrate_rapid_entry.hide()
self.ui.pdepth_label.hide()
@ -2332,7 +2339,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
self.ui.feedrate_probe_entry.hide()
else:
self.ui.level.setText(_(
'<span style="color:red;"><b>Advanced</b></span>'
'<span style="color:red;"><b>%s</b></span>' % _('Advanced')
))
assert isinstance(self.ui, ExcellonObjectUI), \
@ -2595,7 +2602,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
return has_slots, excellon_code
def generate_milling_drills(self, tools=None, outname=None, tooldia=None, use_thread=False):
def generate_milling_drills(self, tools=None, outname=None, tooldia=None, plot=False, use_thread=False):
"""
Note: This method is a good template for generic operations as
it takes it's options from parameters or otherwise from the
@ -2674,7 +2681,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
Point(hole['point']).buffer(buffer_value).exterior)
if use_thread:
def geo_thread(app_obj):
app_obj.new_object("geometry", outname, geo_init)
app_obj.new_object("geometry", outname, geo_init, plot=plot)
app_obj.progress.emit(100)
# Create a promise with the new name
@ -2683,11 +2690,11 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
# Send to worker
self.app.worker_task.emit({'fcn': geo_thread, 'params': [self.app]})
else:
self.app.new_object("geometry", outname, geo_init)
self.app.new_object("geometry", outname, geo_init, plot=plot)
return True, ""
def generate_milling_slots(self, tools=None, outname=None, tooldia=None, use_thread=False):
def generate_milling_slots(self, tools=None, outname=None, tooldia=None, plot=True, use_thread=False):
"""
Note: This method is a good template for generic operations as
it takes it's options from parameters or otherwise from the
@ -2781,7 +2788,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
if use_thread:
def geo_thread(app_obj):
app_obj.new_object("geometry", outname + '_slot', geo_init)
app_obj.new_object("geometry", outname + '_slot', geo_init, plot=plot)
app_obj.progress.emit(100)
# Create a promise with the new name
@ -2790,7 +2797,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
# Send to worker
self.app.worker_task.emit({'fcn': geo_thread, 'params': [self.app]})
else:
self.app.new_object("geometry", outname + '_slot', geo_init)
self.app.new_object("geometry", outname + '_slot', geo_init, plot=plot)
return True, ""
@ -3596,7 +3603,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
# Show/Hide Advanced Options
if self.app.defaults["global_app_level"] == 'b':
self.ui.level.setText(_(
'<span style="color:green;"><b>Basic</b></span>'
'<span style="color:green;"><b>%s</b></span>' % _('Basic')
))
self.ui.geo_tools_table.setColumnHidden(2, True)
@ -3607,8 +3614,8 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
self.ui.addtool_btn.hide()
self.ui.copytool_btn.hide()
self.ui.deltool_btn.hide()
self.ui.endzlabel.hide()
self.ui.gendz_entry.hide()
# self.ui.endzlabel.hide()
# self.ui.gendz_entry.hide()
self.ui.fr_rapidlabel.hide()
self.ui.cncfeedrate_rapid_entry.hide()
self.ui.extracut_cb.hide()
@ -3618,7 +3625,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
self.ui.feedrate_probe_entry.hide()
else:
self.ui.level.setText(_(
'<span style="color:red;"><b>Advanced</b></span>'
'<span style="color:red;"><b>%s</b></span>' % _('Advanced')
))
self.ui.plot_cb.stateChanged.connect(self.on_plot_cb_click)
self.ui.generate_cnc_button.clicked.connect(self.on_generatecnc_button_click)
@ -4518,7 +4525,8 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
self.app.inform.emit('[ERROR_NOTCL] %s' %
_("Failed. No tool selected in the tool table ..."))
def mtool_gen_cncjob(self, outname=None, tools_dict=None, tools_in_use=None, segx=None, segy=None, use_thread=True):
def mtool_gen_cncjob(self, outname=None, tools_dict=None, tools_in_use=None, segx=None, segy=None,
plot=True, use_thread=True):
"""
Creates a multi-tool CNCJob out of this Geometry object.
The actual work is done by the target FlatCAMCNCjob object's
@ -4875,7 +4883,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
def job_thread(app_obj):
if self.solid_geometry:
with self.app.proc_container.new(_("Generating CNC Code")):
if app_obj.new_object("cncjob", outname, job_init_single_geometry) != 'fail':
if app_obj.new_object("cncjob", outname, job_init_single_geometry, plot=plot) != 'fail':
app_obj.inform.emit('[success] %s: %s' %
(_("CNCjob created")), outname)
app_obj.progress.emit(100)
@ -4892,22 +4900,23 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
else:
if self.solid_geometry:
self.app.new_object("cncjob", outname, job_init_single_geometry)
self.app.new_object("cncjob", outname, job_init_single_geometry, plot=plot)
else:
self.app.new_object("cncjob", outname, job_init_multi_geometry)
self.app.new_object("cncjob", outname, job_init_multi_geometry, plot=plot)
def generatecncjob(
self, outname=None,
tooldia=None, offset=None,
dia=None, offset=None,
z_cut=None, z_move=None,
feedrate=None, feedrate_z=None, feedrate_rapid=None,
spindlespeed=None, dwell=None, dwelltime=None,
multidepth=None, depthperpass=None,
toolchange=None, toolchangez=None, toolchangexy=None,
extracut=None, startz=None, endz=None,
ppname_g=None,
pp=None,
segx=None, segy=None,
use_thread=True):
use_thread=True,
plot=True):
"""
Only used for TCL Command.
Creates a CNCJob out of this Geometry object. The actual
@ -4919,14 +4928,14 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
:param feedrate: Feed rate while cutting on X - Y plane
:param feedrate_z: Feed rate while cutting on Z plane
:param feedrate_rapid: Feed rate while moving with rapids
:param tooldia: Tool diameter
:param dia: Tool diameter
:param outname: Name of the new object
:param spindlespeed: Spindle speed (RPM)
:param ppname_g Name of the postprocessor
:param pp Name of the postprocessor
:return: None
"""
tooldia = tooldia if tooldia else float(self.options["cnctooldia"])
tooldia = dia if dia else float(self.options["cnctooldia"])
outname = outname if outname is not None else self.options["name"]
z_cut = z_cut if z_cut is not None else float(self.options["cutz"])
@ -4957,7 +4966,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
dwell = dwell if dwell else self.options["dwell"]
dwelltime = dwelltime if dwelltime else float(self.options["dwelltime"])
ppname_g = ppname_g if ppname_g else self.options["ppname_g"]
ppname_g = pp if pp else self.options["ppname_g"]
# Object initialization function for app.new_object()
# RUNNING ON SEPARATE THREAD!
@ -5034,7 +5043,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
# To be run in separate thread
def job_thread(app_obj):
with self.app.proc_container.new(_("Generating CNC Code")):
app_obj.new_object("cncjob", outname, job_init)
app_obj.new_object("cncjob", outname, job_init, plot=plot)
app_obj.inform.emit('[success] %s: %s' %
(_("CNCjob created")), outname)
app_obj.progress.emit(100)
@ -5044,7 +5053,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
# Send to worker
self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
else:
self.app.new_object("cncjob", outname, job_init)
self.app.new_object("cncjob", outname, job_init, plot=plot)
# def on_plot_cb_click(self, *args): # TODO: args not needed
# if self.muted_ui:
@ -5833,11 +5842,12 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
preamble = str(self.ui.prepend_text.get_value())
postamble = str(self.ui.append_text.get_value())
gc = self.export_gcode(preamble=preamble, postamble=postamble, to_file=True)
if gc == 'fail':
gco = self.export_gcode(preamble=preamble, postamble=postamble, to_file=True)
if gco == 'fail':
return
else:
self.app.gcode_edited = gc
self.app.gcode_edited = gco
self.app.init_code_editor(name=_("Code Editor"))
self.app.ui.buttonOpen.clicked.connect(self.app.handleOpen)

View File

@ -320,7 +320,7 @@ class ObjectCollection(QtCore.QAbstractItemModel):
self.app.ui.menuprojectgeneratecnc.setVisible(False)
if type(obj) != FlatCAMGeometry and type(obj) != FlatCAMExcellon and type(obj) != FlatCAMGerber:
self.app.ui.menuprojectedit.setVisible(False)
if type(obj) != FlatCAMGerber and type(obj) != FlatCAMExcellon:
if type(obj) != FlatCAMGerber and type(obj) != FlatCAMExcellon and type(obj) != FlatCAMCNCjob:
self.app.ui.menuprojectviewsource.setVisible(False)
else:
self.app.ui.menuprojectgeneratecnc.setVisible(False)

View File

@ -9,6 +9,18 @@ CAD program, and create G-Code for Isolation routing.
=================================================
16.09.2019
- modified the TclCommand New so it will no longer close all tabs when called (it closed the Code Editor tab which may have been holding the code that run)
- fixed the App.on_view_source() method for CNCJob objects: the Gcode will now contain the Prepend and Append code from the Edit -> Preferences -> CNCJob -> CNCJob Options
- added a new parameter named 'muted' for the TclCommands: cncjob, drillcncjob and write_gcode. Setting it as -muted 1 will disable the error reporting in TCL Shell
- some GUI optimizations
- more GUI optimizations related to being part of the Advanced category or not
- added possibility to change the positive SVG exported file color in Tool Film
- fixed some issues recently introduced in the TclCommands CNCJob, DrillCNCJob and write_gcode; changed some parameters names
- fixed issue in the Laser postprocessor where the laser was turned on as soon as the GCode started creating an unwanted cut up until the job start
- added new links in Menu -> Help (Excellon, Gerber specifications and a Report Bug)
15.09.2019
- refactored FlatCAMGeometry.mtool_gen_cncjob() method
@ -19,6 +31,18 @@ CAD program, and create G-Code for Isolation routing.
- finished updating the TclCommand cncjob to work for multi-geo Geometry objects with the parameters from the args
- fixed the TclCommand cncjob to use the -outname parameter
- added some more keywords in the data_model for auto-completer
- fixed isolate TclCommand to use correctly the -outname parameter
- added possibility to see the GCode when right clicking on the Project tab on a CNCJob object and then clicking View Source
- added a new TclCommand named PlotObjects which will plot a list of FlatCAM objects
- made that after opening an object in FlatCAM it is not automatically plotted. If the user wants to plot it can use the TclCommands PlotAll or PlotObjects
- modified the TclCommands so that open files do not plot the opened files automatically
- made all TclCommands not to be plotted automatically
- made sure that all TclCommands are not threaded
- added new TclCommands: NewExcellon, NewGerber
- fixed the TclCommand open_project
- added the outname parameter (and established an default name when outname not used) for the AlignDrillGrid and AlignDrill TclCommands
- fixed Scripts repeating multiple time when the Code Editor is used. This repetition was correlated with multiple openings of the Code Editor window (especially after an error)
- added the autocomplete keywords that can be changed to the defaults dictionary
14.09.2019

View File

@ -5685,10 +5685,11 @@ class CNCjob(Geometry):
must_visit.remove(nearest)
return path
def generate_from_excellon_by_tool(self, exobj, tools="all", drillz = 3.0,
toolchange=False, toolchangez=0.1, toolchangexy='',
endz=2.0, startz=None,
excellon_optimization_type='B'):
def generate_from_excellon_by_tool(
self, exobj, tools="all", drillz = 3.0,
toolchange=False, toolchangez=0.1, toolchangexy='',
endz=2.0, startz=None,
excellon_optimization_type='B'):
"""
Creates gcode for this object from an Excellon object
for the specified tools.
@ -6482,11 +6483,18 @@ class CNCjob(Geometry):
# self.gcode += self.doformat(p.toolchange_code)
self.gcode += self.doformat(p.toolchange_code)
self.gcode += self.doformat(p.spindle_code) # Spindle start
if 'laser' not in self.pp_geometry_name:
self.gcode += self.doformat(p.spindle_code) # Spindle start
else:
# for laser this will disable the laser
self.gcode += self.doformat(p.lift_code, x=self.oldx, y=self.oldy) # Move (up) to travel height
if self.dwell is True:
self.gcode += self.doformat(p.dwell_code) # Dwell time
else:
self.gcode += self.doformat(p.spindle_code) # Spindle start
if 'laser' not in self.pp_geometry_name:
self.gcode += self.doformat(p.spindle_code) # Spindle start
if self.dwell is True:
self.gcode += self.doformat(p.dwell_code) # Dwell time
@ -6589,15 +6597,16 @@ class CNCjob(Geometry):
)
return self.gcode
def generate_from_geometry_2(self, geometry, append=True,
tooldia=None, offset=0.0, tolerance=0,
z_cut=1.0, z_move=2.0,
feedrate=2.0, feedrate_z=2.0, feedrate_rapid=30,
spindlespeed=None, spindledir='CW', dwell=False, dwelltime=1.0,
multidepth=False, depthpercut=None,
toolchange=False, toolchangez=1.0, toolchangexy="0.0, 0.0",
extracut=False, startz=None, endz=2.0,
pp_geometry_name=None, tool_no=1):
def generate_from_geometry_2(
self, geometry, append=True,
tooldia=None, offset=0.0, tolerance=0,
z_cut=1.0, z_move=2.0,
feedrate=2.0, feedrate_z=2.0, feedrate_rapid=30,
spindlespeed=None, spindledir='CW', dwell=False, dwelltime=1.0,
multidepth=False, depthpercut=None,
toolchange=False, toolchangez=1.0, toolchangexy="0.0, 0.0",
extracut=False, startz=None, endz=2.0,
pp_geometry_name=None, tool_no=1):
"""
Second algorithm to generate from Geometry.
@ -6825,13 +6834,18 @@ class CNCjob(Geometry):
# self.gcode += self.doformat(p.toolchange_code)
self.gcode += self.doformat(p.toolchange_code)
self.gcode += self.doformat(p.spindle_code) # Spindle start
if 'laser' not in self.pp_geometry_name:
self.gcode += self.doformat(p.spindle_code) # Spindle start
else:
# for laser this will disable the laser
self.gcode += self.doformat(p.lift_code, x=self.oldx, y=self.oldy) # Move (up) to travel height
if self.dwell is True:
self.gcode += self.doformat(p.dwell_code) # Dwell time
else:
self.gcode += self.doformat(p.spindle_code) # Spindle start
if 'laser' not in self.pp_geometry_name:
self.gcode += self.doformat(p.spindle_code) # Spindle start
if self.dwell is True:
self.gcode += self.doformat(p.dwell_code) # Dwell time
@ -7247,7 +7261,7 @@ class CNCjob(Geometry):
match_lsr_pos = re.search(r"^(M0[3|5])", gline)
if match_lsr_pos:
if match_lsr_pos.group(1) == 'M05':
if 'M05' in match_lsr_pos.group(1):
# the value does not matter, only that it is positive so the gcode_parse() know it is > 0,
# therefore the move is of kind T (travel)
command['Z'] = 1
@ -7316,7 +7330,7 @@ class CNCjob(Geometry):
pass
elif 'hpgl' in self.pp_excellon_name or 'hpgl' in self.pp_geometry_name:
pass
elif 'grbl_laser' in self.pp_excellon_name or 'grbl_laser' in self.pp_geometry_name:
elif 'laser' in self.pp_excellon_name or 'laser' in self.pp_geometry_name:
pass
elif ('X' in gobj or 'Y' in gobj) and gobj['Z'] != current['Z']:
if self.pp_geometry_name == 'line_xyz' or self.pp_excellon_name == 'line_xyz':

View File

@ -400,6 +400,15 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
self.menuhelp_manual = self.menuhelp.addAction(QtGui.QIcon('share/globe16.png'), _('Online Help\tF1'))
self.menuhelp_home = self.menuhelp.addAction(QtGui.QIcon('share/home16.png'), _('FlatCAM.org'))
self.menuhelp.addSeparator()
self.menuhelp_report_bug = self.menuhelp.addAction(QtGui.QIcon('share/bug16.png'), _('Report a bug'))
self.menuhelp.addSeparator()
self.menuhelp_exc_spec = self.menuhelp.addAction(QtGui.QIcon('share/pdf_link16.png'),
_('Excellon Specification'))
self.menuhelp_gerber_spec = self.menuhelp.addAction(QtGui.QIcon('share/pdf_link16.png'),
_('Gerber Specification'))
self.menuhelp.addSeparator()
self.menuhelp_shortcut_list = self.menuhelp.addAction(QtGui.QIcon('share/shortcuts24.png'),
_('Shortcuts List\tF3'))
self.menuhelp_videohelp = self.menuhelp.addAction(QtGui.QIcon('share/youtube32.png'), _('YouTube Channel\tF4')
@ -2044,7 +2053,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
def eventFilter(self, obj, event):
# filter the ToolTips display based on a Preferences setting
if self.general_defaults_form.general_app_group.toggle_tooltips_cb.get_value() is False:
if self.general_defaults_form.general_gui_set_group.toggle_tooltips_cb.get_value() is False:
if event.type() == QtCore.QEvent.ToolTip:
return True
else:
@ -4026,6 +4035,7 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
)
self.selection_cb = FCCheckBox()
# Notebook Font Size
self.notebook_font_size_label = QtWidgets.QLabel('%s:' % _('NB Font Size'))
self.notebook_font_size_label.setToolTip(
_("This sets the font size for the elements found in the Notebook.\n"
@ -4074,6 +4084,56 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
else:
self.splash_cb.set_value(False)
# Shell StartUp CB
self.shell_startup_label = QtWidgets.QLabel('%s:' % _('Shell at StartUp'))
self.shell_startup_label.setToolTip(
_("Check this box if you want the shell to\n"
"start automatically at startup.")
)
self.shell_startup_cb = FCCheckBox(label='')
self.shell_startup_cb.setToolTip(
_("Check this box if you want the shell to\n"
"start automatically at startup.")
)
# Project at StartUp CB
self.project_startup_label = QtWidgets.QLabel('%s:' % _('Project at StartUp'))
self.project_startup_label.setToolTip(
_("Check this box if you want the project/selected/tool tab area to\n"
"to be shown automatically at startup.")
)
self.project_startup_cb = FCCheckBox(label='')
self.project_startup_cb.setToolTip(
_("Check this box if you want the project/selected/tool tab area to\n"
"to be shown automatically at startup.")
)
# Project autohide CB
self.project_autohide_label = QtWidgets.QLabel('%s:' % _('Project AutoHide'))
self.project_autohide_label.setToolTip(
_("Check this box if you want the project/selected/tool tab area to\n"
"hide automatically when there are no objects loaded and\n"
"to show whenever a new object is created.")
)
self.project_autohide_cb = FCCheckBox(label='')
self.project_autohide_cb.setToolTip(
_("Check this box if you want the project/selected/tool tab area to\n"
"hide automatically when there are no objects loaded and\n"
"to show whenever a new object is created.")
)
# Enable/Disable ToolTips globally
self.toggle_tooltips_label = QtWidgets.QLabel('<b>%s:</b>' % _('Enable ToolTips'))
self.toggle_tooltips_label.setToolTip(
_("Check this box if you want to have toolTips displayed\n"
"when hovering with mouse over items throughout the App.")
)
self.toggle_tooltips_cb = FCCheckBox(label='')
self.toggle_tooltips_cb.setToolTip(
_("Check this box if you want to have toolTips displayed\n"
"when hovering with mouse over items throughout the App.")
)
# Add (label - input field) pair to the QFormLayout
self.form_box.addRow(self.spacelabel, self.spacelabel)
@ -4088,11 +4148,27 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
self.form_box.addRow(self.axis_font_size_label, self.axis_font_size_spinner)
self.form_box.addRow(QtWidgets.QLabel(''))
self.form_box.addRow(self.splash_label, self.splash_cb)
self.form_box.addRow(self.shell_startup_label, self.shell_startup_cb)
self.form_box.addRow(self.project_startup_label, self.project_startup_cb)
self.form_box.addRow(self.project_autohide_label, self.project_autohide_cb)
self.form_box.addRow(QtWidgets.QLabel(''))
self.form_box.addRow(self.toggle_tooltips_label, self.toggle_tooltips_cb)
# Add the QFormLayout that holds the Application general defaults
# to the main layout of this TAB
self.layout.addLayout(self.form_box)
# Delete confirmation
self.delete_conf_cb = FCCheckBox(_('Delete object confirmation'))
self.delete_conf_cb.setToolTip(
_("When checked the application will ask for user confirmation\n"
"whenever the Delete object(s) event is triggered, either by\n"
"menu shortcut or key shortcut.")
)
self.layout.addWidget(self.delete_conf_cb)
self.layout.addStretch()
def handle_style(self, style):
# set current style
settings = QSettings("Open Source", "FlatCAM")
@ -4141,7 +4217,7 @@ class GeneralAppPrefGroupUI(OptionsGroupUI):
self.form_box = QtWidgets.QFormLayout()
# Units for FlatCAM
self.unitslabel = QtWidgets.QLabel('<b>%s:</b>' % _('Units'))
self.unitslabel = QtWidgets.QLabel('<span style="color:red;"><b>%s:</b></span>' % _('Units'))
self.unitslabel.setToolTip(_("The default value for FlatCAM units.\n"
"Whatever is selected here is set every time\n"
"FLatCAM is started."))
@ -4180,18 +4256,6 @@ class GeneralAppPrefGroupUI(OptionsGroupUI):
"security features. In this case the language will be\n"
"applied at the next app start."))
# Shell StartUp CB
self.shell_startup_label = QtWidgets.QLabel('%s:' % _('Shell at StartUp'))
self.shell_startup_label.setToolTip(
_("Check this box if you want the shell to\n"
"start automatically at startup.")
)
self.shell_startup_cb = FCCheckBox(label='')
self.shell_startup_cb.setToolTip(
_("Check this box if you want the shell to\n"
"start automatically at startup.")
)
# Version Check CB
self.version_check_label = QtWidgets.QLabel('%s:' % _('Version Check'))
self.version_check_label.setToolTip(
@ -4232,43 +4296,7 @@ class GeneralAppPrefGroupUI(OptionsGroupUI):
self.mselect_radio = RadioSet([{'label': _('CTRL'), 'value': 'Control'},
{'label': _('SHIFT'), 'value': 'Shift'}])
# Project at StartUp CB
self.project_startup_label = QtWidgets.QLabel('%s:' % _('Project at StartUp'))
self.project_startup_label.setToolTip(
_("Check this box if you want the project/selected/tool tab area to\n"
"to be shown automatically at startup.")
)
self.project_startup_cb = FCCheckBox(label='')
self.project_startup_cb.setToolTip(
_("Check this box if you want the project/selected/tool tab area to\n"
"to be shown automatically at startup.")
)
# Project autohide CB
self.project_autohide_label = QtWidgets.QLabel('%s:' % _('Project AutoHide'))
self.project_autohide_label.setToolTip(
_("Check this box if you want the project/selected/tool tab area to\n"
"hide automatically when there are no objects loaded and\n"
"to show whenever a new object is created.")
)
self.project_autohide_cb = FCCheckBox(label='')
self.project_autohide_cb.setToolTip(
_("Check this box if you want the project/selected/tool tab area to\n"
"hide automatically when there are no objects loaded and\n"
"to show whenever a new object is created.")
)
# Enable/Disable ToolTips globally
self.toggle_tooltips_label = QtWidgets.QLabel('<b>%s:</b>' % _('Enable ToolTips'))
self.toggle_tooltips_label.setToolTip(
_("Check this box if you want to have toolTips displayed\n"
"when hovering with mouse over items throughout the App.")
)
self.toggle_tooltips_cb = FCCheckBox(label='')
self.toggle_tooltips_cb.setToolTip(
_("Check this box if you want to have toolTips displayed\n"
"when hovering with mouse over items throughout the App.")
)
# Worker Numbers
self.worker_number_label = QtWidgets.QLabel('%s:' % _('Workers number'))
self.worker_number_label.setToolTip(
_("The number of Qthreads made available to the App.\n"
@ -4321,15 +4349,11 @@ class GeneralAppPrefGroupUI(OptionsGroupUI):
self.form_box.addRow(self.languagespace, self.language_apply_btn)
self.form_box.addRow(self.spacelabel, self.spacelabel)
self.form_box.addRow(self.shell_startup_label, self.shell_startup_cb)
self.form_box.addRow(self.version_check_label, self.version_check_cb)
self.form_box.addRow(self.send_stats_label, self.send_stats_cb)
self.form_box.addRow(self.panbuttonlabel, self.pan_button_radio)
self.form_box.addRow(self.mselectlabel, self.mselect_radio)
self.form_box.addRow(self.project_startup_label, self.project_startup_cb)
self.form_box.addRow(self.project_autohide_label, self.project_autohide_cb)
self.form_box.addRow(self.toggle_tooltips_label, self.toggle_tooltips_cb)
self.form_box.addRow(self.worker_number_label, self.worker_number_sb)
self.form_box.addRow(tol_label, self.tol_entry)
@ -4350,15 +4374,6 @@ class GeneralAppPrefGroupUI(OptionsGroupUI):
# self.advanced_cb.setLayoutDirection(QtCore.Qt.RightToLeft)
self.layout.addWidget(self.open_style_cb)
# Delete confirmation
self.delete_conf_cb = FCCheckBox(_('Delete object confirmation'))
self.delete_conf_cb.setToolTip(
_("When checked the application will ask for user confirmation\n"
"whenever the Delete object(s) event is triggered, either by\n"
"menu shortcut or key shortcut.")
)
self.layout.addWidget(self.delete_conf_cb)
# Save compressed project CB
self.save_type_cb = FCCheckBox(_('Save Compressed Project'))
self.save_type_cb.setToolTip(
@ -4442,40 +4457,6 @@ class GerberGenPrefGroupUI(OptionsGroupUI):
grid0.addWidget(self.circle_steps_label, 1, 0)
grid0.addWidget(self.circle_steps_entry, 1, 1)
# Milling Type
buffering_label = QtWidgets.QLabel('%s:' % _('Buffering'))
buffering_label.setToolTip(
_("Buffering type:\n"
"- None --> best performance, fast file loading but no so good display\n"
"- Full --> slow file loading but good visuals. This is the default.\n"
"<<WARNING>>: Don't change this unless you know what you are doing !!!")
)
self.buffering_radio = RadioSet([{'label': _('None'), 'value': 'no'},
{'label': _('Full'), 'value': 'full'}])
grid0.addWidget(buffering_label, 2, 0)
grid0.addWidget(self.buffering_radio, 2, 1)
# Simplification
self.simplify_cb = FCCheckBox(label=_('Simplify'))
self.simplify_cb.setToolTip(_("When checked all the Gerber polygons will be\n"
"loaded with simplification having a set tolerance."))
grid0.addWidget(self.simplify_cb, 3, 0)
# Simplification tolerance
self.simplification_tol_label = QtWidgets.QLabel(_('Tolerance'))
self.simplification_tol_label.setToolTip(_("Tolerance for poligon simplification."))
self.simplification_tol_spinner = FCDoubleSpinner()
self.simplification_tol_spinner.set_precision(5)
self.simplification_tol_spinner.setWrapping(True)
self.simplification_tol_spinner.setRange(0.00000, 0.01000)
self.simplification_tol_spinner.setSingleStep(0.0001)
grid0.addWidget(self.simplification_tol_label, 4, 0)
grid0.addWidget(self.simplification_tol_spinner, 4, 1)
self.ois_simplif = OptionalInputSection(self.simplify_cb,
[self.simplification_tol_label, self.simplification_tol_spinner],
logic=True)
self.layout.addStretch()
@ -4525,7 +4506,11 @@ class GerberOptPrefGroupUI(OptionsGroupUI):
"A value here of 0.25 means an overlap of 25%% from the tool diameter found above.")
)
grid0.addWidget(overlabel, 2, 0)
self.iso_overlap_entry = FloatEntry()
self.iso_overlap_entry = FCDoubleSpinner()
self.iso_overlap_entry.set_precision(3)
self.iso_overlap_entry.setWrapping(True)
self.iso_overlap_entry.setRange(0.000, 0.999)
self.iso_overlap_entry.setSingleStep(0.1)
grid0.addWidget(self.iso_overlap_entry, 2, 1)
# Milling Type
@ -4615,7 +4600,7 @@ class GerberAdvOptPrefGroupUI(OptionsGroupUI):
self.setTitle(str(_("Gerber Adv. Options")))
# ## Advanced Gerber Parameters
self.adv_param_label = QtWidgets.QLabel("<b>%s:</b>" % _("Advanced Param."))
self.adv_param_label = QtWidgets.QLabel('<b>%s:</b>' % _('Advanced Options'))
self.adv_param_label.setToolTip(
_("A list of Gerber advanced parameters.\n"
"Those parameters are available only for\n"
@ -4633,7 +4618,7 @@ class GerberAdvOptPrefGroupUI(OptionsGroupUI):
"This means that it will cut through\n"
"the middle of the trace.")
)
grid0.addWidget(self.follow_cb, 0, 0)
grid0.addWidget(self.follow_cb, 0, 0, 1, 2)
# Aperture Table Visibility CB
self.aperture_table_visibility_cb = FCCheckBox(label=_('Table Show/Hide'))
@ -4643,7 +4628,42 @@ class GerberAdvOptPrefGroupUI(OptionsGroupUI):
"that are drawn on canvas.")
)
grid0.addWidget(self.aperture_table_visibility_cb, 1, 0)
grid0.addWidget(self.aperture_table_visibility_cb, 1, 0, 1, 2)
# Buffering Type
buffering_label = QtWidgets.QLabel('%s:' % _('Buffering'))
buffering_label.setToolTip(
_("Buffering type:\n"
"- None --> best performance, fast file loading but no so good display\n"
"- Full --> slow file loading but good visuals. This is the default.\n"
"<<WARNING>>: Don't change this unless you know what you are doing !!!")
)
self.buffering_radio = RadioSet([{'label': _('None'), 'value': 'no'},
{'label': _('Full'), 'value': 'full'}])
grid0.addWidget(buffering_label, 2, 0)
grid0.addWidget(self.buffering_radio, 2, 1)
# Simplification
self.simplify_cb = FCCheckBox(label=_('Simplify'))
self.simplify_cb.setToolTip(_("When checked all the Gerber polygons will be\n"
"loaded with simplification having a set tolerance."))
grid0.addWidget(self.simplify_cb, 3, 0, 1, 2)
# Simplification tolerance
self.simplification_tol_label = QtWidgets.QLabel(_('Tolerance'))
self.simplification_tol_label.setToolTip(_("Tolerance for poligon simplification."))
self.simplification_tol_spinner = FCDoubleSpinner()
self.simplification_tol_spinner.set_precision(5)
self.simplification_tol_spinner.setWrapping(True)
self.simplification_tol_spinner.setRange(0.00000, 0.01000)
self.simplification_tol_spinner.setSingleStep(0.0001)
grid0.addWidget(self.simplification_tol_label, 4, 0)
grid0.addWidget(self.simplification_tol_spinner, 4, 1)
self.ois_simplif = OptionalInputSection(self.simplify_cb,
[self.simplification_tol_label, self.simplification_tol_spinner],
logic=True)
# Scale Aperture Factor
# self.scale_aperture_label = QtWidgets.QLabel(_('Ap. Scale Factor:'))
@ -5141,7 +5161,7 @@ class ExcellonGenPrefGroupUI(OptionsGroupUI):
self.update_excellon_cb.setToolTip(
"If checked, the Excellon Export settings will be updated with the ones above."
)
grid2.addWidget(self.update_excellon_cb, 2, 0)
grid2.addWidget(self.update_excellon_cb, 2, 0, 1, 2)
grid2.addWidget(QtWidgets.QLabel(""), 3, 0)
@ -5161,8 +5181,10 @@ class ExcellonGenPrefGroupUI(OptionsGroupUI):
)
grid2.addWidget(self.excellon_optimization_label, 5, 0)
self.excellon_optimization_radio = RadioSet([{'label': _('MH'), 'value': 'M'},
{'label': _('Basic'), 'value': 'B'}])
self.excellon_optimization_radio = RadioSet([{'label': _('MetaHeuristic'), 'value': 'M'},
{'label': _('Basic'), 'value': 'B'},
{'label': _('TSA'), 'value': 'T'}],
orientation='vertical', stretch=False)
self.excellon_optimization_radio.setToolTip(
_("This sets the optimization type for the Excellon drill path.\n"
"If MH is checked then Google OR-Tools algorithm with MetaHeuristic\n"
@ -5234,6 +5256,7 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI):
grid2 = QtWidgets.QGridLayout()
self.layout.addLayout(grid2)
# Cut Z
cutzlabel = QtWidgets.QLabel('%s:' % _('Cut Z'))
cutzlabel.setToolTip(
_("Drill depth (negative)\n"
@ -5243,6 +5266,7 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI):
self.cutz_entry = LengthEntry()
grid2.addWidget(self.cutz_entry, 0, 1)
# Travel Z
travelzlabel = QtWidgets.QLabel('%s:' % _('Travel Z'))
travelzlabel.setToolTip(
_("Tool height when travelling\n"
@ -5271,15 +5295,27 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI):
self.toolchangez_entry = LengthEntry()
grid2.addWidget(self.toolchangez_entry, 3, 1)
frlabel = QtWidgets.QLabel('%s:' % _('Feedrate (Plunge)'))
# End Move Z
endzlabel = QtWidgets.QLabel('%s:' % _('End move Z'))
endzlabel.setToolTip(
_("Height of the tool after\n"
"the last move at the end of the job.")
)
grid2.addWidget(endzlabel, 4, 0)
self.eendz_entry = LengthEntry()
grid2.addWidget(self.eendz_entry, 4, 1)
# Feedrate Z
frlabel = QtWidgets.QLabel('%s:' % _('Feedrate Z'))
frlabel.setToolTip(
_("Tool speed while drilling\n"
"(in units per minute).\n"
"So called 'Plunge' feedrate.\n"
"This is for linear move G01.")
)
grid2.addWidget(frlabel, 4, 0)
grid2.addWidget(frlabel, 5, 0)
self.feedrate_entry = LengthEntry()
grid2.addWidget(self.feedrate_entry, 4, 1)
grid2.addWidget(self.feedrate_entry, 5, 1)
# Spindle speed
spdlabel = QtWidgets.QLabel('%s:' % _('Spindle Speed'))
@ -5287,23 +5323,9 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI):
_("Speed of the spindle\n"
"in RPM (optional)")
)
grid2.addWidget(spdlabel, 5, 0)
grid2.addWidget(spdlabel, 6, 0)
self.spindlespeed_entry = IntEntry(allow_empty=True)
grid2.addWidget(self.spindlespeed_entry, 5, 1)
# Spindle direction
spindle_dir_label = QtWidgets.QLabel('%s:' % _('Spindle dir.'))
spindle_dir_label.setToolTip(
_("This sets the direction that the spindle is rotating.\n"
"It can be either:\n"
"- CW = clockwise or\n"
"- CCW = counter clockwise")
)
self.spindledir_radio = RadioSet([{'label': _('CW'), 'value': 'CW'},
{'label': _('CCW'), 'value': 'CCW'}])
grid2.addWidget(spindle_dir_label, 6, 0)
grid2.addWidget(self.spindledir_radio, 6, 1)
grid2.addWidget(self.spindlespeed_entry, 6, 1)
# Dwell
dwelllabel = QtWidgets.QLabel('%s:' % _('Dwell'))
@ -5317,6 +5339,7 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI):
)
self.dwell_cb = FCCheckBox()
self.dwelltime_entry = FCEntry()
grid2.addWidget(dwelllabel, 7, 0)
grid2.addWidget(self.dwell_cb, 7, 1)
grid2.addWidget(dwelltime, 8, 0)
@ -5358,7 +5381,7 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI):
self.mill_hole_label.setToolTip(
_("Create Geometry for milling holes.")
)
grid2.addWidget(excellon_gcode_type_label, 11, 0, 1, 2)
grid2.addWidget(self.mill_hole_label, 11, 0, 1, 2)
tdlabel = QtWidgets.QLabel('%s:' % _('Drill Tool dia'))
tdlabel.setToolTip(
@ -5400,12 +5423,13 @@ class ExcellonAdvOptPrefGroupUI(OptionsGroupUI):
# ## ADVANCED OPTIONS ###
# #######################
self.cncjob_label = QtWidgets.QLabel('<b>%s:</b>' % _('Advanced Options'))
self.cncjob_label.setToolTip(
_("Parameters used to create a CNC Job object\n"
"for this drill object that are shown when App Level is Advanced.")
self.exc_label = QtWidgets.QLabel('<b>%s:</b>' % _('Advanced Options'))
self.exc_label.setToolTip(
_("A list of Excellon advanced parameters.\n"
"Those parameters are available only for\n"
"Advanced App. Level.")
)
self.layout.addWidget(self.cncjob_label)
self.layout.addWidget(self.exc_label)
grid1 = QtWidgets.QGridLayout()
self.layout.addLayout(grid1)
@ -5436,15 +5460,7 @@ class ExcellonAdvOptPrefGroupUI(OptionsGroupUI):
self.estartz_entry = FloatEntry()
grid1.addWidget(self.estartz_entry, 2, 1)
endzlabel = QtWidgets.QLabel('%s:' % _('End move Z'))
endzlabel.setToolTip(
_("Height of the tool after\n"
"the last move at the end of the job.")
)
grid1.addWidget(endzlabel, 3, 0)
self.eendz_entry = LengthEntry()
grid1.addWidget(self.eendz_entry, 3, 1)
# Feedrate Rapids
fr_rapid_label = QtWidgets.QLabel('%s:' % _('Feedrate Rapids'))
fr_rapid_label.setToolTip(
_("Tool speed while drilling\n"
@ -5453,9 +5469,9 @@ class ExcellonAdvOptPrefGroupUI(OptionsGroupUI):
"It is useful only for Marlin,\n"
"ignore for any other cases.")
)
grid1.addWidget(fr_rapid_label, 4, 0)
grid1.addWidget(fr_rapid_label, 3, 0)
self.feedrate_rapid_entry = LengthEntry()
grid1.addWidget(self.feedrate_rapid_entry, 4, 1)
grid1.addWidget(self.feedrate_rapid_entry, 3, 1)
# Probe depth
self.pdepth_label = QtWidgets.QLabel('%s:' % _("Probe Z depth"))
@ -5463,18 +5479,32 @@ class ExcellonAdvOptPrefGroupUI(OptionsGroupUI):
_("The maximum depth that the probe is allowed\n"
"to probe. Negative value, in current units.")
)
grid1.addWidget(self.pdepth_label, 5, 0)
grid1.addWidget(self.pdepth_label, 4, 0)
self.pdepth_entry = FCEntry()
grid1.addWidget(self.pdepth_entry, 5, 1)
grid1.addWidget(self.pdepth_entry, 4, 1)
# Probe feedrate
self.feedrate_probe_label = QtWidgets.QLabel('%s:' % _("Feedrate Probe"))
self.feedrate_probe_label.setToolTip(
_("The feedrate used while the probe is probing.")
)
grid1.addWidget(self.feedrate_probe_label, 6, 0)
grid1.addWidget(self.feedrate_probe_label, 5, 0)
self.feedrate_probe_entry = FCEntry()
grid1.addWidget(self.feedrate_probe_entry, 6, 1)
grid1.addWidget(self.feedrate_probe_entry, 5, 1)
# Spindle direction
spindle_dir_label = QtWidgets.QLabel('%s:' % _('Spindle dir.'))
spindle_dir_label.setToolTip(
_("This sets the direction that the spindle is rotating.\n"
"It can be either:\n"
"- CW = clockwise or\n"
"- CCW = counter clockwise")
)
self.spindledir_radio = RadioSet([{'label': _('CW'), 'value': 'CW'},
{'label': _('CCW'), 'value': 'CCW'}])
grid1.addWidget(spindle_dir_label, 6, 0)
grid1.addWidget(self.spindledir_radio, 6, 1)
fplungelabel = QtWidgets.QLabel('%s:' % _('Fast Plunge'))
fplungelabel.setToolTip(
@ -6048,15 +6078,25 @@ class GeometryOptPrefGroupUI(OptionsGroupUI):
self.toolchangez_entry = LengthEntry()
grid1.addWidget(self.toolchangez_entry, 5, 1)
# End move Z
endzlabel = QtWidgets.QLabel('%s:' % _('End move Z'))
endzlabel.setToolTip(
_("Height of the tool after\n"
"the last move at the end of the job.")
)
grid1.addWidget(endzlabel, 6, 0)
self.gendz_entry = LengthEntry()
grid1.addWidget(self.gendz_entry, 6, 1)
# Feedrate X-Y
frlabel = QtWidgets.QLabel('%s:' % _('Feed Rate X-Y'))
frlabel.setToolTip(
_("Cutting speed in the XY\n"
"plane in units per minute")
)
grid1.addWidget(frlabel, 6, 0)
grid1.addWidget(frlabel, 7, 0)
self.cncfeedrate_entry = LengthEntry()
grid1.addWidget(self.cncfeedrate_entry, 6, 1)
grid1.addWidget(self.cncfeedrate_entry, 7, 1)
# Feedrate Z (Plunge)
frz_label = QtWidgets.QLabel('%s:' % _('Feed Rate Z'))
@ -6065,9 +6105,9 @@ class GeometryOptPrefGroupUI(OptionsGroupUI):
"plane in units per minute.\n"
"It is called also Plunge.")
)
grid1.addWidget(frz_label, 7, 0)
grid1.addWidget(frz_label, 8, 0)
self.cncplunge_entry = LengthEntry()
grid1.addWidget(self.cncplunge_entry, 7, 1)
grid1.addWidget(self.cncplunge_entry, 8, 1)
# Spindle Speed
spdlabel = QtWidgets.QLabel('%s:' % _('Spindle speed'))
@ -6078,23 +6118,9 @@ class GeometryOptPrefGroupUI(OptionsGroupUI):
"this value is the power of laser."
)
)
grid1.addWidget(spdlabel, 8, 0)
grid1.addWidget(spdlabel, 9, 0)
self.cncspindlespeed_entry = IntEntry(allow_empty=True)
grid1.addWidget(self.cncspindlespeed_entry, 8, 1)
# Spindle direction
spindle_dir_label = QtWidgets.QLabel('%s:' % _('Spindle dir.'))
spindle_dir_label.setToolTip(
_("This sets the direction that the spindle is rotating.\n"
"It can be either:\n"
"- CW = clockwise or\n"
"- CCW = counter clockwise")
)
self.spindledir_radio = RadioSet([{'label': _('CW'), 'value': 'CW'},
{'label': _('CCW'), 'value': 'CCW'}])
grid1.addWidget(spindle_dir_label, 9, 0)
grid1.addWidget(self.spindledir_radio, 9, 1)
grid1.addWidget(self.cncspindlespeed_entry, 9, 1)
# Dwell
self.dwell_cb = FCCheckBox(label='%s:' % _('Dwell'))
@ -6137,12 +6163,13 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
# ------------------------------
# ## Advanced Options
# ------------------------------
self.cncjob_label = QtWidgets.QLabel('<b>%s:</b>' % _('Advanced Options'))
self.cncjob_label.setToolTip(
_("Parameters to create a CNC Job object\n"
"tracing the contours of a Geometry object.")
self.geo_label = QtWidgets.QLabel('<b>%s:</b>' % _('Advanced Options'))
self.geo_label.setToolTip(
_("A list of Geometry advanced parameters.\n"
"Those parameters are available only for\n"
"Advanced App. Level.")
)
self.layout.addWidget(self.cncjob_label)
self.layout.addWidget(self.geo_label)
grid1 = QtWidgets.QGridLayout()
self.layout.addLayout(grid1)
@ -6166,16 +6193,6 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
self.gstartz_entry = FloatEntry()
grid1.addWidget(self.gstartz_entry, 2, 1)
# End move Z
endzlabel = QtWidgets.QLabel('%s:' % _('End move Z'))
endzlabel.setToolTip(
_("Height of the tool after\n"
"the last move at the end of the job.")
)
grid1.addWidget(endzlabel, 3, 0)
self.gendz_entry = LengthEntry()
grid1.addWidget(self.gendz_entry, 3, 1)
# Feedrate rapids
fr_rapid_label = QtWidgets.QLabel('%s:' % _('Feed Rate Rapids'))
fr_rapid_label.setToolTip(
@ -6218,6 +6235,20 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
self.feedrate_probe_entry = FCEntry()
grid1.addWidget(self.feedrate_probe_entry, 7, 1)
# Spindle direction
spindle_dir_label = QtWidgets.QLabel('%s:' % _('Spindle dir.'))
spindle_dir_label.setToolTip(
_("This sets the direction that the spindle is rotating.\n"
"It can be either:\n"
"- CW = clockwise or\n"
"- CCW = counter clockwise")
)
self.spindledir_radio = RadioSet([{'label': _('CW'), 'value': 'CW'},
{'label': _('CCW'), 'value': 'CCW'}])
grid1.addWidget(spindle_dir_label, 8, 0)
grid1.addWidget(self.spindledir_radio, 8, 1)
# Fast Move from Z Toolchange
fplungelabel = QtWidgets.QLabel('%s:' % _('Fast Plunge'))
fplungelabel.setToolTip(
@ -6227,8 +6258,8 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
"WARNING: the move is done at Toolchange X,Y coords.")
)
self.fplunge_cb = FCCheckBox()
grid1.addWidget(fplungelabel, 8, 0)
grid1.addWidget(self.fplunge_cb, 8, 1)
grid1.addWidget(fplungelabel, 9, 0)
grid1.addWidget(self.fplunge_cb, 9, 1)
# Size of trace segment on X axis
segx_label = QtWidgets.QLabel('%s:' % _("Seg. X size"))
@ -6237,9 +6268,9 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
"Useful for auto-leveling.\n"
"A value of 0 means no segmentation on the X axis.")
)
grid1.addWidget(segx_label, 9, 0)
grid1.addWidget(segx_label, 10, 0)
self.segx_entry = FCEntry()
grid1.addWidget(self.segx_entry, 9, 1)
grid1.addWidget(self.segx_entry, 10, 1)
# Size of trace segment on Y axis
segy_label = QtWidgets.QLabel('%s:' % _("Seg. Y size"))
@ -6248,9 +6279,9 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
"Useful for auto-leveling.\n"
"A value of 0 means no segmentation on the Y axis.")
)
grid1.addWidget(segy_label, 10, 0)
grid1.addWidget(segy_label, 11, 0)
self.segy_entry = FCEntry()
grid1.addWidget(self.segy_entry, 10, 1)
grid1.addWidget(self.segy_entry, 11, 1)
self.layout.addStretch()
@ -6344,37 +6375,6 @@ class CNCJobGenPrefGroupUI(OptionsGroupUI):
grid0.addWidget(self.annotation_cb, 2, 1)
grid0.addWidget(QtWidgets.QLabel(''), 2, 2)
# Annotation Font Size
self.annotation_fontsize_label = QtWidgets.QLabel('%s:' % _("Annotation Size"))
self.annotation_fontsize_label.setToolTip(
_("The font size of the annotation text. In pixels.")
)
grid0.addWidget(self.annotation_fontsize_label, 3, 0)
self.annotation_fontsize_sp = FCSpinner()
grid0.addWidget(self.annotation_fontsize_sp, 3, 1)
grid0.addWidget(QtWidgets.QLabel(''), 3, 2)
# Annotation Font Color
self.annotation_color_label = QtWidgets.QLabel('%s:' % _('Annotation Color'))
self.annotation_color_label.setToolTip(
_("Set the font color for the annotation texts.")
)
self.annotation_fontcolor_entry = FCEntry()
self.annotation_fontcolor_button = QtWidgets.QPushButton()
self.annotation_fontcolor_button.setFixedSize(15, 15)
self.form_box_child = QtWidgets.QHBoxLayout()
self.form_box_child.setContentsMargins(0, 0, 0, 0)
self.form_box_child.addWidget(self.annotation_fontcolor_entry)
self.form_box_child.addWidget(self.annotation_fontcolor_button, alignment=Qt.AlignRight)
self.form_box_child.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
color_widget = QtWidgets.QWidget()
color_widget.setLayout(self.form_box_child)
grid0.addWidget(self.annotation_color_label, 4, 0)
grid0.addWidget(color_widget, 4, 1)
grid0.addWidget(QtWidgets.QLabel(''), 4, 2)
# ###################################################################
# Number of circle steps for circular aperture linear approximation #
# ###################################################################
@ -6383,9 +6383,9 @@ class CNCJobGenPrefGroupUI(OptionsGroupUI):
_("The number of circle steps for <b>GCode</b> \n"
"circle and arc shapes linear approximation.")
)
grid0.addWidget(self.steps_per_circle_label, 5, 0)
grid0.addWidget(self.steps_per_circle_label, 3, 0)
self.steps_per_circle_entry = IntEntry()
grid0.addWidget(self.steps_per_circle_entry, 5, 1)
grid0.addWidget(self.steps_per_circle_entry, 3, 1)
# Tool dia for plot
tdlabel = QtWidgets.QLabel('%s:' % _('Travel dia'))
@ -6394,11 +6394,11 @@ class CNCJobGenPrefGroupUI(OptionsGroupUI):
"rendered in the plot.")
)
self.tooldia_entry = LengthEntry()
grid0.addWidget(tdlabel, 6, 0)
grid0.addWidget(self.tooldia_entry, 6, 1)
grid0.addWidget(tdlabel, 4, 0)
grid0.addWidget(self.tooldia_entry, 4, 1)
# add a space
grid0.addWidget(QtWidgets.QLabel(''), 7, 0)
grid0.addWidget(QtWidgets.QLabel(''), 5, 0)
# Number of decimals to use in GCODE coordinates
cdeclabel = QtWidgets.QLabel('%s:' % _('Coordinates decimals'))
@ -6407,8 +6407,8 @@ class CNCJobGenPrefGroupUI(OptionsGroupUI):
"the X, Y, Z coordinates in CNC code (GCODE, etc.)")
)
self.coords_dec_entry = IntEntry()
grid0.addWidget(cdeclabel, 8, 0)
grid0.addWidget(self.coords_dec_entry, 8, 1)
grid0.addWidget(cdeclabel, 6, 0)
grid0.addWidget(self.coords_dec_entry, 6, 1)
# Number of decimals to use in GCODE feedrate
frdeclabel = QtWidgets.QLabel('%s:' % _('Feedrate decimals'))
@ -6417,8 +6417,8 @@ class CNCJobGenPrefGroupUI(OptionsGroupUI):
"the Feedrate parameter in CNC code (GCODE, etc.)")
)
self.fr_dec_entry = IntEntry()
grid0.addWidget(frdeclabel, 9, 0)
grid0.addWidget(self.fr_dec_entry, 9, 1)
grid0.addWidget(frdeclabel, 7, 0)
grid0.addWidget(self.fr_dec_entry, 7, 1)
# The type of coordinates used in the Gcode: Absolute or Incremental
coords_type_label = QtWidgets.QLabel('%s:' % _('Coordinates type'))
@ -6432,8 +6432,8 @@ class CNCJobGenPrefGroupUI(OptionsGroupUI):
{"label": _("Absolute G90"), "value": "G90"},
{"label": _("Incremental G91"), "value": "G91"}
], orientation='vertical', stretch=False)
grid0.addWidget(coords_type_label, 10, 0)
grid0.addWidget(self.coords_type_radio, 10, 1)
grid0.addWidget(coords_type_label, 8, 0)
grid0.addWidget(self.coords_type_radio, 8, 1)
# hidden for the time being, until implemented
coords_type_label.hide()
@ -6570,6 +6570,42 @@ class CNCJobAdvOptPrefGroupUI(OptionsGroupUI):
# )
# hlay1.addWidget(self.tc_insert_buton)
grid0 = QtWidgets.QGridLayout()
self.layout.addLayout(grid0)
grid0.addWidget(QtWidgets.QLabel(''), 1, 0, 1, 2)
# Annotation Font Size
self.annotation_fontsize_label = QtWidgets.QLabel('%s:' % _("Annotation Size"))
self.annotation_fontsize_label.setToolTip(
_("The font size of the annotation text. In pixels.")
)
grid0.addWidget(self.annotation_fontsize_label, 2, 0)
self.annotation_fontsize_sp = FCSpinner()
grid0.addWidget(self.annotation_fontsize_sp, 2, 1)
grid0.addWidget(QtWidgets.QLabel(''), 2, 2)
# Annotation Font Color
self.annotation_color_label = QtWidgets.QLabel('%s:' % _('Annotation Color'))
self.annotation_color_label.setToolTip(
_("Set the font color for the annotation texts.")
)
self.annotation_fontcolor_entry = FCEntry()
self.annotation_fontcolor_button = QtWidgets.QPushButton()
self.annotation_fontcolor_button.setFixedSize(15, 15)
self.form_box_child = QtWidgets.QHBoxLayout()
self.form_box_child.setContentsMargins(0, 0, 0, 0)
self.form_box_child.addWidget(self.annotation_fontcolor_entry)
self.form_box_child.addWidget(self.annotation_fontcolor_button, alignment=Qt.AlignRight)
self.form_box_child.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
color_widget = QtWidgets.QWidget()
color_widget.setLayout(self.form_box_child)
grid0.addWidget(self.annotation_color_label, 3, 0)
grid0.addWidget(color_widget, 3, 1)
grid0.addWidget(QtWidgets.QLabel(''), 3, 2)
self.layout.addStretch()
@ -6705,8 +6741,12 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI):
"Higher values = slow processing and slow execution on CNC\n"
"due of too many paths.")
)
self.ncc_overlap_entry = FCDoubleSpinner()
self.ncc_overlap_entry.set_precision(3)
self.ncc_overlap_entry.setWrapping(True)
self.ncc_overlap_entry.setRange(0.000, 0.999)
self.ncc_overlap_entry.setSingleStep(0.1)
grid0.addWidget(nccoverlabel, 7, 0)
self.ncc_overlap_entry = FloatEntry()
grid0.addWidget(self.ncc_overlap_entry, 7, 1)
# Margin entry
@ -7050,8 +7090,12 @@ class ToolsPaintPrefGroupUI(OptionsGroupUI):
"Higher values = slow processing and slow execution on CNC\n"
"due of too many paths.")
)
self.paintoverlap_entry = FCDoubleSpinner()
self.paintoverlap_entry.set_precision(3)
self.paintoverlap_entry.setWrapping(True)
self.paintoverlap_entry.setRange(0.000, 0.999)
self.paintoverlap_entry.setSingleStep(0.1)
grid0.addWidget(ovlabel, 2, 0)
self.paintoverlap_entry = LengthEntry()
grid0.addWidget(self.paintoverlap_entry, 2, 1)
# Margin
@ -7167,6 +7211,26 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
grid0.addWidget(ftypelbl, 0, 0)
grid0.addWidget(self.film_type_radio, 0, 1)
# Film Color
self.film_color_label = QtWidgets.QLabel('%s:' % _('Film Color'))
self.film_color_label.setToolTip(
_("Set the film color when positive film is selected.")
)
self.film_color_entry = FCEntry()
self.film_color_button = QtWidgets.QPushButton()
self.film_color_button.setFixedSize(15, 15)
self.form_box_child = QtWidgets.QHBoxLayout()
self.form_box_child.setContentsMargins(0, 0, 0, 0)
self.form_box_child.addWidget(self.film_color_entry)
self.form_box_child.addWidget(self.film_color_button, alignment=Qt.AlignRight)
self.form_box_child.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
film_color_widget = QtWidgets.QWidget()
film_color_widget.setLayout(self.form_box_child)
grid0.addWidget(self.film_color_label, 1, 0)
grid0.addWidget(film_color_widget, 1, 1)
self.film_boundary_entry = FCEntry()
self.film_boundary_label = QtWidgets.QLabel('%s:' % _("Border"))
self.film_boundary_label.setToolTip(
@ -7179,8 +7243,8 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
"white color like the rest and which may confound with the\n"
"surroundings if not for this border.")
)
grid0.addWidget(self.film_boundary_label, 1, 0)
grid0.addWidget(self.film_boundary_entry, 1, 1)
grid0.addWidget(self.film_boundary_label, 2, 0)
grid0.addWidget(self.film_boundary_entry, 2, 1)
self.film_scale_entry = FCEntry()
self.film_scale_label = QtWidgets.QLabel('%s:' % _("Scale Stroke"))
@ -7189,8 +7253,8 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
"It means that the line that envelope each SVG feature will be thicker or thinner,\n"
"therefore the fine features may be more affected by this parameter.")
)
grid0.addWidget(self.film_scale_label, 2, 0)
grid0.addWidget(self.film_scale_entry, 2, 1)
grid0.addWidget(self.film_scale_label, 3, 0)
grid0.addWidget(self.film_scale_entry, 3, 1)
self.layout.addStretch()
@ -7737,7 +7801,7 @@ class FAExcPrefGroupUI(OptionsGroupUI):
self.layout.addWidget(self.exc_list_label)
self.exc_list_text = FCTextArea()
self.exc_list_text.sizeHint(custom_sizehint=150)
# self.exc_list_text.sizeHint(custom_sizehint=150)
font = QtGui.QFont()
font.setPointSize(12)
self.exc_list_text.setFont(font)
@ -7770,7 +7834,7 @@ class FAGcoPrefGroupUI(OptionsGroupUI):
self.layout.addWidget(self.gco_list_label)
self.gco_list_text = FCTextArea()
self.gco_list_text.sizeHint(custom_sizehint=150)
# self.gco_list_text.sizeHint(custom_sizehint=150)
font = QtGui.QFont()
font.setPointSize(12)
self.gco_list_text.setFont(font)
@ -7803,7 +7867,7 @@ class FAGrbPrefGroupUI(OptionsGroupUI):
self.layout.addWidget(self.grb_list_label)
self.grb_list_text = FCTextArea()
self.grb_list_text.sizeHint(custom_sizehint=150)
# self.grb_list_text.sizeHint(custom_sizehint=150)
self.layout.addWidget(self.grb_list_text)
font = QtGui.QFont()
font.setPointSize(12)
@ -7814,6 +7878,7 @@ class FAGrbPrefGroupUI(OptionsGroupUI):
"FlatCAM and the files with above extensions.\n"
"They will be active after next logon.\n"
"This work only in Windows."))
self.layout.addWidget(self.grb_list_btn)
# self.layout.addStretch()

View File

@ -292,7 +292,11 @@ class GerberObjectUI(ObjectUI):
"A value here of 0.25 means an overlap of 25%% from the tool diameter found above.")
)
overlabel.setMinimumWidth(90)
self.iso_overlap_entry = FloatEntry()
self.iso_overlap_entry = FCDoubleSpinner()
self.iso_overlap_entry.set_precision(3)
self.iso_overlap_entry.setWrapping(True)
self.iso_overlap_entry.setRange(0.000, 0.999)
self.iso_overlap_entry.setSingleStep(0.1)
grid1.addWidget(overlabel, 2, 0)
grid1.addWidget(self.iso_overlap_entry, 2, 1, 1, 2)
@ -709,11 +713,12 @@ class ExcellonObjectUI(ObjectUI):
self.eendz_entry = LengthEntry()
grid1.addWidget(self.eendz_entry, 5, 1)
# Excellon Feedrate
frlabel = QtWidgets.QLabel('%s:' % _('Feedrate (Plunge)'))
# Excellon Feedrate Z
frlabel = QtWidgets.QLabel('%s:' % _('Feedrate Z'))
frlabel.setToolTip(
_("Tool speed while drilling\n"
"(in units per minute).\n"
"So called 'Plunge' feedrate.\n"
"This is for linear move G01.")
)
grid1.addWidget(frlabel, 6, 0)

View File

@ -274,7 +274,7 @@ class Film(FlatCAMTool):
self.app.inform.emit('[WARNING_NOTCL] %s' % _("Export SVG positive cancelled."))
return
else:
self.app.export_svg_black(name, boxname, filename, scale_factor=scale_stroke_width)
self.app.export_svg_positive(name, boxname, filename, scale_factor=scale_stroke_width)
else:
try:
filename, _f = QtWidgets.QFileDialog.getSaveFileName(

View File

@ -292,7 +292,11 @@ class NonCopperClear(FlatCAMTool, Gerber):
"Higher values = slow processing and slow execution on CNC\n"
"due of too many paths.")
)
self.ncc_overlap_entry = FCEntry()
self.ncc_overlap_entry = FCDoubleSpinner()
self.ncc_overlap_entry.set_precision(3)
self.ncc_overlap_entry.setWrapping(True)
self.ncc_overlap_entry.setRange(0.000, 0.999)
self.ncc_overlap_entry.setSingleStep(0.1)
grid3.addWidget(nccoverlabel, 2, 0)
grid3.addWidget(self.ncc_overlap_entry, 2, 1)
@ -1292,6 +1296,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
method=None,
rest=None,
tools_storage=None,
plot=True,
run_threaded=True):
"""
Clear the excess copper from the entire object.
@ -2189,9 +2194,9 @@ class NonCopperClear(FlatCAMTool, Gerber):
def job_thread(app_obj):
try:
if rest_machining_choice is True:
app_obj.new_object("geometry", name, gen_clear_area_rest)
app_obj.new_object("geometry", name, gen_clear_area_rest, plot=plot)
else:
app_obj.new_object("geometry", name, gen_clear_area)
app_obj.new_object("geometry", name, gen_clear_area, plot=plot)
except FlatCAMApp.GracefulException:
proc.done()
return

View File

@ -214,8 +214,12 @@ class ToolPaint(FlatCAMTool, Gerber):
"Higher values = slow processing and slow execution on CNC\n"
"due of too many paths.")
)
self.paintoverlap_entry = FCDoubleSpinner()
self.paintoverlap_entry.set_precision(3)
self.paintoverlap_entry.setWrapping(True)
self.paintoverlap_entry.setRange(0.000, 0.999)
self.paintoverlap_entry.setSingleStep(0.1)
grid3.addWidget(ovlabel, 1, 0)
self.paintoverlap_entry = FCEntry()
grid3.addWidget(self.paintoverlap_entry, 1, 1)
# Margin
@ -1168,7 +1172,9 @@ class ToolPaint(FlatCAMTool, Gerber):
outname=None,
connect=None,
contour=None,
tools_storage=None):
tools_storage=None,
plot=True,
run_threaded=True):
"""
Paints a polygon selected by clicking on its interior or by having a point coordinates given
@ -1432,7 +1438,7 @@ class ToolPaint(FlatCAMTool, Gerber):
def job_thread(app_obj):
try:
app_obj.new_object("geometry", name, gen_paintarea)
app_obj.new_object("geometry", name, gen_paintarea, plot=plot)
except FlatCAMApp.GracefulException:
proc.done()
return
@ -1451,8 +1457,11 @@ class ToolPaint(FlatCAMTool, Gerber):
# Promise object with the new name
self.app.collection.promise(name)
# Background
self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
if run_threaded:
# Background
self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
else:
job_thread(app_obj=self.app)
def paint_poly_all(self, obj,
tooldia=None,
@ -1463,7 +1472,9 @@ class ToolPaint(FlatCAMTool, Gerber):
outname=None,
connect=None,
contour=None,
tools_storage=None):
tools_storage=None,
plot=True,
run_threaded=True):
"""
Paints all polygons in this object.
@ -1901,9 +1912,9 @@ class ToolPaint(FlatCAMTool, Gerber):
def job_thread(app_obj):
try:
if self.rest_cb.isChecked():
app_obj.new_object("geometry", name, gen_paintarea_rest_machining)
app_obj.new_object("geometry", name, gen_paintarea_rest_machining, plot=plot)
else:
app_obj.new_object("geometry", name, gen_paintarea)
app_obj.new_object("geometry", name, gen_paintarea, plot=plot)
except FlatCAMApp.GracefulException:
proc.done()
return
@ -1920,8 +1931,11 @@ class ToolPaint(FlatCAMTool, Gerber):
# Promise object with the new name
self.app.collection.promise(name)
# Background
self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
if run_threaded:
# Background
self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
else:
job_thread(app_obj=self.app)
def paint_poly_area(self, obj, sel_obj,
tooldia=None,
@ -1932,7 +1946,9 @@ class ToolPaint(FlatCAMTool, Gerber):
outname=None,
connect=None,
contour=None,
tools_storage=None):
tools_storage=None,
plot=True,
run_threaded=True):
"""
Paints all polygons in this object that are within the sel_obj object
@ -2366,9 +2382,9 @@ class ToolPaint(FlatCAMTool, Gerber):
def job_thread(app_obj):
try:
if self.rest_cb.isChecked():
app_obj.new_object("geometry", name, gen_paintarea_rest_machining)
app_obj.new_object("geometry", name, gen_paintarea_rest_machining, plot=plot)
else:
app_obj.new_object("geometry", name, gen_paintarea)
app_obj.new_object("geometry", name, gen_paintarea, plot=plot)
except FlatCAMApp.GracefulException:
proc.done()
return
@ -2385,8 +2401,11 @@ class ToolPaint(FlatCAMTool, Gerber):
# Promise object with the new name
self.app.collection.promise(name)
# Background
self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
if run_threaded:
# Background
self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
else:
job_thread(app_obj=self.app)
def paint_poly_ref(self, obj, sel_obj,
tooldia=None,
@ -2397,7 +2416,9 @@ class ToolPaint(FlatCAMTool, Gerber):
outname=None,
connect=None,
contour=None,
tools_storage=None):
tools_storage=None,
plot=True,
run_threaded=True):
"""
Paints all polygons in this object that are within the sel_obj object
@ -2441,7 +2462,9 @@ class ToolPaint(FlatCAMTool, Gerber):
outname=outname,
connect=connect,
contour=contour,
tools_storage=tools_storage)
tools_storage=tools_storage,
plot=plot,
run_threaded=run_threaded)
@staticmethod
def paint_bounds(geometry):

Binary file not shown.

Before

Width:  |  Height:  |  Size: 509 B

After

Width:  |  Height:  |  Size: 303 B

BIN
share/bug32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 686 B

BIN
share/pdf_link16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 B

View File

@ -78,8 +78,7 @@ class TclCommand(object):
:return: current command
"""
command_string = []
command_string = list()
command_string.append(self.aliases[0])
if self.original_args is not None:
@ -117,7 +116,7 @@ class TclCommand(object):
if help_key in self.arg_names:
arg_type = self.arg_names[help_key]
type_name = str(arg_type.__name__)
#in_command_name = help_key + "<" + type_name + ">"
# in_command_name = help_key + "<" + type_name + ">"
in_command_name = help_key
elif help_key in self.option_types:
@ -163,35 +162,36 @@ class TclCommand(object):
@staticmethod
def parse_arguments(args):
"""
Pre-processes arguments to detect '-keyword value' pairs into dictionary
and standalone parameters into list.
"""
Pre-processes arguments to detect '-keyword value' pairs into dictionary
and standalone parameters into list.
This is copy from FlatCAMApp.setup_shell().h() just for accessibility,
original should be removed after all commands will be converted
This is copy from FlatCAMApp.setup_shell().h() just for accessibility,
original should be removed after all commands will be converted
:param args: arguments from tcl to parse
:return: arguments, options
"""
:param args: arguments from tcl to parse
:return: arguments, options
"""
options = {}
arguments = []
n = len(args)
name = None
for i in range(n):
match = re.search(r'^-([a-zA-Z].*)', args[i])
if match:
assert name is None
name = match.group(1)
continue
options = {}
arguments = []
n = len(args)
if name is None:
arguments.append(args[i])
else:
options[name] = args[i]
name = None
name = None
for i in range(n):
match = re.search(r'^-([a-zA-Z].*)', args[i])
if match:
assert name is None
name = match.group(1)
continue
return arguments, options
if name is None:
arguments.append(args[i])
else:
options[name] = args[i]
name = None
return arguments, options
def check_args(self, args):
"""
@ -274,7 +274,6 @@ class TclCommand(object):
"""
# self.worker_task.emit({'fcn': self.exec_command_test, 'params': [text, False]})
try:
self.log.debug("TCL command '%s' executed." % str(self.__class__))
self.original_args = args
@ -416,7 +415,6 @@ class TclCommandSignaled(TclCommand):
# when operation will be really long is good to set it higher then defqault 30s
self.app.worker_task.emit({'fcn': self.execute_call, 'params': [args, unnamed_args]})
return self.output
except Exception as unknown:

View File

@ -29,6 +29,7 @@ class TclCommandAlignDrill(TclCommandSignaled):
('axisoffset', float),
('dia', float),
('dist', float),
('outname', str),
])
# array of mandatory options for current Tcl command: required = {'name','outname'}
@ -47,9 +48,11 @@ class TclCommandAlignDrill(TclCommandSignaled):
('minoffset', 'min and max distance between align hole and pcb.'),
('axisoffset', 'Offset on second axis before aligment holes'),
('axis', 'Mirror axis parallel to the X or Y axis.'),
('dist', 'Distance of the mirror axis to the X or Y axis.')
('dist', 'Distance of the mirror axis to the X or Y axis.'),
('outname', 'Name of the resulting Excellon object.'),
]),
'examples': []
'examples': ['aligndrill my_object -axis X -box my_object -dia 3.125 -grid 1 '
'-gridoffset 0 -minoffset 2 -axisoffset 2']
}
def execute(self, args, unnamed_args):
@ -64,6 +67,11 @@ class TclCommandAlignDrill(TclCommandSignaled):
name = args['name']
if 'outname' in args:
outname = args['outname']
else:
outname = name + "_aligndrill"
# Get source object.
try:
obj = self.app.collection.get_by_name(str(name))
@ -176,9 +184,7 @@ class TclCommandAlignDrill(TclCommandSignaled):
px = 0.5 * (xmin + xmax)
py = 0.5 * (ymin + ymax)
obj.app.new_object("excellon",
name + "_aligndrill",
alligndrill_init_me)
obj.app.new_object("excellon", outname, alligndrill_init_me, plot=False)
except Exception as e:
return "Operation failed: %s" % str(e)
@ -194,8 +200,8 @@ class TclCommandAlignDrill(TclCommandSignaled):
try:
px = dist
py = dist
obj.app.new_object("excellon", name + "_alligndrill", alligndrill_init_me)
obj.app.new_object("excellon", outname, alligndrill_init_me, plot=False)
except Exception as e:
return "Operation failed: %s" % str(e)
return 'Ok'
return 'Ok. Align Drills Excellon object created'

View File

@ -17,7 +17,7 @@ class TclCommandAlignDrillGrid(TclCommandSignaled):
# Dictionary of types from Tcl command, needs to be ordered.
# For positional arguments
arg_names = collections.OrderedDict([
('outname', str)
])
# Dictionary of types from Tcl command, needs to be ordered.
@ -29,11 +29,12 @@ class TclCommandAlignDrillGrid(TclCommandSignaled):
('gridy', float),
('gridoffsety', float),
('columns', int),
('rows', int)
('rows', int),
('outname', str)
])
# array of mandatory options for current Tcl command: required = {'name','outname'}
required = ['outname', 'gridx', 'gridy', 'columns', 'rows']
required = ['gridx', 'gridy', 'columns', 'rows']
# structured help for current command, args needs to be ordered
help = {
@ -48,7 +49,7 @@ class TclCommandAlignDrillGrid(TclCommandSignaled):
('colums', 'Number of grid holes on X axis.'),
('rows', 'Number of grid holes on Y axis.'),
]),
'examples': []
'examples': ['aligndrillgrid -rows 2 -columns 2 -gridoffsetx 10 -gridoffsety 10 -gridx 2.54 -gridy 5.08']
}
def execute(self, args, unnamed_args):
@ -61,6 +62,11 @@ class TclCommandAlignDrillGrid(TclCommandSignaled):
:return: None or exception
"""
if 'outname' in args:
outname = args['outname']
else:
outname = "new_aligndrill_grid"
if 'gridoffsetx' not in args:
gridoffsetx = 0
else:
@ -102,4 +108,4 @@ class TclCommandAlignDrillGrid(TclCommandSignaled):
init_obj.create_geometry()
# Create the new object
self.app.new_object("excellon", args['outname'], aligndrillgrid_init_me)
self.app.new_object("excellon", outname, aligndrillgrid_init_me, plot=False)

View File

@ -90,6 +90,6 @@ class TclCommandBbox(TclCommand):
bounding_box = bounding_box.envelope
geo_obj.solid_geometry = bounding_box
self.app.new_object("geometry", args['outname'], geo_init)
self.app.new_object("geometry", args['outname'], geo_init, plot=False)
except Exception as e:
return "Operation failed: %s" % str(e)

View File

@ -24,7 +24,7 @@ class TclCommandCncjob(TclCommandSignaled):
# dictionary of types from Tcl command, needs to be ordered , this is for options like -optionname value
option_types = collections.OrderedDict([
('tooldia', float),
('dia', float),
('z_cut', float),
('z_move', float),
('feedrate', float),
@ -42,6 +42,7 @@ class TclCommandCncjob(TclCommandSignaled):
('dwell', bool),
('dwelltime', float),
('pp', str),
('muted', int),
('outname', str)
])
@ -53,7 +54,7 @@ class TclCommandCncjob(TclCommandSignaled):
'main': "Generates a CNC Job from a Geometry Object.",
'args': collections.OrderedDict([
('name', 'Name of the source object.'),
('tooldia', 'Tool diameter to show on screen.'),
('dia', 'Tool diameter to show on screen.'),
('z_cut', 'Z-axis cutting position.'),
('z_move', 'Z-axis moving position.'),
('feedrate', 'Moving speed on X-Y plane when cutting.'),
@ -71,7 +72,8 @@ class TclCommandCncjob(TclCommandSignaled):
('dwell', 'True or False; use (or not) the dwell'),
('dwelltime', 'Time to pause to allow the spindle to reach the full speed'),
('outname', 'Name of the resulting Geometry object.'),
('pp', 'Name of the Geometry postprocessor. No quotes, case sensitive')
('pp', 'Name of the Geometry postprocessor. No quotes, case sensitive'),
('muted', 'It will not put errors in the Shell.')
]),
'examples': ['cncjob geo_name -tooldia 0.5 -z_cut -1.7 -z_move 2 -feedrate 120 -ppname_g default']
}
@ -91,15 +93,26 @@ class TclCommandCncjob(TclCommandSignaled):
if 'outname' not in args:
args['outname'] = str(name) + "_cnc"
if 'muted' in args:
muted = args['muted']
else:
muted = 0
obj = self.app.collection.get_by_name(str(name), isCaseSensitive=False)
if obj is None:
self.raise_tcl_error("Object not found: %s" % str(name))
if not muted:
self.raise_tcl_error("Object not found: %s" % str(name))
else:
return
if not isinstance(obj, FlatCAMGeometry):
self.raise_tcl_error('Expected FlatCAMGeometry, got %s %s.' % (str(name), type(obj)))
if not muted:
self.raise_tcl_error('Expected FlatCAMGeometry, got %s %s.' % (str(name), type(obj)))
else:
return
args["tooldia"] = args["tooldia"] if "tooldia" in args else obj.options["cnctooldia"]
args["dia"] = args["dia"] if "dia" in args else obj.options["cnctooldia"]
args["z_cut"] = args["z_cut"] if "z_cut" in args else obj.options["cutz"]
args["z_move"] = args["z_move"] if "z_move" in args else obj.options["travelz"]
@ -130,20 +143,24 @@ class TclCommandCncjob(TclCommandSignaled):
del args['name']
for arg in args:
if arg == "toolchange_xy" or arg == "spindlespeed":
if arg == "toolchange_xy" or arg == "spindlespeed" or arg == "startz":
continue
else:
if args[arg] is None:
self.raise_tcl_error('One of the command parameters that have to be not None, is None.\n'
'The parameter that is None is in the default values found in the list \n'
'generated by the TclCommand "list_sys geom". or in the arguments.')
print(arg, args[arg])
if not muted:
self.raise_tcl_error('One of the command parameters that have to be not None, is None.\n'
'The parameter that is None is in the default values found in the list \n'
'generated by the TclCommand "list_sys geom". or in the arguments.')
else:
return
# HACK !!! Should be solved elsewhere!!!
# default option for multidepth is False
obj.options['multidepth'] = False
if not obj.multigeo:
obj.generatecncjob(use_thread=False, **args)
obj.generatecncjob(use_thread=False, plot=False, **args)
else:
# Update the local_tools_dict values with the args value
local_tools_dict = deepcopy(obj.tools)
@ -171,5 +188,6 @@ class TclCommandCncjob(TclCommandSignaled):
outname=args['outname'],
tools_dict=local_tools_dict,
tools_in_use=[],
use_thread=False)
use_thread=False,
plot=False)
# self.raise_tcl_error('The object is a multi-geo geometry which is not supported in cncjob Tcl Command')

View File

@ -226,6 +226,7 @@ class TclCommandCopperClear(TclCommand):
contour=contour,
rest=rest,
tools_storage=ncc_tools,
plot=False,
run_threaded=False)
return
@ -259,6 +260,7 @@ class TclCommandCopperClear(TclCommand):
contour=contour,
rest=rest,
tools_storage=ncc_tools,
plot=False,
run_threaded=False)
return
else:

View File

@ -123,7 +123,7 @@ class TclCommandCutout(TclCommand):
geo_obj.solid_geometry = cascaded_union([LineString(segment) for segment in cuts])
try:
self.app.new_object("geometry", name + "_cutout", geo_init_me)
self.app.new_object("geometry", name + "_cutout", geo_init_me, plot=False)
self.app.inform.emit("[success] Rectangular-form Cutout operation finished.")
except Exception as e:
return "Operation failed: %s" % str(e)

View File

@ -17,7 +17,6 @@ class TclCommandDrillcncjob(TclCommandSignaled):
# dictionary of types from Tcl command, needs to be ordered , this is for options like -optionname value
option_types = collections.OrderedDict([
('tools', str),
('drilled_dias', str),
('drillz', float),
('travelz', float),
@ -31,7 +30,8 @@ class TclCommandDrillcncjob(TclCommandSignaled):
('pp', str),
('outname', str),
('opt_type', str),
('diatol', float)
('diatol', float),
('muted', int)
])
# array of mandatory options for current Tcl command: required = {'name','outname'}
@ -62,7 +62,8 @@ class TclCommandDrillcncjob(TclCommandSignaled):
'the same as the ones in the tools from the Excellon object. E.g: if in drill_dias we have a '
'diameter with value 1.0, in the Excellon we have a tool with dia = 1.05 and we set a tolerance '
'diatol = 5.0 then the drills with the dia = (0.95 ... 1.05) '
'in Excellon will be processed. Float number.')
'in Excellon will be processed. Float number.'),
('muted', 'It will not put errors in the Shell or status bar.')
]),
'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'
@ -84,12 +85,20 @@ class TclCommandDrillcncjob(TclCommandSignaled):
if 'outname' not in args:
args['outname'] = name + "_cnc"
if 'muted' in args:
muted = args['muted']
else:
muted = 0
obj = self.app.collection.get_by_name(name)
if obj is None:
self.raise_tcl_error("Object not found: %s" % name)
if not isinstance(obj, FlatCAMExcellon):
self.raise_tcl_error('Expected FlatCAMExcellon, got %s %s.' % (name, type(obj)))
if not muted:
self.raise_tcl_error('Expected FlatCAMExcellon, got %s %s.' % (name, type(obj)))
else:
return
xmin = obj.options['xmin']
ymin = obj.options['ymin']
@ -127,8 +136,11 @@ class TclCommandDrillcncjob(TclCommandSignaled):
nr_diameters -= 1
if nr_diameters > 0:
self.raise_tcl_error("One or more tool diameters of the drills to be drilled passed to the "
"TclCommand are not actual tool diameters in the Excellon object.")
if not muted:
self.raise_tcl_error("One or more tool diameters of the drills to be drilled passed to the "
"TclCommand are not actual tool diameters in the Excellon object.")
else:
return
# make a string of diameters separated by comma; this is what generate_from_excellon_by_tool() is
# expecting as tools parameter
@ -181,4 +193,4 @@ class TclCommandDrillcncjob(TclCommandSignaled):
job_obj.gcode_parse()
job_obj.create_geometry()
self.app.new_object("cncjob", args['outname'], job_init)
self.app.new_object("cncjob", args['outname'], job_init, plot=False)

View File

@ -61,4 +61,4 @@ class TclCommandExteriors(TclCommandSignaled):
geo_obj.solid_geometry = obj_exteriors
obj_exteriors = obj.get_exteriors()
self.app.new_object('geometry', outname, geo_init)
self.app.new_object('geometry', outname, geo_init, plot=False)

View File

@ -279,7 +279,7 @@ class TclCommandGeoCutout(TclCommandSignaled):
app_obj.inform.emit("[success] Any-form Cutout operation finished.")
outname = cutout_obj.options["name"] + "_cutout"
self.app.new_object('geometry', outname, geo_init)
self.app.new_object('geometry', outname, geo_init, plot=False)
# cutout_obj.plot()
# self.app.inform.emit("[success] Any-form Cutout operation finished.")
@ -338,7 +338,7 @@ class TclCommandGeoCutout(TclCommandSignaled):
app_obj.inform.emit("[success] Any-form Cutout operation finished.")
outname = cutout_obj.options["name"] + "_cutout"
self.app.new_object('geometry', outname, geo_init)
self.app.new_object('geometry', outname, geo_init, plot=False)
cutout_obj = self.app.collection.get_by_name(outname)
else:

View File

@ -71,7 +71,7 @@ class TclCommandImportSvg(TclCommandSignaled):
with self.app.proc_container.new("Import SVG"):
# Object creation
self.app.new_object(obj_type, outname, obj_init)
self.app.new_object(obj_type, outname, obj_init, plot=False)
# Register recent file
self.app.file_opened.emit("svg", filename)

View File

@ -85,4 +85,4 @@ class TclCommandIsolate(TclCommandSignaled):
self.raise_tcl_error('Expected FlatCAMGerber, got %s %s.' % (name, type(obj)))
del args['name']
obj.isolate(**args)
obj.isolate(plot=False, **args)

View File

@ -61,4 +61,4 @@ class TclCommandJoinExcellon(TclCommand):
FlatCAMExcellon.merge(objs, obj_)
if objs is not None:
self.app.new_object("excellon", outname, initialize)
self.app.new_object("excellon", outname, initialize, plot=False)

View File

@ -61,4 +61,4 @@ class TclCommandJoinGeometry(TclCommand):
FlatCAMGeometry.merge(objs, obj_)
if objs is not None:
self.app.new_object("geometry", outname, initialize)
self.app.new_object("geometry", outname, initialize, plot=False)

View File

@ -128,7 +128,7 @@ class TclCommandMillDrills(TclCommandSignaled):
del args['name']
# This runs in the background... Is blocking handled?
success, msg = obj.generate_milling_drills(**args)
success, msg = obj.generate_milling_drills(plot=False, **args)
except Exception as e:
success = None
msg = None

View File

@ -127,7 +127,7 @@ class TclCommandMillSlots(TclCommandSignaled):
del args['name']
# This runs in the background... Is blocking handled?
success, msg = obj.generate_milling_slots(**args)
success, msg = obj.generate_milling_slots(plot=False, **args)
except Exception as e:
success = None

View File

@ -103,6 +103,5 @@ class TclCommandMirror(TclCommandSignaled):
try:
obj.mirror(axis, [dist, dist])
obj.plot()
except Exception as e:
return "Operation failed: %s" % str(e)

View File

@ -36,4 +36,4 @@ class TclCommandNew(TclCommand):
:return: None or exception
"""
self.app.on_file_new()
self.app.on_file_new(cli=True)

View File

@ -0,0 +1,51 @@
from ObjectCollection import *
from tclCommands.TclCommand import TclCommandSignaled
class TclCommandNewExcellon(TclCommandSignaled):
"""
Tcl shell command to subtract polygon from the given Geometry object.
"""
# array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon)
aliases = ['new_excellon']
# Dictionary of types from Tcl command, needs to be ordered.
# For positional arguments
arg_names = collections.OrderedDict([
('name', str)
])
# Dictionary of types from Tcl command, needs to be ordered.
# 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': "Creates a new empty Excellon object.",
'args': collections.OrderedDict([
('name', 'New object name.'),
]),
'examples': []
}
def execute(self, args, unnamed_args):
"""
execute current TCL shell command
:param args: array of known named arguments and options
:param unnamed_args: array of other values which were passed into command
without -somename and we do not have them in known arg_names
:return: None or exception
"""
if 'name' in args:
name = args['name']
else:
name = 'new_exc'
self.app.new_object('excellon', name, lambda x, y: None, plot=False)

View File

@ -23,7 +23,7 @@ class TclCommandNewGeometry(TclCommandSignaled):
])
# array of mandatory options for current Tcl command: required = {'name','outname'}
required = ['name']
required = []
# structured help for current command, args needs to be ordered
help = {
@ -43,7 +43,9 @@ class TclCommandNewGeometry(TclCommandSignaled):
without -somename and we do not have them in known arg_names
:return: None or exception
"""
if 'name' in args:
name = args['name']
else:
name = 'new_geo'
name = args['name']
self.app.new_object('geometry', str(name), lambda x, y: None)
self.app.new_object('geometry', str(name), lambda x, y: None, plot=False)

View File

@ -0,0 +1,68 @@
from ObjectCollection import *
from tclCommands.TclCommand import TclCommandSignaled
class TclCommandNewGerber(TclCommandSignaled):
"""
Tcl shell command to subtract polygon from the given Geometry object.
"""
# array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon)
aliases = ['new_gerber']
# Dictionary of types from Tcl command, needs to be ordered.
# For positional arguments
arg_names = collections.OrderedDict([
('name', str)
])
# Dictionary of types from Tcl command, needs to be ordered.
# 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': "Creates a new empty Gerber object.",
'args': collections.OrderedDict([
('name', 'New object name.'),
]),
'examples': []
}
def execute(self, args, unnamed_args):
"""
execute current TCL shell command
:param args: array of known named arguments and options
:param unnamed_args: array of other values which were passed into command
without -somename and we do not have them in known arg_names
:return: None or exception
"""
if 'name' in args:
name = args['name']
else:
name = 'new_grb'
def initialize(grb_obj, self):
grb_obj.multitool = False
grb_obj.source_file = []
grb_obj.multigeo = False
grb_obj.follow = False
grb_obj.apertures = {}
grb_obj.solid_geometry = []
try:
grb_obj.options['xmin'] = 0
grb_obj.options['ymin'] = 0
grb_obj.options['xmax'] = 0
grb_obj.options['ymax'] = 0
except KeyError:
pass
self.app.new_object('gerber', name, initialize, plot=False)

View File

@ -89,7 +89,7 @@ class TclCommandNregions(TclCommand):
non_copper = bounding_box.difference(geo)
geo_obj.solid_geometry = non_copper
self.app.new_object("geometry", args['outname'], geo_init)
self.app.new_object("geometry", args['outname'], geo_init, plot=False)
except Exception as e:
return "Operation failed: %s" % str(e)

View File

@ -46,5 +46,7 @@ class TclCommandOpenExcellon(TclCommandSignaled):
"""
filename = args.pop('filename')
filename = filename.replace(' ', '')
args['plot'] = False
self.app.open_excellon(filename, **args)

View File

@ -45,5 +45,8 @@ class TclCommandOpenGCode(TclCommandSignaled):
without -somename and we do not have them in known arg_names
:return: None or exception
"""
args['plot'] = False
filename = args["filename"]
filename = filename.replace(' ', '')
self.app.open_gcode(args['filename'], **args)
self.app.open_gcode(filename, **args)

View File

@ -30,7 +30,7 @@ class TclCommandOpenGerber(TclCommandSignaled):
('filename', 'Path to file to open.'),
('outname', 'Name of the resulting Gerber object.')
]),
'examples': []
'examples': ["open_gerber gerber_object_path -outname bla"]
}
def execute(self, args, unnamed_args):
@ -50,25 +50,19 @@ class TclCommandOpenGerber(TclCommandSignaled):
self.raise_tcl_error('Expected FlatCAMGerber, got %s %s.' % (outname, type(gerber_obj)))
# Opening the file happens here
self.app.progress.emit(30)
try:
gerber_obj.parse_file(filename)
except IOError:
app_obj.inform.emit("[ERROR_NOTCL] Failed to open file: %s " % filename)
app_obj.progress.emit(0)
self.raise_tcl_error('Failed to open file: %s' % filename)
except ParseError as e:
app_obj.inform.emit("[ERROR_NOTCL] Failed to parse file: %s, %s " % (filename, str(e)))
app_obj.progress.emit(0)
self.log.error(str(e))
return
# Further parsing
app_obj.progress.emit(70)
filename = args['filename']
filename = filename.replace(' ', '')
if 'outname' in args:
outname = args['outname']
@ -76,17 +70,16 @@ class TclCommandOpenGerber(TclCommandSignaled):
outname = filename.split('/')[-1].split('\\')[-1]
if 'follow' in args:
self.raise_tcl_error("The 'follow' parameter is obsolete. To create 'follow' geometry use the 'follow' parameter for the Tcl Command isolate()")
self.raise_tcl_error("The 'follow' parameter is obsolete. To create 'follow' geometry use the 'follow' "
"parameter for the Tcl Command isolate()")
with self.app.proc_container.new("Opening Gerber"):
# Object creation
self.app.new_object("gerber", outname, obj_init)
self.app.new_object("gerber", outname, obj_init, plot=False)
# Register recent file
self.app.file_opened.emit("gerber", filename)
self.app.progress.emit(100)
# GUI feedback
self.app.inform.emit("[success] Opened: " + filename)

View File

@ -43,5 +43,7 @@ class TclCommandOpenProject(TclCommandSignaled):
without -somename and we do not have them in known arg_names
:return: None or exception
"""
filename = args['filename']
filename = filename.replace(' ', '')
self.app.open_project(args['filename'])
self.app.open_project(filename, cli=True, plot=False)

View File

@ -201,7 +201,9 @@ class TclCommandPaint(TclCommand):
outname=outname,
connect=connect,
contour=contour,
tools_storage=paint_tools)
tools_storage=paint_tools,
plot=False,
run_threaded=False)
return
# Paint single polygon in the painted object
@ -222,7 +224,9 @@ class TclCommandPaint(TclCommand):
outname=outname,
connect=connect,
contour=contour,
tools_storage=paint_tools)
tools_storage=paint_tools,
plot=False,
run_threaded=False)
return
# Paint all polygons found within the box object from the the painted object
@ -250,7 +254,9 @@ class TclCommandPaint(TclCommand):
outname=outname,
connect=connect,
contour=contour,
tools_storage=paint_tools)
tools_storage=paint_tools,
plot=False,
run_threaded=False)
return
else:

View File

@ -90,7 +90,7 @@ class TclCommandPanelize(TclCommand):
if 'threaded' in args:
threaded = args['threaded']
else:
threaded = 1
threaded = 0
if 'spacing_columns' in args:
spacing_columns = args['spacing_columns']
@ -265,10 +265,10 @@ class TclCommandPanelize(TclCommand):
if isinstance(obj, FlatCAMExcellon):
self.app.progress.emit(50)
self.app.new_object("excellon", outname, job_init_excellon, plot=True, autoselected=True)
self.app.new_object("excellon", outname, job_init_excellon, plot=False, autoselected=True)
else:
self.app.progress.emit(50)
self.app.new_object("geometry", outname, job_init_geometry, plot=True, autoselected=True)
self.app.new_object("geometry", outname, job_init_geometry, plot=False, autoselected=True)
if threaded == 1:
proc = self.app.proc_container.new("Generating panel ... Please wait.")

View File

@ -2,7 +2,7 @@ from ObjectCollection import *
from tclCommands.TclCommand import TclCommand
class TclCommandPlot(TclCommand):
class TclCommandPlotAll(TclCommand):
"""
Tcl shell command to update the plot on the user interface.
@ -11,7 +11,7 @@ class TclCommandPlot(TclCommand):
"""
# List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon)
aliases = ['plot']
aliases = ['plot_all']
# Dictionary of types from Tcl command, needs to be ordered
arg_names = collections.OrderedDict([

View File

@ -0,0 +1,51 @@
from ObjectCollection import *
from tclCommands.TclCommand import TclCommand
class TclCommandPlotObjects(TclCommand):
"""
Tcl shell command to update the plot on the user interface.
example:
plot
"""
# List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon)
aliases = ['plot_objects']
# Dictionary of types from Tcl command, needs to be ordered
arg_names = collections.OrderedDict([
('names', 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 = []
# structured help for current command, args needs to be ordered
help = {
'main': "Plot a list of objects.",
'args': collections.OrderedDict([
('names', "UA list of object names to be plotted.")
]),
'examples': ["plot_objects"]
}
def execute(self, args, unnamed_args):
"""
:param args:
:param unnamed_args:
:return:
"""
names = [x.strip() for x in args['names'].split(",")]
objs = []
for name in names:
objs.append(self.app.collection.get_by_name(name))
for obj in objs:
obj.plot()

View File

@ -22,7 +22,8 @@ class TclCommandWriteGCode(TclCommandSignaled):
# For options like -optionname value
option_types = collections.OrderedDict([
('preamble', str),
('postamble', str)
('postamble', str),
('muted', int)
])
# array of mandatory options for current Tcl command: required = {'name','outname'}
@ -35,7 +36,9 @@ class TclCommandWriteGCode(TclCommandSignaled):
('name', 'Source CNC Job object.'),
('filename', 'Output filename.'),
('preamble', 'Text to append at the beginning.'),
('postamble', 'Text to append at the end.')
('postamble', 'Text to append at the end.'),
('muted', 'It will not put errors in the Shell or status bar.')
]),
'examples': ["write_gcode name c:\\\\gcode_repo"]
}
@ -62,6 +65,11 @@ class TclCommandWriteGCode(TclCommandSignaled):
preamble = args['preamble'] if 'preamble' in args else ''
postamble = args['postamble'] if 'postamble' in args else ''
if 'muted' in args:
muted = args['muted']
else:
muted = 0
# TODO: This is not needed any more? All targets should be present.
# If there are promised objects, wait until all promises have been fulfilled.
# if self.collection.has_promises():
@ -82,9 +90,15 @@ class TclCommandWriteGCode(TclCommandSignaled):
try:
obj = self.app.collection.get_by_name(str(obj_name))
except:
return "Could not retrieve object: %s" % obj_name
if not muted:
return "Could not retrieve object: %s" % obj_name
else:
return
try:
obj.export_gcode(str(filename), str(preamble), str(postamble))
except Exception as e:
return "Operation failed: %s" % str(e)
if not muted:
return "Operation failed: %s" % str(e)
else:
return

View File

@ -35,7 +35,9 @@ import tclCommands.TclCommandMillSlots
import tclCommands.TclCommandMirror
import tclCommands.TclCommandNew
import tclCommands.TclCommandNregions
import tclCommands.TclCommandNewExcellon
import tclCommands.TclCommandNewGeometry
import tclCommands.TclCommandNewGerber
import tclCommands.TclCommandOffset
import tclCommands.TclCommandOpenExcellon
import tclCommands.TclCommandOpenGCode
@ -44,7 +46,8 @@ import tclCommands.TclCommandOpenProject
import tclCommands.TclCommandOptions
import tclCommands.TclCommandPaint
import tclCommands.TclCommandPanelize
import tclCommands.TclCommandPlot
import tclCommands.TclCommandPlotAll
import tclCommands.TclCommandPlotObjects
import tclCommands.TclCommandSaveProject
import tclCommands.TclCommandSaveSys
import tclCommands.TclCommandScale