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

Merged marius_stanciu/flatcam_beta/Beta_8.994 into Beta

Marius Stanciu 5 лет назад
Родитель
Сommit
5329cb1219

+ 1 - 1
Bookmark.py

@@ -240,7 +240,7 @@ class BookmarkManager(QtWidgets.QWidget):
             index_list.append(index)
             index_list.append(index)
             title_to_remove = self.table_widget.item(model_index.row(), 1).text()
             title_to_remove = self.table_widget.item(model_index.row(), 1).text()
 
 
-            if title_to_remove == 'FlatCAM' or title_to_remove == 'Backup Site':
+            if title_to_remove == 'FlatCAM' or title_to_remove == _('Backup Site'):
                 self.app.inform.emit('[WARNING_NOTCL] %s.' % _("This bookmark can not be removed"))
                 self.app.inform.emit('[WARNING_NOTCL] %s.' % _("This bookmark can not be removed"))
                 self.build_bm_ui()
                 self.build_bm_ui()
                 return
                 return

+ 8 - 0
CHANGELOG.md

@@ -17,6 +17,14 @@ CHANGELOG for FlatCAM beta
 - some UI cleanup in the Geometry UI
 - some UI cleanup in the Geometry UI
 - updated the translation strings except Russian which could be in the works
 - updated the translation strings except Russian which could be in the works
 - fixed an error that did not allowed for the older preferences to be deleted when installing a different version of the software
 - fixed an error that did not allowed for the older preferences to be deleted when installing a different version of the software
+- in Legacy Mode fixed a small issue: the status bar icon for the Grid axis was not colored on app start
+- added a new string to the translatable strings
+- fixed an error that sometime showed in Legacy Mode when moving the mouse outside canvas
+- reactivated the shortcut key 'S' in TCL Shell, to close the shell dock when it was open (of course the focus has to be not on the command line)
+- brought up-to-date and fixed the Tcl Command Drillcncjob and Cncjob
+- fixed Tcl command Isolate to not print messages on message bar in case it is run headless
+- fixed Tcl command Copper Clear (NCC)
+- fixed Tcl command Paint
 
 
 27.10.2020
 27.10.2020
 
 

+ 5 - 1
appGUI/GUIElements.py

@@ -3757,14 +3757,18 @@ class _BrowserTextEdit(QTextEdit):
             # Copy Text
             # Copy Text
             elif key == QtCore.Qt.Key_C:
             elif key == QtCore.Qt.Key_C:
                 self.copy_text()
                 self.copy_text()
-                # Copy Text
+            # Save Log
             elif key == QtCore.Qt.Key_S:
             elif key == QtCore.Qt.Key_S:
                 if self.app:
                 if self.app:
                     self.save_log(app=self.app)
                     self.save_log(app=self.app)
 
 
         elif modifiers == QtCore.Qt.NoModifier:
         elif modifiers == QtCore.Qt.NoModifier:
+            # Clear all
             if key == QtCore.Qt.Key_Delete:
             if key == QtCore.Qt.Key_Delete:
                 self.clear()
                 self.clear()
+            # Shell toggle
+            if key == QtCore.Qt.Key_S:
+                self.app.ui.toggle_shell_ui()
 
 
     def copy_text(self):
     def copy_text(self):
         tcursor = self.textCursor()
         tcursor = self.textCursor()

+ 18 - 12
appGUI/PlotCanvas.py

@@ -191,13 +191,13 @@ class PlotCanvas(QtCore.QObject, VisPyCanvas):
 
 
         # enable the HUD if it is activated in FlatCAM Preferences
         # enable the HUD if it is activated in FlatCAM Preferences
         if self.fcapp.defaults['global_hud'] is True:
         if self.fcapp.defaults['global_hud'] is True:
-            self.on_toggle_hud(state=True)
+            self.on_toggle_hud(state=True, silent=True)
 
 
         # Axis Display
         # Axis Display
         self.axis_enabled = True
         self.axis_enabled = True
 
 
         # enable Axis
         # enable Axis
-        self.on_toggle_axis(state=True)
+        self.on_toggle_axis(state=True, silent=True)
 
 
         # enable Grid lines
         # enable Grid lines
         self.grid_lines_enabled = True
         self.grid_lines_enabled = True
@@ -218,8 +218,8 @@ class PlotCanvas(QtCore.QObject, VisPyCanvas):
 
 
         self.graph_event_connect('mouse_wheel', self.on_mouse_scroll)
         self.graph_event_connect('mouse_wheel', self.on_mouse_scroll)
 
 
-    def on_toggle_axis(self, signal=None, state=None):
-        if state is None:
+    def on_toggle_axis(self, signal=None, state=None, silent=None):
+        if not state:
             state = not self.axis_enabled
             state = not self.axis_enabled
 
 
         if state:
         if state:
@@ -234,16 +234,18 @@ class PlotCanvas(QtCore.QObject, VisPyCanvas):
                                                               background-color: orange;
                                                               background-color: orange;
                                                           }
                                                           }
                                                           """)
                                                           """)
-            self.fcapp.inform[str, bool].emit(_("Axis enabled."), False)
+            if silent is None:
+                self.fcapp.inform[str, bool].emit(_("Axis enabled."), False)
         else:
         else:
             self.axis_enabled = False
             self.axis_enabled = False
             self.fcapp.defaults['global_axis'] = False
             self.fcapp.defaults['global_axis'] = False
             self.v_line.parent = None
             self.v_line.parent = None
             self.h_line.parent = None
             self.h_line.parent = None
             self.fcapp.ui.axis_status_label.setStyleSheet("")
             self.fcapp.ui.axis_status_label.setStyleSheet("")
-            self.fcapp.inform[str, bool].emit(_("Axis disabled."), False)
+            if silent is None:
+                self.fcapp.inform[str, bool].emit(_("Axis disabled."), False)
 
 
-    def on_toggle_hud(self, signal=None, state=None):
+    def on_toggle_hud(self, signal=None, state=None, silent=None):
         if state is None:
         if state is None:
             state = not self.hud_enabled
             state = not self.hud_enabled
 
 
@@ -259,7 +261,8 @@ class PlotCanvas(QtCore.QObject, VisPyCanvas):
                                                       background-color: mediumpurple;
                                                       background-color: mediumpurple;
                                                   }
                                                   }
                                                   """)
                                                   """)
-            self.fcapp.inform[str, bool].emit(_("HUD enabled."), False)
+            if silent is None:
+                self.fcapp.inform[str, bool].emit(_("HUD enabled."), False)
 
 
         else:
         else:
             self.hud_enabled = False
             self.hud_enabled = False
