Просмотр исходного кода

Merged in marius_stanciu/flatcam_beta/Beta (pull request #208)

Beta
Marius Stanciu 6 лет назад
Родитель
Сommit
a2a4fc1cc4

+ 102 - 50
FlatCAMApp.py

@@ -122,6 +122,10 @@ class App(QtCore.QObject):
     # Manual URL
     # Manual URL
     manual_url = "http://flatcam.org/manual/index.html"
     manual_url = "http://flatcam.org/manual/index.html"
     video_url = "https://www.youtube.com/playlist?list=PLVvP2SYRpx-AQgNlfoxw93tXUXon7G94_"
     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
     # this variable will hold the project status
     # if True it will mean that the project was modified and not saved
     # if True it will mean that the project was modified and not saved
@@ -399,20 +403,15 @@ class App(QtCore.QObject):
             "global_portable": self.ui.general_defaults_form.general_app_group.portability_cb,
             "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_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_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_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_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_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_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_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_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_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,
             "global_save_compressed": self.ui.general_defaults_form.general_app_group.save_type_cb,
@@ -440,15 +439,17 @@ class App(QtCore.QObject):
             "global_layout": self.ui.general_defaults_form.general_gui_set_group.layout_combo,
             "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_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_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 General
             "gerber_plot": self.ui.gerber_defaults_form.gerber_gen_group.plot_cb,
             "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_solid": self.ui.gerber_defaults_form.gerber_gen_group.solid_cb,
             "gerber_multicolored": self.ui.gerber_defaults_form.gerber_gen_group.multicolored_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_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 Options
             "gerber_isotooldia": self.ui.gerber_defaults_form.gerber_opt_group.iso_tool_dia_entry,
             "gerber_isotooldia": self.ui.gerber_defaults_form.gerber_opt_group.iso_tool_dia_entry,
@@ -466,6 +467,9 @@ class App(QtCore.QObject):
             # "gerber_aperture_scale_factor": self.ui.gerber_defaults_form.gerber_adv_opt_group.scale_aperture_entry,
             # "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_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_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 Export
             "gerber_exp_units": self.ui.gerber_defaults_form.gerber_exp_group.gerber_units_radio,
             "gerber_exp_units": self.ui.gerber_defaults_form.gerber_exp_group.gerber_units_radio,
@@ -511,9 +515,9 @@ class App(QtCore.QObject):
             # Excellon Options
             # Excellon Options
             "excellon_drillz": self.ui.excellon_defaults_form.excellon_opt_group.cutz_entry,
             "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_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_feedrate": self.ui.excellon_defaults_form.excellon_opt_group.feedrate_entry,
             "excellon_spindlespeed": self.ui.excellon_defaults_form.excellon_opt_group.spindlespeed_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_dwell": self.ui.excellon_defaults_form.excellon_opt_group.dwell_cb,
             "excellon_dwelltime": self.ui.excellon_defaults_form.excellon_opt_group.dwelltime_entry,
             "excellon_dwelltime": self.ui.excellon_defaults_form.excellon_opt_group.dwelltime_entry,
             "excellon_toolchange": self.ui.excellon_defaults_form.excellon_opt_group.toolchange_cb,
             "excellon_toolchange": self.ui.excellon_defaults_form.excellon_opt_group.toolchange_cb,
@@ -527,10 +531,10 @@ class App(QtCore.QObject):
             "excellon_offset": self.ui.excellon_defaults_form.excellon_adv_opt_group.offset_entry,
             "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_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_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_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_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_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_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,
             "excellon_f_retract": self.ui.excellon_defaults_form.excellon_adv_opt_group.fretract_cb,
 
 
@@ -583,23 +587,23 @@ class App(QtCore.QObject):
             "geometry_feedrate": self.ui.geometry_defaults_form.geometry_opt_group.cncfeedrate_entry,
             "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_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_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_dwell": self.ui.geometry_defaults_form.geometry_opt_group.dwell_cb,
             "geometry_dwelltime": self.ui.geometry_defaults_form.geometry_opt_group.dwelltime_entry,
             "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_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_toolchange": self.ui.geometry_defaults_form.geometry_opt_group.toolchange_cb,
             "geometry_toolchangez": self.ui.geometry_defaults_form.geometry_opt_group.toolchangez_entry,
             "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_depthperpass": self.ui.geometry_defaults_form.geometry_opt_group.depthperpass_entry,
             "geometry_multidepth": self.ui.geometry_defaults_form.geometry_opt_group.multidepth_cb,
             "geometry_multidepth": self.ui.geometry_defaults_form.geometry_opt_group.multidepth_cb,
 
 
             # Geometry Advanced Options
             # Geometry Advanced Options
             "geometry_toolchangexy": self.ui.geometry_defaults_form.geometry_adv_opt_group.toolchangexy_entry,
             "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_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_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_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_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_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_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_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,
             "geometry_segy": self.ui.geometry_defaults_form.geometry_adv_opt_group.segy_entry,
@@ -611,8 +615,6 @@ class App(QtCore.QObject):
             "cncjob_plot": self.ui.cncjob_defaults_form.cncjob_gen_group.plot_cb,
             "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_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": 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_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,
             "cncjob_coords_type": self.ui.cncjob_defaults_form.cncjob_gen_group.coords_type_radio,
@@ -627,6 +629,8 @@ class App(QtCore.QObject):
             # CNC Job Advanced Options
             # CNC Job Advanced Options
             "cncjob_toolchange_macro": self.ui.cncjob_defaults_form.cncjob_adv_opt_group.toolchange_text,
             "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_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
             # NCC Tool
             "tools_ncctools": self.ui.tools_defaults_form.tools_ncc_group.ncc_tool_dia_entry,
             "tools_ncctools": self.ui.tools_defaults_form.tools_ncc_group.ncc_tool_dia_entry,
@@ -675,6 +679,7 @@ class App(QtCore.QObject):
             "tools_film_type": self.ui.tools_defaults_form.tools_film_group.film_type_radio,
             "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_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_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
             # Panelize Tool
             "tools_panelize_spacing_columns": self.ui.tools_defaults_form.tools_panelize_group.pspacing_columns,
             "tools_panelize_spacing_columns": self.ui.tools_defaults_form.tools_panelize_group.pspacing_columns,
@@ -871,9 +876,6 @@ class App(QtCore.QObject):
             "gerber_multicolored": False,
             "gerber_multicolored": False,
             "gerber_circle_steps": 128,
             "gerber_circle_steps": 128,
             "gerber_use_buffer_for_union": True,
             "gerber_use_buffer_for_union": True,
-            "gerber_buffering": "full",
-            "gerber_simplification": False,
-            "gerber_simp_tolerance": 0.0005,
 
 
             # Gerber Options
             # Gerber Options
             "gerber_isotooldia": 0.00787402,
             "gerber_isotooldia": 0.00787402,
@@ -891,6 +893,9 @@ class App(QtCore.QObject):
             "gerber_aperture_scale_factor": 1.0,
             "gerber_aperture_scale_factor": 1.0,
             "gerber_aperture_buffer_factor": 0.0,
             "gerber_aperture_buffer_factor": 0.0,
             "gerber_follow": False,
             "gerber_follow": False,
+            "gerber_buffering": "full",
+            "gerber_simplification": False,
+            "gerber_simp_tolerance": 0.0005,
 
 
             # Gerber Export
             # Gerber Export
             "gerber_exp_units": 'IN',
             "gerber_exp_units": 'IN',
@@ -931,9 +936,9 @@ class App(QtCore.QObject):
             # Excellon Options
             # Excellon Options
             "excellon_drillz": -0.0590551,
             "excellon_drillz": -0.0590551,
             "excellon_travelz": 0.0787402,
             "excellon_travelz": 0.0787402,
+            "excellon_endz": 0.5,
             "excellon_feedrate": 3.14961,
             "excellon_feedrate": 3.14961,
             "excellon_spindlespeed": None,
             "excellon_spindlespeed": None,
-            "excellon_spindledir": 'CW',
             "excellon_dwell": False,
             "excellon_dwell": False,
             "excellon_dwelltime": 1,
             "excellon_dwelltime": 1,
             "excellon_toolchange": False,
             "excellon_toolchange": False,
@@ -947,10 +952,10 @@ class App(QtCore.QObject):
             "excellon_offset": 0.0,
             "excellon_offset": 0.0,
             "excellon_toolchangexy": "0.0, 0.0",
             "excellon_toolchangexy": "0.0, 0.0",
             "excellon_startz": None,
             "excellon_startz": None,
-            "excellon_endz": 0.5,
             "excellon_feedrate_rapid": 31.4961,
             "excellon_feedrate_rapid": 31.4961,
             "excellon_z_pdepth": -0.02,
             "excellon_z_pdepth": -0.02,
             "excellon_feedrate_probe": 3.14961,
             "excellon_feedrate_probe": 3.14961,
+            "excellon_spindledir": 'CW',
             "excellon_f_plunge": False,
             "excellon_f_plunge": False,
             "excellon_f_retract": False,
             "excellon_f_retract": False,
 
 
@@ -997,10 +1002,10 @@ class App(QtCore.QObject):
             "geometry_travelz": 0.0787402,
             "geometry_travelz": 0.0787402,
             "geometry_toolchange": False,
             "geometry_toolchange": False,
             "geometry_toolchangez": 0.5,
             "geometry_toolchangez": 0.5,
+            "geometry_endz": 0.5,
             "geometry_feedrate": 3.14961,
             "geometry_feedrate": 3.14961,
             "geometry_feedrate_z": 3.14961,
             "geometry_feedrate_z": 3.14961,
             "geometry_spindlespeed": None,
             "geometry_spindlespeed": None,
-            "geometry_spindledir": 'CW',
             "geometry_dwell": False,
             "geometry_dwell": False,
             "geometry_dwelltime": 1,
             "geometry_dwelltime": 1,
             "geometry_ppname_g": 'default',
             "geometry_ppname_g": 'default',
@@ -1008,11 +1013,11 @@ class App(QtCore.QObject):
             # Geometry Advanced Options
             # Geometry Advanced Options
             "geometry_toolchangexy": "0.0, 0.0",
             "geometry_toolchangexy": "0.0, 0.0",
             "geometry_startz": None,
             "geometry_startz": None,
-            "geometry_endz": 0.5,
             "geometry_feedrate_rapid": 3.14961,
             "geometry_feedrate_rapid": 3.14961,
             "geometry_extracut": False,
             "geometry_extracut": False,
             "geometry_z_pdepth": -0.02,
             "geometry_z_pdepth": -0.02,
             "geometry_f_plunge": False,
             "geometry_f_plunge": False,
+            "geometry_spindledir": 'CW',
             "geometry_feedrate_probe": 3.14961,
             "geometry_feedrate_probe": 3.14961,
             "geometry_segx": 0.0,
             "geometry_segx": 0.0,
             "geometry_segy": 0.0,
             "geometry_segy": 0.0,
@@ -1024,8 +1029,6 @@ class App(QtCore.QObject):
             "cncjob_plot": True,
             "cncjob_plot": True,
             "cncjob_plot_kind": 'all',
             "cncjob_plot_kind": 'all',
             "cncjob_annotation": True,
             "cncjob_annotation": True,
-            "cncjob_annotation_fontsize": 9,
-            "cncjob_annotation_fontcolor": '#990000',
             "cncjob_tooldia": 0.0393701,
             "cncjob_tooldia": 0.0393701,
             "cncjob_coords_type": "G90",
             "cncjob_coords_type": "G90",
             "cncjob_coords_decimals": 4,
             "cncjob_coords_decimals": 4,
@@ -1039,7 +1042,10 @@ class App(QtCore.QObject):
             # CNC Job Advanced Options
             # CNC Job Advanced Options
             "cncjob_toolchange_macro": "",
             "cncjob_toolchange_macro": "",
             "cncjob_toolchange_macro_enable": False,
             "cncjob_toolchange_macro_enable": False,
+            "cncjob_annotation_fontsize": 9,
+            "cncjob_annotation_fontcolor": '#990000',
 
 
+            # NCC Tool
             "tools_ncctools": "0.0393701, 0.019685",
             "tools_ncctools": "0.0393701, 0.019685",
             "tools_nccorder": 'rev',
             "tools_nccorder": 'rev',
             "tools_nccoverlap": 0.015748,
             "tools_nccoverlap": 0.015748,
@@ -1058,6 +1064,7 @@ class App(QtCore.QObject):
             "tools_ncctipdia": 0.00393701,
             "tools_ncctipdia": 0.00393701,
             "tools_ncctipangle": 30,
             "tools_ncctipangle": 30,
 
 
+            # Cutout Tool
             "tools_cutouttooldia": 0.0944882,
             "tools_cutouttooldia": 0.0944882,
             "tools_cutoutkind": "single",
             "tools_cutoutkind": "single",
             "tools_cutoutmargin": 0.00393701,
             "tools_cutoutmargin": 0.00393701,
@@ -1065,6 +1072,7 @@ class App(QtCore.QObject):
             "tools_gaps_ff": "4",
             "tools_gaps_ff": "4",
             "tools_cutout_convexshape": False,
             "tools_cutout_convexshape": False,
 
 
+            # Paint Tool
             "tools_painttooldia": 0.023622,
             "tools_painttooldia": 0.023622,
             "tools_paintorder": 'rev',
             "tools_paintorder": 'rev',
             "tools_paintoverlap": 0.015748,
             "tools_paintoverlap": 0.015748,
@@ -1075,14 +1083,18 @@ class App(QtCore.QObject):
             "tools_paintcontour": True,
             "tools_paintcontour": True,
             "tools_paint_plotting": 'normal',
             "tools_paint_plotting": 'normal',
 
 
+            # 2-Sided Tool
             "tools_2sided_mirror_axis": "X",
             "tools_2sided_mirror_axis": "X",
             "tools_2sided_axis_loc": "point",
             "tools_2sided_axis_loc": "point",
             "tools_2sided_drilldia": 0.0393701,
             "tools_2sided_drilldia": 0.0393701,
 
 
+            # Film Tool
             "tools_film_type": 'neg',
             "tools_film_type": 'neg',
             "tools_film_boundary": 0.0393701,
             "tools_film_boundary": 0.0393701,
             "tools_film_scale": 0,
             "tools_film_scale": 0,
+            "tools_film_color": '#000000',
 
 
+            # Panel Tool
             "tools_panelize_spacing_columns": 0,
             "tools_panelize_spacing_columns": 0,
             "tools_panelize_spacing_rows": 0,
             "tools_panelize_spacing_rows": 0,
             "tools_panelize_columns": 1,
             "tools_panelize_columns": 1,
@@ -1092,6 +1104,7 @@ class App(QtCore.QObject):
             "tools_panelize_constrainy": 0.0,
             "tools_panelize_constrainy": 0.0,
             "tools_panelize_panel_type": 'gerber',
             "tools_panelize_panel_type": 'gerber',
 
 
+            # Calculators Tool
             "tools_calc_vshape_tip_dia": 0.007874,
             "tools_calc_vshape_tip_dia": 0.007874,
             "tools_calc_vshape_tip_angle": 30,
             "tools_calc_vshape_tip_angle": 30,
             "tools_calc_vshape_cut_z": 0.000787,
             "tools_calc_vshape_cut_z": 0.000787,
@@ -1100,6 +1113,7 @@ class App(QtCore.QObject):
             "tools_calc_electro_cdensity": 13.0,
             "tools_calc_electro_cdensity": 13.0,
             "tools_calc_electro_growth": 10.0,
             "tools_calc_electro_growth": 10.0,
 
 
+            # Transform Tool
             "tools_transform_rotate": 90,
             "tools_transform_rotate": 90,
             "tools_transform_skew_x": 0.0,
             "tools_transform_skew_x": 0.0,
             "tools_transform_skew_y": 0.0,
             "tools_transform_skew_y": 0.0,
@@ -1112,6 +1126,7 @@ class App(QtCore.QObject):
             "tools_transform_mirror_reference": False,
             "tools_transform_mirror_reference": False,
             "tools_transform_mirror_point": (0, 0),
             "tools_transform_mirror_point": (0, 0),
 
 
+            # SolderPaste Tool
             "tools_solderpaste_tools": "0.0393701, 0.011811",
             "tools_solderpaste_tools": "0.0393701, 0.011811",
             "tools_solderpaste_new": 0.011811,
             "tools_solderpaste_new": 0.011811,
             "tools_solderpaste_z_start": 0.00019685039,
             "tools_solderpaste_z_start": 0.00019685039,
@@ -1129,6 +1144,7 @@ class App(QtCore.QObject):
             "tools_solderpaste_dwellrev": 1,
             "tools_solderpaste_dwellrev": 1,
             "tools_solderpaste_pp": 'Paste_1',
             "tools_solderpaste_pp": 'Paste_1',
 
 
+            # Subtract Tool
             "tools_sub_close_paths": True,
             "tools_sub_close_paths": True,
 
 
             # file associations
             # file associations
@@ -1218,9 +1234,9 @@ class App(QtCore.QObject):
 
 
             "excellon_drillz": self.ui.excellon_options_form.excellon_opt_group.cutz_entry,
             "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_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_feedrate": self.ui.excellon_options_form.excellon_opt_group.feedrate_entry,
             "excellon_spindlespeed": self.ui.excellon_options_form.excellon_opt_group.spindlespeed_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_dwell": self.ui.excellon_options_form.excellon_opt_group.dwell_cb,
             "excellon_dwelltime": self.ui.excellon_options_form.excellon_opt_group.dwelltime_entry,
             "excellon_dwelltime": self.ui.excellon_options_form.excellon_opt_group.dwelltime_entry,
             "excellon_toolchange": self.ui.excellon_options_form.excellon_opt_group.toolchange_cb,
             "excellon_toolchange": self.ui.excellon_options_form.excellon_opt_group.toolchange_cb,
@@ -1232,7 +1248,7 @@ class App(QtCore.QObject):
             "excellon_toolchangexy": self.ui.excellon_options_form.excellon_adv_opt_group.toolchangexy_entry,
             "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_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_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_plot": self.ui.geometry_options_form.geometry_gen_group.plot_cb,
             "geometry_cnctooldia": self.ui.geometry_options_form.geometry_gen_group.cnctooldia_entry,
             "geometry_cnctooldia": self.ui.geometry_options_form.geometry_gen_group.cnctooldia_entry,
@@ -1242,12 +1258,12 @@ class App(QtCore.QObject):
             "geometry_feedrate": self.ui.geometry_options_form.geometry_opt_group.cncfeedrate_entry,
             "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_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_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_dwell": self.ui.geometry_options_form.geometry_opt_group.dwell_cb,
             "geometry_dwelltime": self.ui.geometry_options_form.geometry_opt_group.dwelltime_entry,
             "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_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_toolchange": self.ui.geometry_options_form.geometry_opt_group.toolchange_cb,
             "geometry_toolchangez": self.ui.geometry_options_form.geometry_opt_group.toolchangez_entry,
             "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_depthperpass": self.ui.geometry_options_form.geometry_opt_group.depthperpass_entry,
             "geometry_multidepth": self.ui.geometry_options_form.geometry_opt_group.multidepth_cb,
             "geometry_multidepth": self.ui.geometry_options_form.geometry_opt_group.multidepth_cb,
 
 
@@ -1255,9 +1271,9 @@ class App(QtCore.QObject):
             "geometry_segy": self.ui.geometry_options_form.geometry_adv_opt_group.segy_entry,
             "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_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_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_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_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,
             "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,
             "cncjob_plot": self.ui.cncjob_options_form.cncjob_gen_group.plot_cb,
@@ -1501,10 +1517,17 @@ class App(QtCore.QObject):
             "background-color:%s" % str(self.defaults['global_proj_item_dis_color'])[:7])
             "background-color:%s" % str(self.defaults['global_proj_item_dis_color'])[:7])
 
 
         # Init the Annotation CNC Job color
         # 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.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])
             "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 ####
         # ### End of Data ####
 
 
         # ###############################################
         # ###############################################
@@ -1685,6 +1708,9 @@ class App(QtCore.QObject):
         self.ui.menuhelp_about.triggered.connect(self.on_about)
         self.ui.menuhelp_about.triggered.connect(self.on_about)
         self.ui.menuhelp_home.triggered.connect(lambda: webbrowser.open(self.app_url))
         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_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_videohelp.triggered.connect(lambda: webbrowser.open(self.video_url))
         self.ui.menuhelp_shortcut_list.triggered.connect(self.on_shortcut_list)
         self.ui.menuhelp_shortcut_list.triggered.connect(self.on_shortcut_list)
 
 
@@ -1823,11 +1849,17 @@ class App(QtCore.QObject):
         # ########## CNC Job related signals #############
         # ########## CNC Job related signals #############
         self.ui.cncjob_defaults_form.cncjob_adv_opt_group.tc_variable_combo.currentIndexChanged[str].connect(
         self.ui.cncjob_defaults_form.cncjob_adv_opt_group.tc_variable_combo.currentIndexChanged[str].connect(
             self.on_cnc_custom_parameters)
             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.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)
             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 ###########
         # ########## Modify G-CODE Plot Area TAB ###########
         self.ui.code_editor.textChanged.connect(self.handleTextChanged)
         self.ui.code_editor.textChanged.connect(self.handleTextChanged)
         self.ui.buttonOpen.clicked.connect(self.handleOpen)
         self.ui.buttonOpen.clicked.connect(self.handleOpen)