@@ -267,21 +270,24 @@ class PlotCanvas(QtCore.QObject, VisPyCanvas):
             self.text_hud.parent = None
             self.text_hud.parent = None
             self.fcapp.defaults['global_hud'] = False
             self.fcapp.defaults['global_hud'] = False
             self.fcapp.ui.hud_label.setStyleSheet("")
             self.fcapp.ui.hud_label.setStyleSheet("")
-            self.fcapp.inform[str, bool].emit(_("HUD disabled."), False)
+            if silent is None:
+                self.fcapp.inform[str, bool].emit(_("HUD disabled."), False)
 
 
-    def on_toggle_grid_lines(self):
+    def on_toggle_grid_lines(self, signal=None, silent=None):
         state = not self.grid_lines_enabled
         state = not self.grid_lines_enabled
 
 
         if state:
         if state:
             self.fcapp.defaults['global_grid_lines'] = True
             self.fcapp.defaults['global_grid_lines'] = True
             self.grid_lines_enabled = True
             self.grid_lines_enabled = True
             self.grid.parent = self.view.scene
             self.grid.parent = self.view.scene
-            self.fcapp.inform[str, bool].emit(_("Grid enabled."), False)
+            if silent is None:
+                self.fcapp.inform[str, bool].emit(_("Grid enabled."), False)
         else:
         else:
             self.fcapp.defaults['global_grid_lines'] = False
             self.fcapp.defaults['global_grid_lines'] = False
             self.grid_lines_enabled = False
             self.grid_lines_enabled = False
             self.grid.parent = None
             self.grid.parent = None
-            self.fcapp.inform[str, bool].emit(_("Grid disabled."), False)
+            if silent is None:
+                self.fcapp.inform[str, bool].emit(_("Grid disabled."), False)
 
 
         # HACK: enabling/disabling the cursor seams to somehow update the shapes on screen
         # HACK: enabling/disabling the cursor seams to somehow update the shapes on screen
         # - perhaps is a bug in VisPy implementation
         # - perhaps is a bug in VisPy implementation

+ 29 - 15
appGUI/PlotCanvasLegacy.py

@@ -306,9 +306,13 @@ class PlotCanvasLegacy(QtCore.QObject):
         # signal if there is a doubleclick
         # signal if there is a doubleclick
         self.is_dblclk = False
         self.is_dblclk = False
 
 
+        # HUD Display
         self.hud_enabled = False
         self.hud_enabled = False
         self.text_hud = self.Thud(plotcanvas=self)
         self.text_hud = self.Thud(plotcanvas=self)
 
 
+        if self.app.defaults['global_hud'] is True:
+            self.on_toggle_hud(state=True, silent=None)
+
         # enable Grid lines
         # enable Grid lines
         self.grid_lines_enabled = True
         self.grid_lines_enabled = True
 
 
@@ -317,17 +321,21 @@ class PlotCanvasLegacy(QtCore.QObject):
         if self.app.defaults['global_workspace'] is True:
         if self.app.defaults['global_workspace'] is True:
             self.draw_workspace(workspace_size=self.app.defaults["global_workspaceT"])
             self.draw_workspace(workspace_size=self.app.defaults["global_workspaceT"])
 
 
-        if self.app.defaults['global_hud'] is True:
-            self.on_toggle_hud(state=True)
-
         # Axis Display
         # Axis Display
         self.axis_enabled = True
         self.axis_enabled = True
 
 
         # enable Axis
         # enable Axis
-        self.on_toggle_axis(state=True)
-
-    def on_toggle_axis(self, signal=None, state=None):
-        if state is None:
+        self.on_toggle_axis(state=True, silent=True)
+        self.app.ui.axis_status_label.setStyleSheet("""
+                                                    QLabel
+                                                    {
+                                                        color: black;
+                                                        background-color: orange;
+                                                    }
+                                                    """)
+
+    def on_toggle_axis(self, signal=None, state=None, silent=None):
+        if not state:
             state = not self.axis_enabled
             state = not self.axis_enabled
 
 
         if state:
         if state:
@@ -343,7 +351,8 @@ class PlotCanvasLegacy(QtCore.QObject):
                                                                 background-color: orange;
                                                                 background-color: orange;
                                                             }
                                                             }
                                                             """)
                                                             """)
-                self.app.inform[str, bool].emit(_("Axis enabled."), False)
+                if silent is None:
+                    self.app.inform[str, bool].emit(_("Axis enabled."), False)
         else:
         else:
             self.axis_enabled = False
             self.axis_enabled = False
             self.app.defaults['global_axis'] = False
             self.app.defaults['global_axis'] = False
@@ -351,11 +360,12 @@ class PlotCanvasLegacy(QtCore.QObject):
                 self.axes.lines.remove(self.h_line)
                 self.axes.lines.remove(self.h_line)
                 self.axes.lines.remove(self.v_line)
                 self.axes.lines.remove(self.v_line)
                 self.app.ui.axis_status_label.setStyleSheet("")
                 self.app.ui.axis_status_label.setStyleSheet("")
-                self.app.inform[str, bool].emit(_("Axis disabled."), False)
+                if silent is None:
+                    self.app.inform[str, bool].emit(_("Axis disabled."), False)
 
 
         self.canvas.draw()
         self.canvas.draw()
 
 
-    def on_toggle_hud(self, signal=None, state=None):
+    def on_toggle_hud(self, signal=None, state=None, silent=None):
         if state is None:
         if state is None:
             state = not self.hud_enabled
             state = not self.hud_enabled
 
 
@@ -371,13 +381,15 @@ class PlotCanvasLegacy(QtCore.QObject):
                                                     background-color: mediumpurple;
                                                     background-color: mediumpurple;
                                                 }
                                                 }
                                                 """)
                                                 """)
-            self.app.inform[str, bool].emit(_("HUD enabled."), False)
+            if silent is None:
+                self.app.inform[str, bool].emit(_("HUD enabled."), False)
         else:
         else:
             self.hud_enabled = False
             self.hud_enabled = False
             self.text_hud.remove_artist()
             self.text_hud.remove_artist()
             self.app.defaults['global_hud'] = False
             self.app.defaults['global_hud'] = False
             self.app.ui.hud_label.setStyleSheet("")
             self.app.ui.hud_label.setStyleSheet("")
-            self.app.inform[str, bool].emit(_("HUD disabled."), False)
+            if silent is None:
+                self.app.inform[str, bool].emit(_("HUD disabled."), False)
 
 
         self.canvas.draw()
         self.canvas.draw()
 
 
@@ -440,7 +452,7 @@ class PlotCanvasLegacy(QtCore.QObject):
             if self.hud_holder in self.p.axes.artists:
             if self.hud_holder in self.p.axes.artists:
                 self.p.axes.artists.remove(self.hud_holder)
                 self.p.axes.artists.remove(self.hud_holder)
 
 