@@ -1844,7 +1876,7 @@ class App(QtCore.QObject):
         self.collection.view.activated.connect(self.on_row_activated)
         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
         # 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
         # Make sure that when the Excellon loading parameters are changed, the change is reflected in the
         # Export Excellon parameters.
         # Export Excellon parameters.
@@ -5558,8 +5590,8 @@ class App(QtCore.QObject):
 
 
     def on_annotation_fontcolor_entry(self):
     def on_annotation_fontcolor_entry(self):
         self.defaults['cncjob_annotation_fontcolor'] = \
         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']))
             "background-color:%s" % str(self.defaults['cncjob_annotation_fontcolor']))
 
 
     def on_annotation_fontcolor_button(self):
     def on_annotation_fontcolor_button(self):
@@ -5571,12 +5603,38 @@ class App(QtCore.QObject):
         if annotation_color.isValid() is False:
         if annotation_color.isValid() is False:
             return
             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()))
             "background-color:%s" % str(annotation_color.name()))
 
 
         new_val_sel = 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):
     def on_splash_changed(self, state):
         settings = QSettings("Open Source", "FlatCAM")
         settings = QSettings("Open Source", "FlatCAM")
@@ -8584,8 +8642,6 @@ class App(QtCore.QObject):
         def make_negative_film():
         def make_negative_film():
             exported_svg = obj.export_svg(scale_factor=scale_factor)
             exported_svg = obj.export_svg(scale_factor=scale_factor)
 
 
-            self.progress.emit(40)
-
             # Determine bounding area for svg export
             # Determine bounding area for svg export
             bounds = box.bounds()
             bounds = box.bounds()
             size = box.size()
             size = box.size()
@@ -8611,8 +8667,6 @@ class App(QtCore.QObject):
             svg_header += '<g transform="scale(1,-1)">'
             svg_header += '<g transform="scale(1,-1)">'
             svg_footer = '</g> </svg>'
             svg_footer = '</g> </svg>'
 
 
-            self.progress.emit(60)
-
             # Change the attributes of the exported SVG
             # Change the attributes of the exported SVG
             # We don't need stroke-width - wrong, we do when we have lines with certain width
             # We don't need stroke-width - wrong, we do when we have lines with certain width
             # We set opacity to maximum
             # We set opacity to maximum
@@ -8641,7 +8695,6 @@ class App(QtCore.QObject):
             exported_svg = ET.tostring(root)
             exported_svg = ET.tostring(root)
 
 
             svg_elem = svg_header + str(exported_svg) + svg_footer
             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
             # Parse the xml through a xml parser just to add line feeds
             # and to make it look more pretty for the output
             # and to make it look more pretty for the output
@@ -8655,7 +8708,6 @@ class App(QtCore.QObject):
                                    "Most likely another app is holding the file open and not accessible."))
                                    "Most likely another app is holding the file open and not accessible."))
                 return 'fail'
                 return 'fail'
 
 
-            self.progress.emit(100)
             if self.defaults["global_open_style"] is False:
             if self.defaults["global_open_style"] is False:
                 self.file_opened.emit("SVG", filename)
                 self.file_opened.emit("SVG", filename)
             self.file_saved.emit("SVG", filename)
             self.file_saved.emit("SVG", filename)
@@ -8677,7 +8729,7 @@ class App(QtCore.QObject):
         else:
         else:
             make_negative_film()
             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.
         Exports a Geometry Object to an SVG file in positive black.
 
 
@@ -8688,7 +8740,7 @@ class App(QtCore.QObject):
         :param use_thread: if to be run in a separate thread; boolean
         :param use_thread: if to be run in a separate thread; boolean
         :return:
         :return:
         """
         """
-        self.report_usage("export_svg_black()")
+        self.report_usage("export_svg_positive()")
 
 
         if filename is None:
         if filename is None:
             filename = self.defaults["global_last_save_folder"]
             filename = self.defaults["global_last_save_folder"]
@@ -8712,7 +8764,7 @@ class App(QtCore.QObject):
                              (_("No object Box. Using instead"), obj))
                              (_("No object Box. Using instead"), obj))
             box = obj
             box = obj
 
 
-        def make_black_film():
+        def make_positive_film():
             exported_svg = obj.export_svg(scale_factor=scale_factor)
             exported_svg = obj.export_svg(scale_factor=scale_factor)
 
 
             self.progress.emit(40)
             self.progress.emit(40)
@@ -8723,9 +8775,9 @@ class App(QtCore.QObject):
             # We set the colour to WHITE
             # We set the colour to WHITE
             root = ET.fromstring(exported_svg)
             root = ET.fromstring(exported_svg)
             for child in root:
             for child in root:
-                child.set('fill', '#000000')
+                child.set('fill', str(self.defaults['tools_film_color']))
                 child.set('opacity', '1.0')
                 child.set('opacity', '1.0')
-                child.set('stroke', '#000000')
+                child.set('stroke', str(self.defaults['tools_film_color']))
 
 
             exported_svg = ET.tostring(root)
             exported_svg = ET.tostring(root)
 
 
@@ -8793,7 +8845,7 @@ class App(QtCore.QObject):
 
 
             def job_thread_film(app_obj):
             def job_thread_film(app_obj):
                 try:
                 try:
-                    make_black_film()
+                    make_positive_film()
                 except Exception as e:
                 except Exception as e:
                     proc.done()
                     proc.done()
                     return
                     return
@@ -8801,7 +8853,7 @@ class App(QtCore.QObject):
 
 
             self.worker_task.emit({'fcn': job_thread_film, 'params': [self]})
             self.worker_task.emit({'fcn': job_thread_film, 'params': [self]})
         else:
         else:
-            make_black_film()
+            make_positive_film()
 
 
     def save_source_file(self, obj_name, filename, use_thread=True):
     def save_source_file(self, obj_name, filename, use_thread=True):
         """
         """

+ 14 - 16
FlatCAMObj.py