-    def on_toggle_grid_lines(self):
+    def on_toggle_grid_lines(self, signal=None, silent=None):
         state = not self.grid_lines_enabled
         state = not self.grid_lines_enabled
 
 
         if state:
         if state:
@@ -451,7 +463,8 @@ class PlotCanvasLegacy(QtCore.QObject):
                 self.canvas.draw()
                 self.canvas.draw()
             except IndexError:
             except IndexError:
                 pass
                 pass
-            self.app.inform[str, bool].emit(_("Grid enabled."), False)
+            if silent is None:
+                self.app.inform[str, bool].emit(_("Grid enabled."), False)
         else:
         else:
             self.app.defaults['global_grid_lines'] = False
             self.app.defaults['global_grid_lines'] = False
             self.grid_lines_enabled = False
             self.grid_lines_enabled = False
@@ -460,7 +473,8 @@ class PlotCanvasLegacy(QtCore.QObject):
                 self.canvas.draw()
                 self.canvas.draw()
             except IndexError:
             except IndexError:
                 pass
                 pass
-            self.app.inform[str, bool].emit(_("Grid disabled."), False)
+            if silent is None:
+                self.app.inform[str, bool].emit(_("Grid disabled."), False)
 
 
     def draw_workspace(self, workspace_size):
     def draw_workspace(self, workspace_size):
         """
         """

+ 6 - 1
appObjects/FlatCAMCNCJob.py

@@ -372,7 +372,12 @@ class CNCJobObject(FlatCAMObj, CNCjob):
             dia_item = QtWidgets.QTableWidgetItem('%.*f' % (self.decimals, float(tooldia_key)))
             dia_item = QtWidgets.QTableWidgetItem('%.*f' % (self.decimals, float(tooldia_key)))
             nr_drills_item = QtWidgets.QTableWidgetItem('%d' % int(dia_value['nr_drills']))
             nr_drills_item = QtWidgets.QTableWidgetItem('%d' % int(dia_value['nr_drills']))
             nr_slots_item = QtWidgets.QTableWidgetItem('%d' % int(dia_value['nr_slots']))
             nr_slots_item = QtWidgets.QTableWidgetItem('%d' % int(dia_value['nr_slots']))
-            cutz_item = QtWidgets.QTableWidgetItem('%.*f' % (self.decimals, float(dia_value['offset']) + self.z_cut))
+            try:
+                offset_val = self.app.dec_format(float(dia_value['offset']), self.decimals) + self.z_cut
+            except KeyError:
+                offset_val = self.app.dec_format(float(dia_value['offset_z']), self.decimals) + self.z_cut
+
+            cutz_item = QtWidgets.QTableWidgetItem('%f' % offset_val)
 
 
             t_id.setFlags(QtCore.Qt.ItemIsEnabled)
             t_id.setFlags(QtCore.Qt.ItemIsEnabled)
             dia_item.setFlags(QtCore.Qt.ItemIsEnabled)
             dia_item.setFlags(QtCore.Qt.ItemIsEnabled)

+ 11 - 6
appObjects/FlatCAMGerber.py

@@ -493,7 +493,7 @@ class GerberObject(FlatCAMObj, Gerber):
 
 
                 geo_obj.solid_geometry = []
                 geo_obj.solid_geometry = []
 
 
-                # transfer the Cut Z and Vtip and VAngle values in case that we use the V-Shape tool in Gerber UI
+                # transfer the Cut Z and Vtip and Vangle values in case that we use the V-Shape tool in Gerber UI
                 if geo_obj.tool_type.lower() == 'v':
                 if geo_obj.tool_type.lower() == 'v':
                     new_cutz = self.app.defaults["tools_iso_tool_cutz"]
                     new_cutz = self.app.defaults["tools_iso_tool_cutz"]
                     new_vtipdia = self.app.defaults["tools_iso_tool_vtipdia"]
                     new_vtipdia = self.app.defaults["tools_iso_tool_vtipdia"]
@@ -555,7 +555,8 @@ class GerberObject(FlatCAMObj, Gerber):
                                                   follow=follow, nr_passes=nr_pass)
                                                   follow=follow, nr_passes=nr_pass)
 
 
                     if geom == 'fail':
                     if geom == 'fail':
-                        app_obj.inform.emit('[ERROR_NOTCL] %s' % _("Isolation geometry could not be generated."))
+                        if plot:
+                            app_obj.inform.emit('[ERROR_NOTCL] %s' % _("Isolation geometry could not be generated."))
                         return 'fail'
                         return 'fail'
                     geo_obj.solid_geometry.append(geom)
                     geo_obj.solid_geometry.append(geom)
 
 
@@ -580,7 +581,9 @@ class GerberObject(FlatCAMObj, Gerber):
                 if empty_cnt == len(geo_obj.solid_geometry):
                 if empty_cnt == len(geo_obj.solid_geometry):
                     raise ValidationError("Empty Geometry", None)
                     raise ValidationError("Empty Geometry", None)
                 else:
                 else:
-                    app_obj.inform.emit('[success] %s" %s' % (_("Isolation geometry created"), geo_obj.options["name"]))
+                    if plot:
+                        app_obj.inform.emit('[success] %s: %s' %
+                                            (_("Isolation geometry created"), geo_obj.options["name"]))
 
 
                 # even if combine is checked, one pass is still single-geo
                 # even if combine is checked, one pass is still single-geo
                 geo_obj.multigeo = True if passes > 1 else False
                 geo_obj.multigeo = True if passes > 1 else False
@@ -629,7 +632,8 @@ class GerberObject(FlatCAMObj, Gerber):
                                                   follow=follow, nr_passes=i)
                                                   follow=follow, nr_passes=i)
 
 
                     if geom == 'fail':
                     if geom == 'fail':
-                        app_obj.inform.emit('[ERROR_NOTCL] %s' % _("Isolation geometry could not be generated."))
+                        if plot:
+                            app_obj.inform.emit('[ERROR_NOTCL] %s' % _("Isolation geometry could not be generated."))
                         return 'fail'
                         return 'fail'
 
 
                     geo_obj.solid_geometry = geom
                     geo_obj.solid_geometry = geom
@@ -706,8 +710,9 @@ class GerberObject(FlatCAMObj, Gerber):
                     if empty_cnt == len(geo_obj.solid_geometry):
                     if empty_cnt == len(geo_obj.solid_geometry):
                         raise ValidationError("Empty Geometry", None)
                         raise ValidationError("Empty Geometry", None)
                     else:
                     else:
-                        app_obj.inform.emit('[success] %s: %s' %
-                                            (_("Isolation geometry created"), geo_obj.options["name"]))
+                        if plot:
+                            app_obj.inform.emit('[success] %s: %s' %
+                                                (_("Isolation geometry created"), geo_obj.options["name"]))
                     geo_obj.multigeo = False
                     geo_obj.multigeo = False
 
 
                     # ############################################################
                     # ############################################################