@@ -600,7 +600,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
         # Show/Hide Advanced Options
         # Show/Hide Advanced Options
         if self.app.defaults["global_app_level"] == 'b':
         if self.app.defaults["global_app_level"] == 'b':
             self.ui.level.setText(_(
             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.apertures_table_label.hide()
             self.ui.aperture_table_visibility_cb.hide()
             self.ui.aperture_table_visibility_cb.hide()
@@ -613,7 +613,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
             self.ui.except_cb.hide()
             self.ui.except_cb.hide()
         else:
         else:
             self.ui.level.setText(_(
             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':
         if self.app.defaults["gerber_buffering"] == 'no':
@@ -2325,14 +2325,12 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
         # Show/Hide Advanced Options
         # Show/Hide Advanced Options
         if self.app.defaults["global_app_level"] == 'b':
         if self.app.defaults["global_app_level"] == 'b':
             self.ui.level.setText(_(
             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.tools_table.setColumnHidden(4, True)
             self.ui.estartz_label.hide()
             self.ui.estartz_label.hide()
             self.ui.estartz_entry.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_label.hide()
             self.ui.feedrate_rapid_entry.hide()
             self.ui.feedrate_rapid_entry.hide()
             self.ui.pdepth_label.hide()
             self.ui.pdepth_label.hide()
@@ -2341,7 +2339,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
             self.ui.feedrate_probe_entry.hide()
             self.ui.feedrate_probe_entry.hide()
         else:
         else:
             self.ui.level.setText(_(
             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), \
         assert isinstance(self.ui, ExcellonObjectUI), \
@@ -3605,7 +3603,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
         # Show/Hide Advanced Options
         # Show/Hide Advanced Options
         if self.app.defaults["global_app_level"] == 'b':
         if self.app.defaults["global_app_level"] == 'b':
             self.ui.level.setText(_(
             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)
             self.ui.geo_tools_table.setColumnHidden(2, True)
@@ -3616,8 +3614,8 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
             self.ui.addtool_btn.hide()
             self.ui.addtool_btn.hide()
             self.ui.copytool_btn.hide()
             self.ui.copytool_btn.hide()
             self.ui.deltool_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.fr_rapidlabel.hide()
             self.ui.cncfeedrate_rapid_entry.hide()
             self.ui.cncfeedrate_rapid_entry.hide()
             self.ui.extracut_cb.hide()
             self.ui.extracut_cb.hide()
@@ -3627,7 +3625,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
             self.ui.feedrate_probe_entry.hide()
             self.ui.feedrate_probe_entry.hide()
         else:
         else:
             self.ui.level.setText(_(
             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.plot_cb.stateChanged.connect(self.on_plot_cb_click)
         self.ui.generate_cnc_button.clicked.connect(self.on_generatecnc_button_click)
         self.ui.generate_cnc_button.clicked.connect(self.on_generatecnc_button_click)
@@ -4908,14 +4906,14 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
 
 
     def generatecncjob(
     def generatecncjob(
             self, outname=None,
             self, outname=None,
-            tooldia=None, offset=None,
+            dia=None, offset=None,
             z_cut=None, z_move=None,
             z_cut=None, z_move=None,
             feedrate=None, feedrate_z=None, feedrate_rapid=None,
             feedrate=None, feedrate_z=None, feedrate_rapid=None,
             spindlespeed=None, dwell=None, dwelltime=None,
             spindlespeed=None, dwell=None, dwelltime=None,
             multidepth=None, depthperpass=None,
             multidepth=None, depthperpass=None,
             toolchange=None, toolchangez=None, toolchangexy=None,
             toolchange=None, toolchangez=None, toolchangexy=None,
             extracut=None, startz=None, endz=None,
             extracut=None, startz=None, endz=None,
-            ppname_g=None,
+            pp=None,
             segx=None, segy=None,
             segx=None, segy=None,
             use_thread=True,
             use_thread=True,
             plot=True):
             plot=True):
@@ -4930,14 +4928,14 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
         :param feedrate: Feed rate while cutting on X - Y plane
         :param feedrate: Feed rate while cutting on X - Y plane
         :param feedrate_z: Feed rate while cutting on Z plane
         :param feedrate_z: Feed rate while cutting on Z plane
         :param feedrate_rapid: Feed rate while moving with rapids
         :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 outname: Name of the new object
         :param spindlespeed: Spindle speed (RPM)
         :param spindlespeed: Spindle speed (RPM)
-        :param ppname_g Name of the postprocessor
+        :param pp Name of the postprocessor
         :return: None
         :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"]
         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"])
         z_cut = z_cut if z_cut is not None else float(self.options["cutz"])
@@ -4968,7 +4966,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
         dwell = dwell if dwell else self.options["dwell"]
         dwell = dwell if dwell else self.options["dwell"]
         dwelltime = dwelltime if dwelltime else float(self.options["dwelltime"])
         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()
         # Object initialization function for app.new_object()
         # RUNNING ON SEPARATE THREAD!
         # RUNNING ON SEPARATE THREAD!

+ 6 - 0
README.md

@@ -14,6 +14,12 @@ CAD program, and create G-Code for Isolation routing.
 - 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)
 - 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
 - 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
 - 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
 15.09.2019
 
 

+ 34 - 20
camlib.py

@@ -5685,10 +5685,11 @@ class CNCjob(Geometry):
             must_visit.remove(nearest)
             must_visit.remove(nearest)
         return path
         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
         Creates gcode for this object from an Excellon object
         for the specified tools.
         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.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:
             if self.dwell is True:
                 self.gcode += self.doformat(p.dwell_code)   # Dwell time
                 self.gcode += self.doformat(p.dwell_code)   # Dwell time
         else:
         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:
             if self.dwell is True:
                 self.gcode += self.doformat(p.dwell_code)   # Dwell time
                 self.gcode += self.doformat(p.dwell_code)   # Dwell time
 
 
@@ -6589,15 +6597,16 @@ class CNCjob(Geometry):
                              )
                              )
         return self.gcode
         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.
         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.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:
             if self.dwell is True:
                 self.gcode += self.doformat(p.dwell_code)   # Dwell time
                 self.gcode += self.doformat(p.dwell_code)   # Dwell time
-
         else:
         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:
             if self.dwell is True:
                 self.gcode += self.doformat(p.dwell_code)   # Dwell time
                 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)
             match_lsr_pos = re.search(r"^(M0[3|5])", gline)
             if match_lsr_pos:
             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,
                     # 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)
                     # therefore the move is of kind T (travel)
                     command['Z'] = 1
                     command['Z'] = 1
@@ -7316,7 +7330,7 @@ class CNCjob(Geometry):
                     pass
                     pass
                 elif 'hpgl' in self.pp_excellon_name or 'hpgl' in self.pp_geometry_name:
                 elif 'hpgl' in self.pp_excellon_name or 'hpgl' in self.pp_geometry_name:
                     pass
                     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
                     pass
                 elif ('X' in gobj or 'Y' in gobj) and gobj['Z'] != current['Z']:
                 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':
                     if self.pp_geometry_name == 'line_xyz' or self.pp_excellon_name == 'line_xyz':

+ 302 - 237
flatcamGUI/FlatCAMGUI.py

@@ -400,6 +400,15 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
         self.menuhelp_manual = self.menuhelp.addAction(QtGui.QIcon('share/globe16.png'), _('Online Help\tF1'))
         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_home = self.menuhelp.addAction(QtGui.QIcon('share/home16.png'), _('FlatCAM.org'))
         self.menuhelp.addSeparator()
         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'),
         self.menuhelp_shortcut_list = self.menuhelp.addAction(QtGui.QIcon('share/shortcuts24.png'),
                                                               _('Shortcuts List\tF3'))
                                                               _('Shortcuts List\tF3'))
         self.menuhelp_videohelp = self.menuhelp.addAction(QtGui.QIcon('share/youtube32.png'), _('YouTube Channel\tF4')
         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):
     def eventFilter(self, obj, event):
         # filter the ToolTips display based on a Preferences setting
         # 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:
             if event.type() == QtCore.QEvent.ToolTip:
                 return True
                 return True
             else:
             else:
@@ -4026,6 +4035,7 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
         )
         )
         self.selection_cb = FCCheckBox()
         self.selection_cb = FCCheckBox()
 
 
+        # Notebook Font Size
         self.notebook_font_size_label = QtWidgets.QLabel('%s:' % _('NB Font Size'))
         self.notebook_font_size_label = QtWidgets.QLabel('%s:' % _('NB Font Size'))
         self.notebook_font_size_label.setToolTip(
         self.notebook_font_size_label.setToolTip(
             _("This sets the font size for the elements found in the Notebook.\n"
             _("This sets the font size for the elements found in the Notebook.\n"
@@ -4074,6 +4084,56 @@ class GeneralGUISetGroupUI(OptionsGroupUI):
         else:
         else:
             self.splash_cb.set_value(False)
             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
         # Add (label - input field) pair to the QFormLayout
         self.form_box.addRow(self.spacelabel, self.spacelabel)
         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(self.axis_font_size_label, self.axis_font_size_spinner)
         self.form_box.addRow(QtWidgets.QLabel(''))
         self.form_box.addRow(QtWidgets.QLabel(''))
         self.form_box.addRow(self.splash_label, self.splash_cb)
         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
         # Add the QFormLayout that holds the Application general defaults
         # to the main layout of this TAB
         # to the main layout of this TAB
         self.layout.addLayout(self.form_box)
         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):
     def handle_style(self, style):
         # set current style
         # set current style
         settings = QSettings("Open Source", "FlatCAM")
         settings = QSettings("Open Source", "FlatCAM")
@@ -4141,7 +4217,7 @@ class GeneralAppPrefGroupUI(OptionsGroupUI):
         self.form_box = QtWidgets.QFormLayout()
         self.form_box = QtWidgets.QFormLayout()
 
 
         # Units for FlatCAM
         # 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"
         self.unitslabel.setToolTip(_("The default value for FlatCAM units.\n"
                                      "Whatever is selected here is set every time\n"
                                      "Whatever is selected here is set every time\n"
                                      "FLatCAM is started."))
                                      "FLatCAM is started."))
@@ -4180,18 +4256,6 @@ class GeneralAppPrefGroupUI(OptionsGroupUI):
                                              "security features. In this case the language will be\n"
                                              "security features. In this case the language will be\n"
                                              "applied at the next app start."))
                                              "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
         # Version Check CB
         self.version_check_label = QtWidgets.QLabel('%s:' % _('Version Check'))
         self.version_check_label = QtWidgets.QLabel('%s:' % _('Version Check'))
         self.version_check_label.setToolTip(
         self.version_check_label.setToolTip(
@@ -4232,43 +4296,7 @@ class GeneralAppPrefGroupUI(OptionsGroupUI):
         self.mselect_radio = RadioSet([{'label': _('CTRL'), 'value': 'Control'},
         self.mselect_radio = RadioSet([{'label': _('CTRL'), 'value': 'Control'},
                                        {'label': _('SHIFT'), 'value': 'Shift'}])
                                        {'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 = QtWidgets.QLabel('%s:' % _('Workers number'))
         self.worker_number_label.setToolTip(
         self.worker_number_label.setToolTip(
             _("The number of Qthreads made available to the App.\n"
             _("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.languagespace, self.language_apply_btn)
 
 
         self.form_box.addRow(self.spacelabel, self.spacelabel)
         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.version_check_label, self.version_check_cb)
         self.form_box.addRow(self.send_stats_label, self.send_stats_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.panbuttonlabel, self.pan_button_radio)
         self.form_box.addRow(self.mselectlabel, self.mselect_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(self.worker_number_label, self.worker_number_sb)
         self.form_box.addRow(tol_label, self.tol_entry)
         self.form_box.addRow(tol_label, self.tol_entry)
 
 
@@ -4350,15 +4374,6 @@ class GeneralAppPrefGroupUI(OptionsGroupUI):
         # self.advanced_cb.setLayoutDirection(QtCore.Qt.RightToLeft)
         # self.advanced_cb.setLayoutDirection(QtCore.Qt.RightToLeft)
         self.layout.addWidget(self.open_style_cb)
         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
         # Save compressed project CB
         self.save_type_cb = FCCheckBox(_('Save Compressed Project'))
         self.save_type_cb = FCCheckBox(_('Save Compressed Project'))
         self.save_type_cb.setToolTip(
         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_label, 1, 0)
         grid0.addWidget(self.circle_steps_entry, 1, 1)
         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()
         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.")
               "A value here of 0.25 means an overlap of 25%% from the tool diameter found above.")
         )
         )
         grid0.addWidget(overlabel, 2, 0)
         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)
         grid0.addWidget(self.iso_overlap_entry, 2, 1)
 
 
         # Milling Type
         # Milling Type
@@ -4615,7 +4600,7 @@ class GerberAdvOptPrefGroupUI(OptionsGroupUI):
         self.setTitle(str(_("Gerber Adv. Options")))
         self.setTitle(str(_("Gerber Adv. Options")))
 
 
         # ## Advanced Gerber Parameters
         # ## 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(
         self.adv_param_label.setToolTip(
             _("A list of Gerber advanced parameters.\n"
             _("A list of Gerber advanced parameters.\n"
               "Those parameters are available only for\n"
               "Those parameters are available only for\n"
@@ -4633,7 +4618,7 @@ class GerberAdvOptPrefGroupUI(OptionsGroupUI):
               "This means that it will cut through\n"
               "This means that it will cut through\n"
               "the middle of the trace.")
               "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
         # Aperture Table Visibility CB
         self.aperture_table_visibility_cb = FCCheckBox(label=_('Table Show/Hide'))
         self.aperture_table_visibility_cb = FCCheckBox(label=_('Table Show/Hide'))
@@ -4643,7 +4628,42 @@ class GerberAdvOptPrefGroupUI(OptionsGroupUI):
               "that are drawn on canvas.")
               "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
         # Scale Aperture Factor
         # self.scale_aperture_label = QtWidgets.QLabel(_('Ap. Scale Factor:'))
         # self.scale_aperture_label = QtWidgets.QLabel(_('Ap. Scale Factor:'))
@@ -5141,7 +5161,7 @@ class ExcellonGenPrefGroupUI(OptionsGroupUI):
         self.update_excellon_cb.setToolTip(
         self.update_excellon_cb.setToolTip(
             "If checked, the Excellon Export settings will be updated with the ones above."
             "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)
         grid2.addWidget(QtWidgets.QLabel(""), 3, 0)
 
 
@@ -5161,8 +5181,10 @@ class ExcellonGenPrefGroupUI(OptionsGroupUI):
         )
         )
         grid2.addWidget(self.excellon_optimization_label, 5, 0)
         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(
         self.excellon_optimization_radio.setToolTip(
             _("This sets the optimization type for the Excellon drill path.\n"
             _("This sets the optimization type for the Excellon drill path.\n"
               "If MH is checked then Google OR-Tools algorithm with MetaHeuristic\n"
               "If MH is checked then Google OR-Tools algorithm with MetaHeuristic\n"
@@ -5234,6 +5256,7 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI):
         grid2 = QtWidgets.QGridLayout()
         grid2 = QtWidgets.QGridLayout()
         self.layout.addLayout(grid2)
         self.layout.addLayout(grid2)
 
 
+        # Cut Z
         cutzlabel = QtWidgets.QLabel('%s:' % _('Cut Z'))
         cutzlabel = QtWidgets.QLabel('%s:' % _('Cut Z'))
         cutzlabel.setToolTip(
         cutzlabel.setToolTip(
             _("Drill depth (negative)\n"
             _("Drill depth (negative)\n"
@@ -5243,6 +5266,7 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI):
         self.cutz_entry = LengthEntry()
         self.cutz_entry = LengthEntry()
         grid2.addWidget(self.cutz_entry, 0, 1)
         grid2.addWidget(self.cutz_entry, 0, 1)
 
 
+        # Travel Z
         travelzlabel = QtWidgets.QLabel('%s:' % _('Travel Z'))
         travelzlabel = QtWidgets.QLabel('%s:' % _('Travel Z'))
         travelzlabel.setToolTip(
         travelzlabel.setToolTip(
             _("Tool height when travelling\n"
             _("Tool height when travelling\n"
@@ -5271,15 +5295,27 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI):
         self.toolchangez_entry = LengthEntry()
         self.toolchangez_entry = LengthEntry()
         grid2.addWidget(self.toolchangez_entry, 3, 1)
         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(
         frlabel.setToolTip(
             _("Tool speed while drilling\n"
             _("Tool speed while drilling\n"
               "(in units per minute).\n"
               "(in units per minute).\n"
+              "So called 'Plunge' feedrate.\n"
               "This is for linear move G01.")
               "This is for linear move G01.")
         )
         )
-        grid2.addWidget(frlabel, 4, 0)
+        grid2.addWidget(frlabel, 5, 0)
         self.feedrate_entry = LengthEntry()
         self.feedrate_entry = LengthEntry()
-        grid2.addWidget(self.feedrate_entry, 4, 1)
+        grid2.addWidget(self.feedrate_entry, 5, 1)
 
 
         # Spindle speed
         # Spindle speed
         spdlabel = QtWidgets.QLabel('%s:' % _('Spindle Speed'))
         spdlabel = QtWidgets.QLabel('%s:' % _('Spindle Speed'))
@@ -5287,23 +5323,9 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI):
             _("Speed of the spindle\n"
             _("Speed of the spindle\n"
               "in RPM (optional)")
               "in RPM (optional)")
         )
         )
-        grid2.addWidget(spdlabel, 5, 0)
+        grid2.addWidget(spdlabel, 6, 0)
         self.spindlespeed_entry = IntEntry(allow_empty=True)
         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
         # Dwell
         dwelllabel = QtWidgets.QLabel('%s:' % _('Dwell'))
         dwelllabel = QtWidgets.QLabel('%s:' % _('Dwell'))
@@ -5317,6 +5339,7 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI):
         )
         )
         self.dwell_cb = FCCheckBox()
         self.dwell_cb = FCCheckBox()
         self.dwelltime_entry = FCEntry()
         self.dwelltime_entry = FCEntry()
+
         grid2.addWidget(dwelllabel, 7, 0)
         grid2.addWidget(dwelllabel, 7, 0)
         grid2.addWidget(self.dwell_cb, 7, 1)
         grid2.addWidget(self.dwell_cb, 7, 1)
         grid2.addWidget(dwelltime, 8, 0)
         grid2.addWidget(dwelltime, 8, 0)
@@ -5358,7 +5381,7 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI):
         self.mill_hole_label.setToolTip(
         self.mill_hole_label.setToolTip(
             _("Create Geometry for milling holes.")
             _("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 = QtWidgets.QLabel('%s:' % _('Drill Tool dia'))
         tdlabel.setToolTip(
         tdlabel.setToolTip(
@@ -5400,12 +5423,13 @@ class ExcellonAdvOptPrefGroupUI(OptionsGroupUI):
         # ## ADVANCED OPTIONS ###
         # ## 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()
         grid1 = QtWidgets.QGridLayout()
         self.layout.addLayout(grid1)
         self.layout.addLayout(grid1)
@@ -5436,15 +5460,7 @@ class ExcellonAdvOptPrefGroupUI(OptionsGroupUI):
         self.estartz_entry = FloatEntry()
         self.estartz_entry = FloatEntry()
         grid1.addWidget(self.estartz_entry, 2, 1)
         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 = QtWidgets.QLabel('%s:' % _('Feedrate Rapids'))
         fr_rapid_label.setToolTip(
         fr_rapid_label.setToolTip(
             _("Tool speed while drilling\n"
             _("Tool speed while drilling\n"
@@ -5453,9 +5469,9 @@ class ExcellonAdvOptPrefGroupUI(OptionsGroupUI):
               "It is useful only for Marlin,\n"
               "It is useful only for Marlin,\n"
               "ignore for any other cases.")
               "ignore for any other cases.")
         )
         )
-        grid1.addWidget(fr_rapid_label, 4, 0)
+        grid1.addWidget(fr_rapid_label, 3, 0)
         self.feedrate_rapid_entry = LengthEntry()
         self.feedrate_rapid_entry = LengthEntry()
-        grid1.addWidget(self.feedrate_rapid_entry, 4, 1)
+        grid1.addWidget(self.feedrate_rapid_entry, 3, 1)
 
 
         # Probe depth
         # Probe depth
         self.pdepth_label = QtWidgets.QLabel('%s:' % _("Probe Z 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"
             _("The maximum depth that the probe is allowed\n"
               "to probe. Negative value, in current units.")
               "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()
         self.pdepth_entry = FCEntry()
-        grid1.addWidget(self.pdepth_entry, 5, 1)
+        grid1.addWidget(self.pdepth_entry, 4, 1)
 
 
         # Probe feedrate
         # Probe feedrate
         self.feedrate_probe_label = QtWidgets.QLabel('%s:' % _("Feedrate Probe"))
         self.feedrate_probe_label = QtWidgets.QLabel('%s:' % _("Feedrate Probe"))
         self.feedrate_probe_label.setToolTip(
         self.feedrate_probe_label.setToolTip(
            _("The feedrate used while the probe is probing.")
            _("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()
         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 = QtWidgets.QLabel('%s:' % _('Fast Plunge'))
         fplungelabel.setToolTip(
         fplungelabel.setToolTip(
@@ -6048,15 +6078,25 @@ class GeometryOptPrefGroupUI(OptionsGroupUI):
         self.toolchangez_entry = LengthEntry()
         self.toolchangez_entry = LengthEntry()
         grid1.addWidget(self.toolchangez_entry, 5, 1)
         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
         # Feedrate X-Y
         frlabel = QtWidgets.QLabel('%s:' % _('Feed Rate X-Y'))
         frlabel = QtWidgets.QLabel('%s:' % _('Feed Rate X-Y'))
         frlabel.setToolTip(
         frlabel.setToolTip(
             _("Cutting speed in the XY\n"
             _("Cutting speed in the XY\n"
               "plane in units per minute")
               "plane in units per minute")
         )
         )
-        grid1.addWidget(frlabel, 6, 0)
+        grid1.addWidget(frlabel, 7, 0)
         self.cncfeedrate_entry = LengthEntry()
         self.cncfeedrate_entry = LengthEntry()
-        grid1.addWidget(self.cncfeedrate_entry, 6, 1)
+        grid1.addWidget(self.cncfeedrate_entry, 7, 1)
 
 
         # Feedrate Z (Plunge)
         # Feedrate Z (Plunge)
         frz_label = QtWidgets.QLabel('%s:' % _('Feed Rate Z'))
         frz_label = QtWidgets.QLabel('%s:' % _('Feed Rate Z'))
@@ -6065,9 +6105,9 @@ class GeometryOptPrefGroupUI(OptionsGroupUI):
               "plane in units per minute.\n"
               "plane in units per minute.\n"
               "It is called also Plunge.")
               "It is called also Plunge.")
         )
         )
-        grid1.addWidget(frz_label, 7, 0)
+        grid1.addWidget(frz_label, 8, 0)
         self.cncplunge_entry = LengthEntry()
         self.cncplunge_entry = LengthEntry()
-        grid1.addWidget(self.cncplunge_entry, 7, 1)
+        grid1.addWidget(self.cncplunge_entry, 8, 1)
 
 
         # Spindle Speed
         # Spindle Speed
         spdlabel = QtWidgets.QLabel('%s:' % _('Spindle speed'))
         spdlabel = QtWidgets.QLabel('%s:' % _('Spindle speed'))
@@ -6078,23 +6118,9 @@ class GeometryOptPrefGroupUI(OptionsGroupUI):
                 "this value is the power of laser."
                 "this value is the power of laser."
             )
             )
         )
         )
-        grid1.addWidget(spdlabel, 8, 0)
+        grid1.addWidget(spdlabel, 9, 0)
         self.cncspindlespeed_entry = IntEntry(allow_empty=True)
         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
         # Dwell
         self.dwell_cb = FCCheckBox(label='%s:' % _('Dwell'))
         self.dwell_cb = FCCheckBox(label='%s:' % _('Dwell'))
@@ -6137,12 +6163,13 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
         # ------------------------------
         # ------------------------------
         # ## Advanced Options
         # ## 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()
         grid1 = QtWidgets.QGridLayout()
         self.layout.addLayout(grid1)
         self.layout.addLayout(grid1)
@@ -6166,16 +6193,6 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
         self.gstartz_entry = FloatEntry()
         self.gstartz_entry = FloatEntry()
         grid1.addWidget(self.gstartz_entry, 2, 1)
         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
         # Feedrate rapids
         fr_rapid_label = QtWidgets.QLabel('%s:' % _('Feed Rate Rapids'))
         fr_rapid_label = QtWidgets.QLabel('%s:' % _('Feed Rate Rapids'))
         fr_rapid_label.setToolTip(
         fr_rapid_label.setToolTip(
@@ -6218,6 +6235,20 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
         self.feedrate_probe_entry = FCEntry()
         self.feedrate_probe_entry = FCEntry()
         grid1.addWidget(self.feedrate_probe_entry, 7, 1)
         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
         # Fast Move from Z Toolchange
         fplungelabel = QtWidgets.QLabel('%s:' % _('Fast Plunge'))
         fplungelabel = QtWidgets.QLabel('%s:' % _('Fast Plunge'))
         fplungelabel.setToolTip(
         fplungelabel.setToolTip(
@@ -6227,8 +6258,8 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
               "WARNING: the move is done at Toolchange X,Y coords.")
               "WARNING: the move is done at Toolchange X,Y coords.")
         )
         )
         self.fplunge_cb = FCCheckBox()
         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
         # Size of trace segment on X axis
         segx_label = QtWidgets.QLabel('%s:' % _("Seg. X size"))
         segx_label = QtWidgets.QLabel('%s:' % _("Seg. X size"))
@@ -6237,9 +6268,9 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
               "Useful for auto-leveling.\n"
               "Useful for auto-leveling.\n"
               "A value of 0 means no segmentation on the X axis.")
               "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()
         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
         # Size of trace segment on Y axis
         segy_label = QtWidgets.QLabel('%s:' % _("Seg. Y size"))
         segy_label = QtWidgets.QLabel('%s:' % _("Seg. Y size"))
@@ -6248,9 +6279,9 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
               "Useful for auto-leveling.\n"
               "Useful for auto-leveling.\n"
               "A value of 0 means no segmentation on the Y axis.")
               "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()
         self.segy_entry = FCEntry()
-        grid1.addWidget(self.segy_entry, 10, 1)
+        grid1.addWidget(self.segy_entry, 11, 1)
 
 
         self.layout.addStretch()
         self.layout.addStretch()
 
 
@@ -6344,37 +6375,6 @@ class CNCJobGenPrefGroupUI(OptionsGroupUI):
         grid0.addWidget(self.annotation_cb, 2, 1)
         grid0.addWidget(self.annotation_cb, 2, 1)
         grid0.addWidget(QtWidgets.QLabel(''), 2, 2)
         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 #
         # 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"
             _("The number of circle steps for <b>GCode</b> \n"
               "circle and arc shapes linear approximation.")
               "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()
         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
         # Tool dia for plot
         tdlabel = QtWidgets.QLabel('%s:' % _('Travel dia'))
         tdlabel = QtWidgets.QLabel('%s:' % _('Travel dia'))
@@ -6394,11 +6394,11 @@ class CNCJobGenPrefGroupUI(OptionsGroupUI):
               "rendered in the plot.")
               "rendered in the plot.")
         )
         )
         self.tooldia_entry = LengthEntry()
         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
         # add a space
-        grid0.addWidget(QtWidgets.QLabel(''), 7, 0)
+        grid0.addWidget(QtWidgets.QLabel(''), 5, 0)
 
 
         # Number of decimals to use in GCODE coordinates
         # Number of decimals to use in GCODE coordinates
         cdeclabel = QtWidgets.QLabel('%s:' % _('Coordinates decimals'))
         cdeclabel = QtWidgets.QLabel('%s:' % _('Coordinates decimals'))
@@ -6407,8 +6407,8 @@ class CNCJobGenPrefGroupUI(OptionsGroupUI):
               "the X, Y, Z coordinates in CNC code (GCODE, etc.)")
               "the X, Y, Z coordinates in CNC code (GCODE, etc.)")
         )
         )
         self.coords_dec_entry = IntEntry()
         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
         # Number of decimals to use in GCODE feedrate
         frdeclabel = QtWidgets.QLabel('%s:' % _('Feedrate decimals'))
         frdeclabel = QtWidgets.QLabel('%s:' % _('Feedrate decimals'))
@@ -6417,8 +6417,8 @@ class CNCJobGenPrefGroupUI(OptionsGroupUI):
               "the Feedrate parameter in CNC code (GCODE, etc.)")
               "the Feedrate parameter in CNC code (GCODE, etc.)")
         )
         )
         self.fr_dec_entry = IntEntry()
         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
         # The type of coordinates used in the Gcode: Absolute or Incremental
         coords_type_label = QtWidgets.QLabel('%s:' % _('Coordinates type'))
         coords_type_label = QtWidgets.QLabel('%s:' % _('Coordinates type'))