+ 6 - 4
appTools/ToolNCC.py

@@ -2836,10 +2836,10 @@ class NonCopperClear(AppTool, Gerber):
             # Generate area for each tool
             # Generate area for each tool
             offset_a = sum(sorted_tools)
             offset_a = sum(sorted_tools)
             current_uid = int(1)
             current_uid = int(1)
-            try:
-                tool = eval(self.app.defaults["tools_ncc_tools"])[0]
-            except TypeError:
-                tool = eval(self.app.defaults["tools_ncc_tools"])
+            # try:
+            #     tool = eval(self.app.defaults["tools_ncc_tools"])[0]
+            # except TypeError:
+            #     tool = eval(self.app.defaults["tools_ncc_tools"])
 
 
             # ###################################################################################################
             # ###################################################################################################
             # Calculate the empty area by subtracting the solid_geometry from the object bounding box geometry ##
             # Calculate the empty area by subtracting the solid_geometry from the object bounding box geometry ##
@@ -2854,6 +2854,8 @@ class NonCopperClear(AppTool, Gerber):
                     sol_geo = ncc_obj.solid_geometry.buffer(0)
                     sol_geo = ncc_obj.solid_geometry.buffer(0)
                 else:
                 else:
                     sol_geo = ncc_obj.solid_geometry
                     sol_geo = ncc_obj.solid_geometry
+                    if isinstance(sol_geo, list):
+                        sol_geo = unary_union(sol_geo)
 
 
                 if has_offset is True:
                 if has_offset is True:
                     app_obj.inform.emit('[WARNING_NOTCL] %s ...' % _("Buffering"))
                     app_obj.inform.emit('[WARNING_NOTCL] %s ...' % _("Buffering"))

+ 4 - 2
appTools/ToolPaint.py

@@ -2234,7 +2234,9 @@ class ToolPaint(AppTool, Gerber):
             self.app.inform.emit('%s %s' % (_("Paint Tool."), _("Normal painting polygon task started.")))
             self.app.inform.emit('%s %s' % (_("Paint Tool."), _("Normal painting polygon task started.")))
 
 
         if inside_pt and poly_list is None:
         if inside_pt and poly_list is None:
-            polygon_list = [self.find_polygon(point=inside_pt, geoset=obj.solid_geometry)]
+            polygon_list = self.find_polygon(point=inside_pt, geoset=obj.solid_geometry)
+            if polygon_list:
+                polygon_list = [polygon_list]
         elif (inside_pt is None and poly_list) or (inside_pt and poly_list):
         elif (inside_pt is None and poly_list) or (inside_pt and poly_list):
             polygon_list = poly_list
             polygon_list = poly_list
         else:
         else:
@@ -2244,7 +2246,7 @@ class ToolPaint(AppTool, Gerber):
         if polygon_list is None:
         if polygon_list is None:
             self.app.log.warning('No polygon found.')
             self.app.log.warning('No polygon found.')
             self.app.inform.emit('[WARNING] %s' % _('No polygon found.'))
             self.app.inform.emit('[WARNING] %s' % _('No polygon found.'))
-            return
+            return "fail"
 
 
         self.paint_geo(obj, polygon_list, tooldia=tooldia, order=order, method=method, outname=outname,
         self.paint_geo(obj, polygon_list, tooldia=tooldia, order=order, method=method, outname=outname,
                        tools_storage=tools_storage, plot=plot, run_threaded=run_threaded)
                        tools_storage=tools_storage, plot=plot, run_threaded=run_threaded)

+ 6 - 3
app_Main.py

@@ -3204,7 +3204,7 @@ class App(QtCore.QObject):
             self.defaults["global_bookmarks"].update(
             self.defaults["global_bookmarks"].update(
                 {
                 {
                     '1': ['FlatCAM', "http://flatcam.org"],
                     '1': ['FlatCAM', "http://flatcam.org"],
-                    '2': ['Backup Site', ""]
+                    '2': [_('Backup Site'), ""]
                 }
                 }
             )
             )
         else:
         else:
@@ -3246,7 +3246,7 @@ class App(QtCore.QObject):
 
 
                 act.setIcon(QtGui.QIcon(self.resource_location + '/link16.png'))
                 act.setIcon(QtGui.QIcon(self.resource_location + '/link16.png'))
                 # from here: https://stackoverflow.com/questions/20390323/pyqt-dynamic-generate-qmenu-action-and-connect
                 # from here: https://stackoverflow.com/questions/20390323/pyqt-dynamic-generate-qmenu-action-and-connect
-                if title == 'Backup Site' and weblink == "":
+                if title == _('Backup Site') and weblink == "":
                     act.triggered.connect(self.on_backup_site)
                     act.triggered.connect(self.on_backup_site)
                 else:
                 else:
                     act.triggered.connect(lambda sig, link=weblink: webbrowser.open(link))
                     act.triggered.connect(lambda sig, link=weblink: webbrowser.open(link))
@@ -6377,7 +6377,10 @@ class App(QtCore.QObject):
 
 
         pos_canvas = self.plotcanvas.translate_coords(event_pos)
         pos_canvas = self.plotcanvas.translate_coords(event_pos)
         if self.grid_status():
         if self.grid_status():
-            pos = self.geo_editor.snap(pos_canvas[0], pos_canvas[1])
+            try:
+                pos = self.geo_editor.snap(pos_canvas[0], pos_canvas[1])
+            except TypeError:
+                return
         else:
         else:
             pos = (pos_canvas[0], pos_canvas[1])
             pos = (pos_canvas[0], pos_canvas[1])
 
 

+ 4 - 2
camlib.py

@@ -3596,6 +3596,7 @@ class CNCjob(Geometry):
                     for k, v in list(self.options.items()):
                     for k, v in list(self.options.items()):
                         default_data[k] = deepcopy(v)
                         default_data[k] = deepcopy(v)
 
 
+                    # it[1] is the tool diameter
                     self.exc_cnc_tools[it[1]] = {}
                     self.exc_cnc_tools[it[1]] = {}
                     self.exc_cnc_tools[it[1]]['tool'] = it[0]
                     self.exc_cnc_tools[it[1]]['tool'] = it[0]
                     self.exc_cnc_tools[it[1]]['nr_drills'] = drill_no
                     self.exc_cnc_tools[it[1]]['nr_drills'] = drill_no
@@ -6349,10 +6350,11 @@ class CNCjob(Geometry):
         # Current path: temporary storage until tool is
         # Current path: temporary storage until tool is
         # lifted or lowered.
         # lifted or lowered.
         if self.toolchange_xy_type == "excellon":
         if self.toolchange_xy_type == "excellon":