@@ -6432,8 +6432,8 @@ class CNCJobGenPrefGroupUI(OptionsGroupUI):
             {"label": _("Absolute G90"), "value": "G90"},
             {"label": _("Absolute G90"), "value": "G90"},
             {"label": _("Incremental G91"), "value": "G91"}
             {"label": _("Incremental G91"), "value": "G91"}
         ], orientation='vertical', stretch=False)
         ], 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
         # hidden for the time being, until implemented
         coords_type_label.hide()
         coords_type_label.hide()
@@ -6570,6 +6570,42 @@ class CNCJobAdvOptPrefGroupUI(OptionsGroupUI):
         # )
         # )
         # hlay1.addWidget(self.tc_insert_buton)
         # 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()
         self.layout.addStretch()
 
 
 
 
@@ -6705,8 +6741,12 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI):
              "Higher values = slow processing and slow execution on CNC\n"
              "Higher values = slow processing and slow execution on CNC\n"
              "due of too many paths.")
              "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)
         grid0.addWidget(nccoverlabel, 7, 0)
-        self.ncc_overlap_entry = FloatEntry()
         grid0.addWidget(self.ncc_overlap_entry, 7, 1)
         grid0.addWidget(self.ncc_overlap_entry, 7, 1)
 
 
         # Margin entry
         # Margin entry