-            if self.app.defaults["excellon_toolchangexy"] == '' or self.app.defaults["excellon_toolchangexy"] is None:
+            if self.app.defaults["tools_drill_toolchangexy"] == '' or \
+                    self.app.defaults["tools_drill_toolchangexy"] is None:
                 pos_xy = (0, 0)
                 pos_xy = (0, 0)
             else:
             else:
-                pos_xy = self.app.defaults["excellon_toolchangexy"]
+                pos_xy = self.app.defaults["tools_drill_toolchangexy"]
                 try:
                 try:
                     pos_xy = [float(eval(a)) for a in pos_xy.split(",")]
                     pos_xy = [float(eval(a)) for a in pos_xy.split(",")]
                 except Exception:
                 except Exception:

BIN
locale/de/LC_MESSAGES/strings.mo


+ 8 - 2
locale/de/LC_MESSAGES/strings.po

@@ -1,8 +1,8 @@
 msgid ""
 msgid ""
 msgstr ""
 msgstr ""
 "Project-Id-Version: \n"
 "Project-Id-Version: \n"
-"POT-Creation-Date: 2020-10-28 03:19+0200\n"
-"PO-Revision-Date: 2020-10-28 03:19+0200\n"
+"POT-Creation-Date: 2020-10-28 10:53+0200\n"
+"PO-Revision-Date: 2020-10-28 10:53+0200\n"
 "Last-Translator: \n"
 "Last-Translator: \n"
 "Language-Team: \n"
 "Language-Team: \n"
 "Language: de\n"
 "Language: de\n"
@@ -84,6 +84,12 @@ msgstr ""
 msgid "Bookmark added."
 msgid "Bookmark added."
 msgstr "Lesezeichen verwalten."
 msgstr "Lesezeichen verwalten."
 
 
+#: Bookmark.py:243 app_Main.py:3207 app_Main.py:3249
+#, fuzzy
+#| msgid "Backup"
+msgid "Backup Site"
+msgstr "Sicherungskopie"
+
 #: Bookmark.py:244
 #: Bookmark.py:244
 msgid "This bookmark can not be removed"
 msgid "This bookmark can not be removed"
 msgstr "Dieses Lesezeichen kann nicht entfernt werden"
 msgstr "Dieses Lesezeichen kann nicht entfernt werden"

BIN
locale/en/LC_MESSAGES/strings.mo


+ 7 - 3
locale/en/LC_MESSAGES/strings.po

@@ -5,8 +5,8 @@
 msgid ""
 msgid ""
 msgstr ""
 msgstr ""
 "Project-Id-Version: \n"
 "Project-Id-Version: \n"
-"POT-Creation-Date: 2020-10-28 03:19+0200\n"
-"PO-Revision-Date: 2020-10-28 03:19+0200\n"
+"POT-Creation-Date: 2020-10-28 10:53+0200\n"
+"PO-Revision-Date: 2020-10-28 10:53+0200\n"
 "Last-Translator: \n"
 "Last-Translator: \n"
 "Language-Team: \n"
 "Language-Team: \n"
 "Language: en\n"
 "Language: en\n"
@@ -88,6 +88,11 @@ msgstr "Either the Title or the Weblink already in the table."
 msgid "Bookmark added."
 msgid "Bookmark added."
 msgstr "Bookmark added."
 msgstr "Bookmark added."
 
 
+#: Bookmark.py:243 app_Main.py:3207 app_Main.py:3249
+#| msgid "Backup"
+msgid "Backup Site"
+msgstr "Backup Site"
+
 #: Bookmark.py:244
 #: Bookmark.py:244
 msgid "This bookmark can not be removed"
 msgid "This bookmark can not be removed"
 msgstr "This bookmark can not be removed"
 msgstr "This bookmark can not be removed"
@@ -13466,7 +13471,6 @@ msgid "Working..."
 msgstr "Working..."
 msgstr "Working..."
 
 
 #: appObjects/FlatCAMGeometry.py:2425
 #: appObjects/FlatCAMGeometry.py:2425
-#| msgid "Add Polish"
 msgid "Polish"
 msgid "Polish"
 msgstr "Polish"
 msgstr "Polish"
 
 

BIN
locale/es/LC_MESSAGES/strings.mo


+ 6 - 2
locale/es/LC_MESSAGES/strings.po

@@ -5,8 +5,8 @@
 msgid ""
 msgid ""
 msgstr ""
 msgstr ""
 "Project-Id-Version: \n"
 "Project-Id-Version: \n"
-"POT-Creation-Date: 2020-10-28 03:19+0200\n"
-"PO-Revision-Date: 2020-10-28 03:20+0200\n"
+"POT-Creation-Date: 2020-10-28 10:53+0200\n"
+"PO-Revision-Date: 2020-10-28 10:54+0200\n"
 "Last-Translator: Marius Stanciu - Google Translate\n"
 "Last-Translator: Marius Stanciu - Google Translate\n"
 "Language-Team: \n"
 "Language-Team: \n"
 "Language: es\n"
 "Language: es\n"
@@ -88,6 +88,10 @@ msgstr "Ya sea el Título o el Enlace web ya en la tabla."
 msgid "Bookmark added."
 msgid "Bookmark added."
 msgstr "Marcador agregado."
 msgstr "Marcador agregado."
 
 
+#: Bookmark.py:243 app_Main.py:3207 app_Main.py:3249
+msgid "Backup Site"
+msgstr "Sitio de respaldo"
+
 #: Bookmark.py:244
 #: Bookmark.py:244
 msgid "This bookmark can not be removed"
 msgid "This bookmark can not be removed"
 msgstr "Este marcador no se puede eliminar"
 msgstr "Este marcador no se puede eliminar"

BIN
locale/fr/LC_MESSAGES/strings.mo


+ 8 - 2
locale/fr/LC_MESSAGES/strings.po

@@ -6,8 +6,8 @@
 msgid ""
 msgid ""
 msgstr ""
 msgstr ""
 "Project-Id-Version: \n"
 "Project-Id-Version: \n"
-"POT-Creation-Date: 2020-10-28 03:21+0200\n"
-"PO-Revision-Date: 2020-10-28 03:21+0200\n"
+"POT-Creation-Date: 2020-10-28 10:55+0200\n"
+"PO-Revision-Date: 2020-10-28 10:55+0200\n"
 "Last-Translator: \n"
 "Last-Translator: \n"
 "Language-Team: \n"
 "Language-Team: \n"
 "Language: fr\n"
 "Language: fr\n"
@@ -89,6 +89,12 @@ msgstr "Titre ou lien Web déjà dans le tableau."
 msgid "Bookmark added."
 msgid "Bookmark added."
 msgstr "Signet ajouté."
 msgstr "Signet ajouté."
 
 
+#: Bookmark.py:243 app_Main.py:3207 app_Main.py:3249
+#, fuzzy
+#| msgid "Backup"
+msgid "Backup Site"
+msgstr "F. Paramètres"
+
 #: Bookmark.py:244
 #: Bookmark.py:244
 msgid "This bookmark can not be removed"
 msgid "This bookmark can not be removed"
 msgstr "Ce menu ne peut être supprimé"
 msgstr "Ce menu ne peut être supprimé"

BIN
locale/it/LC_MESSAGES/strings.mo


+ 6 - 2
locale/it/LC_MESSAGES/strings.po

@@ -5,8 +5,8 @@
 msgid ""
 msgid ""
 msgstr ""
 msgstr ""
 "Project-Id-Version: \n"
 "Project-Id-Version: \n"
-"POT-Creation-Date: 2020-10-28 03:21+0200\n"
-"PO-Revision-Date: 2020-10-28 03:21+0200\n"
+"POT-Creation-Date: 2020-10-28 10:55+0200\n"
+"PO-Revision-Date: 2020-10-28 10:56+0200\n"
 "Last-Translator: \n"
 "Last-Translator: \n"
 "Language-Team: \n"
 "Language-Team: \n"
 "Language: it\n"
 "Language: it\n"
@@ -88,6 +88,10 @@ msgstr "Il titolo o il link sono già presenti nella tabella."
 msgid "Bookmark added."
 msgid "Bookmark added."
 msgstr "Segnalibro aggiunto."
 msgstr "Segnalibro aggiunto."
 
 
+#: Bookmark.py:243 app_Main.py:3207 app_Main.py:3249
+msgid "Backup Site"
+msgstr "Sito di backup"
+
 #: Bookmark.py:244
 #: Bookmark.py:244
 msgid "This bookmark can not be removed"
 msgid "This bookmark can not be removed"
 msgstr "Questo segnalibro non può essere rimosso"
 msgstr "Questo segnalibro non può essere rimosso"

BIN
locale/pt_BR/LC_MESSAGES/strings.mo


+ 6 - 2
locale/pt_BR/LC_MESSAGES/strings.po

@@ -1,8 +1,8 @@
 msgid ""
 msgid ""
 msgstr ""
 msgstr ""
 "Project-Id-Version: \n"
 "Project-Id-Version: \n"
-"POT-Creation-Date: 2020-10-28 03:21+0200\n"
-"PO-Revision-Date: 2020-10-28 03:25+0200\n"
+"POT-Creation-Date: 2020-10-28 10:56+0200\n"
+"PO-Revision-Date: 2020-10-28 10:57+0200\n"
 "Last-Translator: Carlos Stein <carlos.stein@gmail.com>\n"
 "Last-Translator: Carlos Stein <carlos.stein@gmail.com>\n"
 "Language-Team: \n"
 "Language-Team: \n"
 "Language: pt_BR\n"
 "Language: pt_BR\n"
@@ -84,6 +84,10 @@ msgstr "O título ou o link da Web já está na tabela."
 msgid "Bookmark added."
 msgid "Bookmark added."
 msgstr "Favorito adicionado."
 msgstr "Favorito adicionado."
 
 
+#: Bookmark.py:243 app_Main.py:3207 app_Main.py:3249
+msgid "Backup Site"
+msgstr "Site de backup"
+
 #: Bookmark.py:244
 #: Bookmark.py:244
 msgid "This bookmark can not be removed"
 msgid "This bookmark can not be removed"
 msgstr "Este favorito não pode ser removido"
 msgstr "Este favorito não pode ser removido"

BIN
locale/ro/LC_MESSAGES/strings.mo


+ 7 - 3
locale/ro/LC_MESSAGES/strings.po

@@ -5,8 +5,8 @@
 msgid ""
 msgid ""
 msgstr ""
 msgstr ""
 "Project-Id-Version: \n"
 "Project-Id-Version: \n"
-"POT-Creation-Date: 2020-10-28 03:25+0200\n"
-"PO-Revision-Date: 2020-10-28 03:26+0200\n"
+"POT-Creation-Date: 2020-10-28 10:57+0200\n"
+"PO-Revision-Date: 2020-10-28 10:57+0200\n"
 "Last-Translator: \n"
 "Last-Translator: \n"
 "Language-Team: \n"
 "Language-Team: \n"
 "Language: ro\n"
 "Language: ro\n"
@@ -89,6 +89,10 @@ msgstr "Fie Titlul, fie Weblink-ul deja sunt in tabel."
 msgid "Bookmark added."
 msgid "Bookmark added."
 msgstr "Bookmark adăugat."
 msgstr "Bookmark adăugat."
 
 
+#: Bookmark.py:243 app_Main.py:3207 app_Main.py:3249
+msgid "Backup Site"
+msgstr "Site de Backup"
+
 #: Bookmark.py:244
 #: Bookmark.py:244
 msgid "This bookmark can not be removed"
 msgid "This bookmark can not be removed"
 msgstr "Acest bookmark nu poate fi eliminat"
 msgstr "Acest bookmark nu poate fi eliminat"
@@ -5026,7 +5030,7 @@ msgstr "F1"
 
 
 #: appGUI/MainGUI.py:592 app_Main.py:3263 app_Main.py:3272
 #: appGUI/MainGUI.py:592 app_Main.py:3263 app_Main.py:3272
 msgid "Bookmarks Manager"
 msgid "Bookmarks Manager"
-msgstr "Bookmarks Manager"
+msgstr "Manager Bookmark-uri"
 
 
 #: appGUI/MainGUI.py:597
 #: appGUI/MainGUI.py:597
 msgid "Report a bug"
 msgid "Report a bug"

BIN
locale/tr/LC_MESSAGES/strings.mo


+ 9 - 3
locale/tr/LC_MESSAGES/strings.po

@@ -5,8 +5,8 @@
 msgid ""
 msgid ""
 msgstr ""
 msgstr ""
 "Project-Id-Version: \n"
 "Project-Id-Version: \n"
-"POT-Creation-Date: 2020-10-28 03:26+0200\n"
-"PO-Revision-Date: 2020-10-28 03:26+0200\n"
+"POT-Creation-Date: 2020-10-28 10:58+0200\n"
+"PO-Revision-Date: 2020-10-28 10:58+0200\n"
 "Last-Translator: \n"
 "Last-Translator: \n"
 "Language-Team: \n"
 "Language-Team: \n"
 "Language: tr_TR\n"
 "Language: tr_TR\n"
@@ -88,6 +88,12 @@ msgstr "Başlık veya Web Bağlantısı zaten tabloda."
 msgid "Bookmark added."
 msgid "Bookmark added."
 msgstr "Yer işareti eklendi."
 msgstr "Yer işareti eklendi."
 
 