@@ -7050,8 +7090,12 @@ class ToolsPaintPrefGroupUI(OptionsGroupUI):
               "Higher values = slow processing and slow execution on CNC\n"
               "Higher values = slow processing and slow execution on CNC\n"
               "due of too many paths.")
               "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)
         grid0.addWidget(ovlabel, 2, 0)
-        self.paintoverlap_entry = LengthEntry()
         grid0.addWidget(self.paintoverlap_entry, 2, 1)
         grid0.addWidget(self.paintoverlap_entry, 2, 1)
 
 
         # Margin
         # Margin
@@ -7167,6 +7211,26 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
         grid0.addWidget(ftypelbl, 0, 0)
         grid0.addWidget(ftypelbl, 0, 0)
         grid0.addWidget(self.film_type_radio, 0, 1)
         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_entry = FCEntry()
         self.film_boundary_label = QtWidgets.QLabel('%s:' % _("Border"))
         self.film_boundary_label = QtWidgets.QLabel('%s:' % _("Border"))
         self.film_boundary_label.setToolTip(
         self.film_boundary_label.setToolTip(
@@ -7179,8 +7243,8 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
               "white color like the rest and which may confound with the\n"
               "white color like the rest and which may confound with the\n"
               "surroundings if not for this border.")
               "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_entry = FCEntry()
         self.film_scale_label = QtWidgets.QLabel('%s:' % _("Scale Stroke"))
         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"
               "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.")
               "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()
         self.layout.addStretch()
 
 
@@ -7737,7 +7801,7 @@ class FAExcPrefGroupUI(OptionsGroupUI):
         self.layout.addWidget(self.exc_list_label)
         self.layout.addWidget(self.exc_list_label)
 
 
         self.exc_list_text = FCTextArea()
         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 = QtGui.QFont()
         font.setPointSize(12)
         font.setPointSize(12)
         self.exc_list_text.setFont(font)
         self.exc_list_text.setFont(font)
@@ -7770,7 +7834,7 @@ class FAGcoPrefGroupUI(OptionsGroupUI):
         self.layout.addWidget(self.gco_list_label)
         self.layout.addWidget(self.gco_list_label)
 
 
         self.gco_list_text = FCTextArea()
         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 = QtGui.QFont()
         font.setPointSize(12)
         font.setPointSize(12)
         self.gco_list_text.setFont(font)
         self.gco_list_text.setFont(font)
@@ -7803,7 +7867,7 @@ class FAGrbPrefGroupUI(OptionsGroupUI):
         self.layout.addWidget(self.grb_list_label)
         self.layout.addWidget(self.grb_list_label)
 
 
         self.grb_list_text = FCTextArea()
         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)
         self.layout.addWidget(self.grb_list_text)
         font = QtGui.QFont()
         font = QtGui.QFont()
         font.setPointSize(12)
         font.setPointSize(12)
@@ -7814,6 +7878,7 @@ class FAGrbPrefGroupUI(OptionsGroupUI):
                                        "FlatCAM and the files with above extensions.\n"
                                        "FlatCAM and the files with above extensions.\n"
                                        "They will be active after next logon.\n"
                                        "They will be active after next logon.\n"
                                        "This work only in Windows."))
                                        "This work only in Windows."))
+
         self.layout.addWidget(self.grb_list_btn)
         self.layout.addWidget(self.grb_list_btn)
 
 
         # self.layout.addStretch()
         # self.layout.addStretch()

+ 8 - 3
flatcamGUI/ObjectUI.py

@@ -292,7 +292,11 @@ class GerberObjectUI(ObjectUI):
               "A value here of 0.25 means an overlap of 25%% from the tool diameter found above.")
               "A value here of 0.25 means an overlap of 25%% from the tool diameter found above.")
         )
         )
         overlabel.setMinimumWidth(90)
         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(overlabel, 2, 0)
         grid1.addWidget(self.iso_overlap_entry, 2, 1, 1, 2)
         grid1.addWidget(self.iso_overlap_entry, 2, 1, 1, 2)
 
 
@@ -709,11 +713,12 @@ class ExcellonObjectUI(ObjectUI):
         self.eendz_entry = LengthEntry()
         self.eendz_entry = LengthEntry()
         grid1.addWidget(self.eendz_entry, 5, 1)
         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(
         frlabel.setToolTip(
             _("Tool speed while drilling\n"
             _("Tool speed while drilling\n"
               "(in units per minute).\n"
               "(in units per minute).\n"
+              "So called 'Plunge' feedrate.\n"
               "This is for linear move G01.")
               "This is for linear move G01.")
         )
         )
         grid1.addWidget(frlabel, 6, 0)
         grid1.addWidget(frlabel, 6, 0)

+ 1 - 1
flatcamTools/ToolFilm.py

@@ -274,7 +274,7 @@ class Film(FlatCAMTool):
                 self.app.inform.emit('[WARNING_NOTCL] %s' % _("Export SVG positive cancelled."))
                 self.app.inform.emit('[WARNING_NOTCL] %s' % _("Export SVG positive cancelled."))
                 return
                 return
             else:
             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:
         else:
             try:
             try:
                 filename, _f = QtWidgets.QFileDialog.getSaveFileName(
                 filename, _f = QtWidgets.QFileDialog.getSaveFileName(

+ 5 - 1
flatcamTools/ToolNonCopperClear.py

@@ -292,7 +292,11 @@ class NonCopperClear(FlatCAMTool, Gerber):
               "Higher values = slow processing and slow execution on CNC\n"
               "Higher values = slow processing and slow execution on CNC\n"
               "due of too many paths.")
               "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(nccoverlabel, 2, 0)
         grid3.addWidget(self.ncc_overlap_entry, 2, 1)
         grid3.addWidget(self.ncc_overlap_entry, 2, 1)
 
 

+ 5 - 1
flatcamTools/ToolPaint.py

@@ -214,8 +214,12 @@ class ToolPaint(FlatCAMTool, Gerber):
               "Higher values = slow processing and slow execution on CNC\n"
               "Higher values = slow processing and slow execution on CNC\n"
               "due of too many paths.")
               "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)
         grid3.addWidget(ovlabel, 1, 0)
-        self.paintoverlap_entry = FCEntry()
         grid3.addWidget(self.paintoverlap_entry, 1, 1)
         grid3.addWidget(self.paintoverlap_entry, 1, 1)
 
 
         # Margin
         # Margin

BIN
share/bug16.png


BIN
share/bug32.png


BIN
share/pdf_link16.png


+ 7 - 4
tclCommands/TclCommandCncjob.py

@@ -24,7 +24,7 @@ class TclCommandCncjob(TclCommandSignaled):
 
 
     # dictionary of types from Tcl command, needs to be ordered , this  is  for options  like -optionname value
     # dictionary of types from Tcl command, needs to be ordered , this  is  for options  like -optionname value
     option_types = collections.OrderedDict([
     option_types = collections.OrderedDict([
-        ('tooldia', float),
+        ('dia', float),
         ('z_cut', float),
         ('z_cut', float),
         ('z_move', float),
         ('z_move', float),
         ('feedrate', float),
         ('feedrate', float),
@@ -54,7 +54,7 @@ class TclCommandCncjob(TclCommandSignaled):
         'main': "Generates a CNC Job from a Geometry Object.",
         'main': "Generates a CNC Job from a Geometry Object.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
             ('name', 'Name of the source object.'),
             ('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_cut', 'Z-axis cutting position.'),
             ('z_move', 'Z-axis moving position.'),
             ('z_move', 'Z-axis moving position.'),
             ('feedrate', 'Moving speed on X-Y plane when cutting.'),
             ('feedrate', 'Moving speed on X-Y plane when cutting.'),
@@ -95,6 +95,8 @@ class TclCommandCncjob(TclCommandSignaled):
 
 
         if 'muted' in args:
         if 'muted' in args:
             muted = args['muted']
             muted = args['muted']
+        else:
+            muted = 0
 
 
         obj = self.app.collection.get_by_name(str(name), isCaseSensitive=False)
         obj = self.app.collection.get_by_name(str(name), isCaseSensitive=False)
 
 
@@ -110,7 +112,7 @@ class TclCommandCncjob(TclCommandSignaled):
             else:
             else:
                 return
                 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_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"]
         args["z_move"] = args["z_move"] if "z_move" in args else obj.options["travelz"]
@@ -141,10 +143,11 @@ class TclCommandCncjob(TclCommandSignaled):
         del args['name']
         del args['name']
 
 
         for arg in args:
         for arg in args:
-            if arg == "toolchange_xy" or arg == "spindlespeed":
+            if arg == "toolchange_xy" or arg == "spindlespeed" or arg == "startz":
                 continue
                 continue
             else:
             else:
                 if args[arg] is None:
                 if args[arg] is None:
+                    print(arg, args[arg])
                     if not muted:
                     if not muted:
                         self.raise_tcl_error('One of the command parameters that have to be not None, is None.\n'
                         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'
                                              'The parameter that is None is in the default values found in the list \n'

+ 2 - 1
tclCommands/TclCommandDrillcncjob.py

@@ -17,7 +17,6 @@ class TclCommandDrillcncjob(TclCommandSignaled):
 
 
     # dictionary of types from Tcl command, needs to be ordered , this  is  for options  like -optionname value
     # dictionary of types from Tcl command, needs to be ordered , this  is  for options  like -optionname value
     option_types = collections.OrderedDict([
     option_types = collections.OrderedDict([
-        ('tools', str),
         ('drilled_dias', str),
         ('drilled_dias', str),
         ('drillz', float),
         ('drillz', float),
         ('travelz', float),
         ('travelz', float),
@@ -88,6 +87,8 @@ class TclCommandDrillcncjob(TclCommandSignaled):
 
 
         if 'muted' in args:
         if 'muted' in args:
             muted = args['muted']
             muted = args['muted']
+        else:
+            muted = 0
 
 
         obj = self.app.collection.get_by_name(name)
         obj = self.app.collection.get_by_name(name)
         if obj is None:
         if obj is None:

+ 2 - 0
tclCommands/TclCommandWriteGCode.py

@@ -67,6 +67,8 @@ class TclCommandWriteGCode(TclCommandSignaled):
 
 
         if 'muted' in args:
         if 'muted' in args:
             muted = args['muted']
             muted = args['muted']
+        else:
+            muted = 0
 
 
         # TODO: This is not needed any more? All targets should be present.
         # 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 there are promised objects, wait until all promises have been fulfilled.