+#: Bookmark.py:243 app_Main.py:3207 app_Main.py:3249
+#, fuzzy
+#| msgid "Backup"
+msgid "Backup Site"
+msgstr "Yedekleme"
+
 #: Bookmark.py:244
 #: Bookmark.py:244
 msgid "This bookmark can not be removed"
 msgid "This bookmark can not be removed"
 msgstr "Bu yer işareti silinemez"
 msgstr "Bu yer işareti silinemez"
@@ -4980,7 +4986,7 @@ msgstr "Gerber Özellikleri"
 
 
 #: appGUI/MainGUI.py:610
 #: appGUI/MainGUI.py:610
 msgid "Shortcuts List"
 msgid "Shortcuts List"
-msgstr "Shortcuts List"
+msgstr ""
 
 
 #: appGUI/MainGUI.py:610 appGUI/MainGUI.py:4398
 #: appGUI/MainGUI.py:610 appGUI/MainGUI.py:4398
 msgid "F3"
 msgid "F3"

+ 5 - 1
locale_template/strings.pot

@@ -6,7 +6,7 @@
 msgid ""
 msgid ""
 msgstr ""
 msgstr ""
 "Project-Id-Version: \n"
 "Project-Id-Version: \n"
-"POT-Creation-Date: 2020-10-28 03:27+0200\n"
+"POT-Creation-Date: 2020-10-28 10:53+0200\n"
 "PO-Revision-Date: 2019-03-25 15:08+0200\n"
 "PO-Revision-Date: 2019-03-25 15:08+0200\n"
 "Last-Translator: \n"
 "Last-Translator: \n"
 "Language-Team: \n"
 "Language-Team: \n"
@@ -84,6 +84,10 @@ msgstr ""
 msgid "Bookmark added."
 msgid "Bookmark added."
 msgstr ""
 msgstr ""
 
 
+#: Bookmark.py:243 app_Main.py:3207 app_Main.py:3249
+msgid "Backup Site"
+msgstr ""
+
 #: Bookmark.py:244
 #: Bookmark.py:244
 msgid "This bookmark can not be removed"
 msgid "This bookmark can not be removed"
 msgstr ""
 msgstr ""

+ 2 - 2
tclCommands/TclCommandCncjob.py

@@ -169,7 +169,7 @@ class TclCommandCncjob(TclCommandSignaled):
             args["endxy"] = args["endxy"]
             args["endxy"] = args["endxy"]
         else:
         else:
             if self.app.defaults["geometry_endxy"]:
             if self.app.defaults["geometry_endxy"]:
-                args["endxy"] = self.app.defaults["geometry_endxy"]
+                args["endxy"] = str(self.app.defaults["geometry_endxy"])
             else:
             else:
                 args["endxy"] = '0, 0'
                 args["endxy"] = '0, 0'
         if len(eval(args["endxy"])) != 2:
         if len(eval(args["endxy"])) != 2:
@@ -204,7 +204,7 @@ class TclCommandCncjob(TclCommandSignaled):
             args["toolchangexy"] = args["toolchangexy"]
             args["toolchangexy"] = args["toolchangexy"]
         else:
         else:
             if self.app.defaults["geometry_toolchangexy"]:
             if self.app.defaults["geometry_toolchangexy"]:
-                args["toolchangexy"] = self.app.defaults["geometry_toolchangexy"]
+                args["toolchangexy"] = str(self.app.defaults["geometry_toolchangexy"])
             else:
             else:
                 args["toolchangexy"] = '0, 0'
                 args["toolchangexy"] = '0, 0'
         if len(eval(args["toolchangexy"])) != 2:
         if len(eval(args["toolchangexy"])) != 2:

+ 4 - 4
tclCommands/TclCommandCopperClear.py

@@ -103,7 +103,7 @@ class TclCommandCopperClear(TclCommand):
         if 'tooldia' in args:
         if 'tooldia' in args:
             tooldia = str(args['tooldia'])
             tooldia = str(args['tooldia'])
         else:
         else:
-            tooldia = self.app.defaults["tools_ncc_tools"]
+            tooldia = str(self.app.defaults["tools_ncc_tools"])
 
 
         if 'overlap' in args:
         if 'overlap' in args:
             overlap = float(args['overlap']) / 100.0
             overlap = float(args['overlap']) / 100.0
@@ -223,8 +223,8 @@ class TclCommandCopperClear(TclCommand):
             "area_strategy":    self.app.defaults["geometry_area_strategy"],
             "area_strategy":    self.app.defaults["geometry_area_strategy"],
             "area_overz":       float(self.app.defaults["geometry_area_overz"]),
             "area_overz":       float(self.app.defaults["geometry_area_overz"]),
 
 
-            "tooldia":              self.app.defaults["tools_paint_tooldia"],
-            "tools_ncc_operation":   self.app.defaults["tools_ncc_operation"],
+            "tooldia":                  tooldia,
+            "tools_ncc_operation":      self.app.defaults["tools_ncc_operation"],
 
 
             "tools_ncc_margin":  margin,
             "tools_ncc_margin":  margin,
             "tools_ncc_method":  method_data,
             "tools_ncc_method":  method_data,
@@ -253,7 +253,7 @@ class TclCommandCopperClear(TclCommand):
                     'solid_geometry':   []
                     'solid_geometry':   []
                 }
                 }
             })
             })
-            ncc_tools[int(tooluid)]['data']['tooldia'] = float('%.*f' % (obj.decimals, tool))
+            ncc_tools[int(tooluid)]['data']['tooldia'] = self.app.dec_format(tool, obj.decimals)
 
 
         # Non-Copper clear all polygons in the non-copper clear object
         # Non-Copper clear all polygons in the non-copper clear object
         if 'all' in args:
         if 'all' in args:

+ 8 - 7
tclCommands/TclCommandDrillcncjob.py

@@ -235,7 +235,7 @@ class TclCommandDrillcncjob(TclCommandSignaled):
                 xy_toolchange = args["toolchangexy"]
                 xy_toolchange = args["toolchangexy"]
             else:
             else:
                 if self.app.defaults["tools_drill_toolchangexy"]:
                 if self.app.defaults["tools_drill_toolchangexy"]:
-                    xy_toolchange = self.app.defaults["tools_drill_toolchangexy"]
+                    xy_toolchange = str(self.app.defaults["tools_drill_toolchangexy"])
                 else:
                 else:
                     xy_toolchange = '0, 0'
                     xy_toolchange = '0, 0'
             if len(eval(xy_toolchange)) != 2:
             if len(eval(xy_toolchange)) != 2:
@@ -249,7 +249,7 @@ class TclCommandDrillcncjob(TclCommandSignaled):
                 xy_end = args["endxy"]
                 xy_end = args["endxy"]
             else:
             else:
                 if self.app.defaults["tools_drill_endxy"]:
                 if self.app.defaults["tools_drill_endxy"]:
-                    xy_end = self.app.defaults["tools_drill_endxy"]
+                    xy_end = str(self.app.defaults["tools_drill_endxy"])
                 else:
                 else:
                     xy_end = '0, 0'
                     xy_end = '0, 0'
 
 
@@ -322,14 +322,15 @@ class TclCommandDrillcncjob(TclCommandSignaled):
             if "startz" in args and args["startz"] is not None:
             if "startz" in args and args["startz"] is not None:
                 job_obj.startz = float(args["startz"])
                 job_obj.startz = float(args["startz"])
             else:
             else:
-                if self.app.defaults["excellon_startz"]:
+                if self.app.defaults["tools_drill_startz"]:
                     job_obj.startz = self.app.defaults["tools_drill_startz"]
                     job_obj.startz = self.app.defaults["tools_drill_startz"]
                 else:
                 else:
-                    job_obj.startz = (0, 0)
+                    job_obj.startz = self.app.defaults["tools_drill_travelz"]
 
 
             job_obj.endz = float(endz)
             job_obj.endz = float(endz)
             job_obj.xy_end = xy_end
             job_obj.xy_end = xy_end
             job_obj.excellon_optimization_type = opt_type
             job_obj.excellon_optimization_type = opt_type
+            job_obj.spindledir = self.app.defaults["tools_drill_spindledir"]
 
 
             ret_val = job_obj.generate_from_excellon_by_tool(obj, tools, use_ui=False)
             ret_val = job_obj.generate_from_excellon_by_tool(obj, tools, use_ui=False)
             job_obj.source_file = ret_val
             job_obj.source_file = ret_val
@@ -338,9 +339,9 @@ class TclCommandDrillcncjob(TclCommandSignaled):
                 return 'fail'
                 return 'fail'
 
 
             for t_item in job_obj.exc_cnc_tools:
             for t_item in job_obj.exc_cnc_tools:
-                job_obj.exc_cnc_tools[t_item]['data']['offset'] = \
-                    float(job_obj.exc_cnc_tools[t_item]['offset']) + float(drillz)
-                job_obj.exc_cnc_tools[t_item]['data']['ppname_e'] = obj.options['ppname_e']
+                job_obj.exc_cnc_tools[t_item]['data']['tools_drill_offset'] = \
+                    float(job_obj.exc_cnc_tools[t_item]['offset_z']) + float(drillz)
+                job_obj.exc_cnc_tools[t_item]['data']['tools_drill_ppname_e'] = job_obj.options['ppname_e']
 
 
             job_obj.gcode_parse()
             job_obj.gcode_parse()
             job_obj.create_geometry()
             job_obj.create_geometry()

+ 21 - 19
tclCommands/TclCommandPaint.py

@@ -102,7 +102,7 @@ class TclCommandPaint(TclCommand):
         if 'tooldia' in args:
         if 'tooldia' in args:
             tooldia = str(args['tooldia'])
             tooldia = str(args['tooldia'])
         else:
         else:
-            tooldia = float(self.app.defaults["tools_paint_overlap"])
+            tooldia = str(self.app.defaults["tools_paint_tooldia"])
 
 
         if 'overlap' in args:
         if 'overlap' in args:
             overlap = float(args['overlap']) / 100.0
             overlap = float(args['overlap']) / 100.0
@@ -202,13 +202,13 @@ class TclCommandPaint(TclCommand):
             "area_strategy":        self.app.defaults["geometry_area_strategy"],
             "area_strategy":        self.app.defaults["geometry_area_strategy"],
             "area_overz":           float(self.app.defaults["geometry_area_overz"]),
             "area_overz":           float(self.app.defaults["geometry_area_overz"]),
 
 
-            "tooldia":              self.app.defaults["tools_paint_tooldia"],
-            "tools_paint_offset":   offset,
-            "tools_paint_method":    method,
-            "tools_paint_selectmethod":   select,
-            "tools_paint_connect":    connect,
-            "tools_paint_contour":   contour,
-            "tools_paint_overlap":   overlap
+            "tooldia":                  tooldia,
+            "tools_paint_offset":       offset,
+            "tools_paint_method":       method,
+            "tools_paint_selectmethod": select,
+            "tools_paint_connect":      connect,
+            "tools_paint_contour":      contour,
+            "tools_paint_overlap":      overlap
         })
         })
         paint_tools = {}
         paint_tools = {}
 
 
@@ -217,7 +217,7 @@ class TclCommandPaint(TclCommand):
             tooluid += 1
             tooluid += 1
             paint_tools.update({
             paint_tools.update({
                 int(tooluid): {
                 int(tooluid): {
-                    'tooldia': float('%.*f' % (obj.decimals, tool)),
+                    'tooldia': self.app.dec_format(float(tool), self.app.decimals),
                     'offset': 'Path',
                     'offset': 'Path',
                     'offset_value': 0.0,
                     'offset_value': 0.0,
                     'type': 'Iso',
                     'type': 'Iso',
@@ -226,7 +226,7 @@ class TclCommandPaint(TclCommand):
                     'solid_geometry': []
                     'solid_geometry': []
                 }
                 }
             })
             })
-            paint_tools[int(tooluid)]['data']['tooldia'] = float('%.*f' % (obj.decimals, tool))
+            paint_tools[int(tooluid)]['data']['tooldia'] = self.app.dec_format(float(tool), self.app.decimals)
 
 
         if obj is None:
         if obj is None:
             return "Object not found: %s" % name
             return "Object not found: %s" % name
@@ -257,15 +257,17 @@ class TclCommandPaint(TclCommand):
                 x = coords_xy[0]
                 x = coords_xy[0]
                 y = coords_xy[1]
                 y = coords_xy[1]
 
 
-                self.app.paint_tool.paint_poly(obj=obj,
-                                               inside_pt=[x, y],
-                                               tooldia=tooldia,
-                                               order=order,
-                                               method=method,
-                                               outname=outname,
-                                               tools_storage=paint_tools,
-                                               plot=False,
-                                               run_threaded=False)
+                ret_val = self.app.paint_tool.paint_poly(obj=obj,
+                                                         inside_pt=[x, y],
+                                                         tooldia=tooldia,
+                                                         order=order,
+                                                         method=method,
+                                                         outname=outname,
+                                                         tools_storage=paint_tools,
+                                                         plot=False,
+                                                         run_threaded=False)
+                if ret_val == 'fail':
+                    return "Could not find a Polygon at the specified location."
             return
             return
 
 
         # Paint all polygons found within the box object from the the painted object
         # Paint all polygons found within the box object from the the painted object