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

- added protection against entering float numbers with comma separator instead of decimal dot separator in key points of FlatCAM (not everywhere)
- added a choice of plotting the kind of geometry for the CNC plot (all, travel and cut kind of geometries) in CNCJob Selected Tab

Marius Stanciu 7 лет назад
Родитель
Сommit
7607aad8d8

+ 3 - 2
FlatCAMApp.py

@@ -93,7 +93,7 @@ class App(QtCore.QObject):
 
 
     # Version
     # Version
     version = 8.906
     version = 8.906
-    version_date = "2019/02/2"
+    version_date = "2019/02/3"
     beta = True
     beta = True
 
 
     # URL for update checks and statistics
     # URL for update checks and statistics
@@ -1432,7 +1432,7 @@ class App(QtCore.QObject):
         self.move_tool.install(icon=QtGui.QIcon('share/move16.png'), pos=self.ui.menuedit,
         self.move_tool.install(icon=QtGui.QIcon('share/move16.png'), pos=self.ui.menuedit,
                                before=self.ui.menueditorigin)
                                before=self.ui.menueditorigin)
 
 
-        self.cutout_tool = ToolCutout(self)
+        self.cutout_tool = ToolCutOut(self)
         self.cutout_tool.install(icon=QtGui.QIcon('share/cut16.png'), pos=self.ui.menutool,
         self.cutout_tool.install(icon=QtGui.QIcon('share/cut16.png'), pos=self.ui.menutool,
                                  before=self.measurement_tool.menuAction)
                                  before=self.measurement_tool.menuAction)
 
 
@@ -1558,6 +1558,7 @@ class App(QtCore.QObject):
         elif isinstance(edited_obj, FlatCAMExcellon):
         elif isinstance(edited_obj, FlatCAMExcellon):
             obj_type = "Excellon"
             obj_type = "Excellon"
             self.exc_editor.update_fcexcellon(edited_obj)
             self.exc_editor.update_fcexcellon(edited_obj)
+            self.exc_editor.update_options(edited_obj)
             self.exc_editor.deactivate()
             self.exc_editor.deactivate()
 
 
             # update the exc object options so it is including the bounding box values
             # update the exc object options so it is including the bounding box values

+ 7 - 0
FlatCAMEditor.py

@@ -4471,6 +4471,13 @@ class FlatCAMExcEditor(QtCore.QObject):
         # Switch notebook to Selected page
         # Switch notebook to Selected page
         self.app.ui.notebook.setCurrentWidget(self.app.ui.selected_tab)
         self.app.ui.notebook.setCurrentWidget(self.app.ui.selected_tab)
 
 
+    def update_options(self, obj):
+        if not obj.options:
+            obj.options = {}
+            return True
+        else:
+            return False
+
     def new_edited_excellon(self, outname):
     def new_edited_excellon(self, outname):
         """
         """
         Creates a new Excellon object for the edited Excellon. Thread-safe.
         Creates a new Excellon object for the edited Excellon. Thread-safe.

+ 110 - 12
FlatCAMObj.py

@@ -2291,7 +2291,18 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
 
 
             for tooluid_key, tooluid_value in self.tools.items():
             for tooluid_key, tooluid_value in self.tools.items():
                 if int(tooluid_key) == tool_uid:
                 if int(tooluid_key) == tool_uid:
-                    tooluid_value['offset_value'] = self.ui.tool_offset_entry.get_value()
+                    try:
+                        tooluid_value['offset_value'] = float(self.ui.tool_offset_entry.get_value())
+                    except ValueError:
+                        # try to convert comma to decimal point. if it's still not working error message and return
+                        try:
+                            tooluid_value['offset_value'] = float(
+                                self.ui.tool_offset_entry.get_value().replace(',', '.')
+                            )
+                        except ValueError:
+                            self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                                                 "use a number.")
+                            return
 
 
     def ui_connect(self):
     def ui_connect(self):
 
 
@@ -2408,10 +2419,23 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
         last_data = None
         last_data = None
         last_solid_geometry = []
         last_solid_geometry = []
 
 
+        # if a Tool diameter entered is a char instead a number the final message of Tool adding is changed
+        # because the Default value for Tool is used.
+        change_message = False
+
         if dia is not None:
         if dia is not None:
             tooldia = dia
             tooldia = dia
         else:
         else:
-            tooldia = self.ui.addtool_entry.get_value()
+            try:
+                tooldia = float(self.ui.addtool_entry.get_value())
+            except ValueError:
+                # try to convert comma to decimal point. if it's still not working error message and return
+                try:
+                    tooldia = float(self.ui.addtool_entry.get_value().replace(',', '.'))
+                except ValueError:
+                    change_message = True
+                    tooldia = float(self.app.defaults["geometry_cnctooldia"])
+
             if tooldia is None:
             if tooldia is None:
                 self.build_ui()
                 self.build_ui()
                 self.app.inform.emit("[error_notcl] Please enter the desired tool diameter in Float format.")
                 self.app.inform.emit("[error_notcl] Please enter the desired tool diameter in Float format.")
@@ -2486,7 +2510,11 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
             pass
             pass
         self.ser_attrs.append('tools')
         self.ser_attrs.append('tools')
 
 
-        self.app.inform.emit("[success] Tool added in Tool Table.")
+        if change_message is False:
+            self.app.inform.emit("[success] Tool added in Tool Table.")
+        else:
+            change_message = False
+            self.app.inform.emit("[error_notcl]Default Tool added. Wrong value format entered.")
         self.build_ui()
         self.build_ui()
 
 
     def on_tool_copy(self, all=None):
     def on_tool_copy(self, all=None):
@@ -2556,7 +2584,18 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
         self.ui_disconnect()
         self.ui_disconnect()
 
 
         current_row = current_item.row()
         current_row = current_item.row()
-        tool_dia = float('%.4f' % float(self.ui.geo_tools_table.item(current_row, 1).text()))
+        try:
+            d = float(self.ui.geo_tools_table.item(current_row, 1).text())
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                d = float(self.ui.geo_tools_table.item(current_row, 1).text().replace(',', '.'))
+            except ValueError:
+                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                                     "use a number.")
+                return
+
+        tool_dia = float('%.4f' % d)
         tooluid = int(self.ui.geo_tools_table.item(current_row, 5).text())
         tooluid = int(self.ui.geo_tools_table.item(current_row, 5).text())
 
 
         self.tools[tooluid]['tooldia'] = tool_dia
         self.tools[tooluid]['tooldia'] = tool_dia
@@ -2823,7 +2862,17 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
         tool_type_item = self.ui.geo_tools_table.cellWidget(row, 4).currentText()
         tool_type_item = self.ui.geo_tools_table.cellWidget(row, 4).currentText()
         tooluid_item = int(self.ui.geo_tools_table.item(row, 5).text())
         tooluid_item = int(self.ui.geo_tools_table.item(row, 5).text())
 
 
-        offset_value_item = self.ui.tool_offset_entry.get_value()
+        try:
+            offset_value_item = float(self.ui.tool_offset_entry.get_value())
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                offset_value_item = float(self.ui.tool_offset_entry.get_value().replace(',', '.')
+                                     )
+            except ValueError:
+                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                                     "use a number.")
+                return
 
 
         # this new dict will hold the actual useful data, another dict that is the value of key 'data'
         # this new dict will hold the actual useful data, another dict that is the value of key 'data'
         temp_tools = {}
         temp_tools = {}
@@ -2965,7 +3014,16 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
         # test to see if we have tools available in the tool table
         # test to see if we have tools available in the tool table
         if self.ui.geo_tools_table.selectedItems():
         if self.ui.geo_tools_table.selectedItems():
             for x in self.ui.geo_tools_table.selectedItems():
             for x in self.ui.geo_tools_table.selectedItems():
-                tooldia = float(self.ui.geo_tools_table.item(x.row(), 1).text())
+                try:
+                    tooldia = float(self.ui.geo_tools_table.item(x.row(), 1).text())
+                except ValueError:
+                    # try to convert comma to decimal point. if it's still not working error message and return
+                    try:
+                        tooldia = float(self.ui.geo_tools_table.item(x.row(), 1).text().replace(',', '.'))
+                    except ValueError:
+                        self.app.inform.emit("[error_notcl]Wrong Tool Dia value format entered, "
+                                             "use a number.")
+                        return
                 tooluid = int(self.ui.geo_tools_table.item(x.row(), 5).text())
                 tooluid = int(self.ui.geo_tools_table.item(x.row(), 5).text())
 
 
                 for tooluid_key, tooluid_value in self.tools.items():
                 for tooluid_key, tooluid_value in self.tools.items():
@@ -3119,7 +3177,17 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
                     tool_offset = 0.0
                     tool_offset = 0.0
                 else:
                 else:
                     offset_str = 'custom'
                     offset_str = 'custom'
-                    offset_value = self.ui.tool_offset_entry.get_value()
+                    try:
+                        offset_value = float(self.ui.tool_offset_entry.get_value())
+                    except ValueError:
+                        # try to convert comma to decimal point. if it's still not working error message and return
+                        try:
+                            offset_value = float(self.ui.tool_offset_entry.get_value().replace(',', '.')
+                                                 )
+                        except ValueError:
+                            self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                                                 "use a number.")
+                            return
                     if offset_value:
                     if offset_value:
                         tool_offset = float(offset_value)
                         tool_offset = float(offset_value)
                     else:
                     else:
@@ -3296,7 +3364,17 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
                     tool_offset = 0.0
                     tool_offset = 0.0
                 else:
                 else:
                     offset_str = 'custom'
                     offset_str = 'custom'
-                    offset_value = self.ui.tool_offset_entry.get_value()
+                    try:
+                        offset_value = float(self.ui.tool_offset_entry.get_value())
+                    except ValueError:
+                        # try to convert comma to decimal point. if it's still not working error message and return
+                        try:
+                            offset_value = float(self.ui.tool_offset_entry.get_value().replace(',', '.')
+                                                  )
+                        except ValueError:
+                            self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                                                 "use a number.")
+                            return
                     if offset_value:
                     if offset_value:
                         tool_offset = float(offset_value)
                         tool_offset = float(offset_value)
                     else:
                     else:
@@ -3649,7 +3727,18 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
                     tool_dia_copy[dia_key] = dia_value
                     tool_dia_copy[dia_key] = dia_value
 
 
                     # convert the value in the Custom Tool Offset entry in UI
                     # convert the value in the Custom Tool Offset entry in UI
-                    custom_offset = self.ui.tool_offset_entry.get_value()
+                    try:
+                        custom_offset = float(self.ui.tool_offset_entry.get_value())
+                    except ValueError:
+                        # try to convert comma to decimal point. if it's still not working error message and return
+                        try:
+                            custom_offset = float(self.ui.tool_offset_entry.get_value().replace(',', '.')
+                            )
+                        except ValueError:
+                            self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                                                 "use a number.")
+                            return
+
                     if custom_offset:
                     if custom_offset:
                         custom_offset *= factor
                         custom_offset *= factor
                         self.ui.tool_offset_entry.set_value(custom_offset)
                         self.ui.tool_offset_entry.set_value(custom_offset)
@@ -3998,10 +4087,15 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
         # Fill form fields only on object create
         # Fill form fields only on object create
         self.to_form()
         self.to_form()
 
 
+        # set the kind of geometries are plotted by default with plot2() from camlib.CNCJob
+        self.ui.cncplot_method_combo.set_value('all')
+
         self.ui.updateplot_button.clicked.connect(self.on_updateplot_button_click)
         self.ui.updateplot_button.clicked.connect(self.on_updateplot_button_click)
         self.ui.export_gcode_button.clicked.connect(self.on_exportgcode_button_click)
         self.ui.export_gcode_button.clicked.connect(self.on_exportgcode_button_click)
         self.ui.modify_gcode_button.clicked.connect(self.on_modifygcode_button_click)
         self.ui.modify_gcode_button.clicked.connect(self.on_modifygcode_button_click)
 
 
+        self.ui.cncplot_method_combo.activated_custom.connect(self.on_plot_kind_change)
+
     def ui_connect(self):
     def ui_connect(self):
         for row in range(self.ui.cnc_tools_table.rowCount()):
         for row in range(self.ui.cnc_tools_table.rowCount()):
             self.ui.cnc_tools_table.cellWidget(row, 6).clicked.connect(self.on_plot_cb_click_table)
             self.ui.cnc_tools_table.cellWidget(row, 6).clicked.connect(self.on_plot_cb_click_table)
@@ -4024,6 +4118,10 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
         self.read_form()
         self.read_form()
         self.plot()
         self.plot()
 
 
+    def on_plot_kind_change(self):
+        kind = self.ui.cncplot_method_combo.get_value()
+        self.plot(kind=kind)
+
     def on_exportgcode_button_click(self, *args):
     def on_exportgcode_button_click(self, *args):
         self.app.report_usage("cncjob_on_exportgcode_button")
         self.app.report_usage("cncjob_on_exportgcode_button")
 
 
@@ -4280,7 +4378,7 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
         self.ui_connect()
         self.ui_connect()
 
 
 
 
-    def plot(self, visible=None):
+    def plot(self, visible=None, kind='all'):
 
 
         # Does all the required setup and returns False
         # Does all the required setup and returns False
         # if the 'ptint' option is set to False.
         # if the 'ptint' option is set to False.
@@ -4291,13 +4389,13 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
 
 
         try:
         try:
             if self.multitool is False: # single tool usage
             if self.multitool is False: # single tool usage
-                self.plot2(tooldia=self.options["tooldia"], obj=self, visible=visible)
+                self.plot2(tooldia=self.options["tooldia"], obj=self, visible=visible, kind=kind)
             else:
             else:
                 # multiple tools usage
                 # multiple tools usage
                 for tooluid_key in self.cnc_tools:
                 for tooluid_key in self.cnc_tools:
                     tooldia = float('%.4f' % float(self.cnc_tools[tooluid_key]['tooldia']))
                     tooldia = float('%.4f' % float(self.cnc_tools[tooluid_key]['tooldia']))
                     gcode_parsed = self.cnc_tools[tooluid_key]['gcode_parsed']
                     gcode_parsed = self.cnc_tools[tooluid_key]['gcode_parsed']
-                    self.plot2(tooldia=tooldia, obj=self, visible=visible, gcode_parsed=gcode_parsed)
+                    self.plot2(tooldia=tooldia, obj=self, visible=visible, gcode_parsed=gcode_parsed, kind=kind)
             self.shapes.redraw()
             self.shapes.redraw()
         except (ObjectDeleted, AttributeError):
         except (ObjectDeleted, AttributeError):
             self.shapes.clear(update=True)
             self.shapes.clear(update=True)

+ 26 - 11
ObjectUI.py

@@ -708,6 +708,8 @@ class GeometryObjectUI(ObjectUI):
         self.geo_tools_table.setColumnWidth(0, 20)
         self.geo_tools_table.setColumnWidth(0, 20)
         self.geo_tools_table.setHorizontalHeaderLabels(['#', 'Dia', 'Offset', 'Type', 'TT', '', 'P'])
         self.geo_tools_table.setHorizontalHeaderLabels(['#', 'Dia', 'Offset', 'Type', 'TT', '', 'P'])
         self.geo_tools_table.setColumnHidden(5, True)
         self.geo_tools_table.setColumnHidden(5, True)
+        # stylesheet = "::section{Background-color:rgb(239,239,245)}"
+        # self.geo_tools_table.horizontalHeader().setStyleSheet(stylesheet)
 
 
         self.geo_tools_table.horizontalHeaderItem(0).setToolTip(
         self.geo_tools_table.horizontalHeaderItem(0).setToolTip(
             "This is the Tool Number.\n"
             "This is the Tool Number.\n"
@@ -758,7 +760,7 @@ class GeometryObjectUI(ObjectUI):
             "cut and negative for 'inside' cut."
             "cut and negative for 'inside' cut."
         )
         )
         self.grid1.addWidget(self.tool_offset_lbl, 0, 0)
         self.grid1.addWidget(self.tool_offset_lbl, 0, 0)
-        self.tool_offset_entry = FloatEntry()
+        self.tool_offset_entry = FCEntry()
         spacer_lbl = QtWidgets.QLabel(" ")
         spacer_lbl = QtWidgets.QLabel(" ")
         spacer_lbl.setFixedWidth(80)
         spacer_lbl.setFixedWidth(80)
 
 
@@ -777,7 +779,7 @@ class GeometryObjectUI(ObjectUI):
         self.addtool_entry_lbl.setToolTip(
         self.addtool_entry_lbl.setToolTip(
             "Diameter for the new tool"
             "Diameter for the new tool"
         )
         )
-        self.addtool_entry = FloatEntry()
+        self.addtool_entry = FCEntry()
 
 
         # hlay.addWidget(self.addtool_label)
         # hlay.addWidget(self.addtool_label)
         # hlay.addStretch()
         # hlay.addStretch()
@@ -1067,15 +1069,26 @@ class CNCObjectUI(ObjectUI):
         self.plot_options_label = QtWidgets.QLabel("<b>Plot Options:</b>")
         self.plot_options_label = QtWidgets.QLabel("<b>Plot Options:</b>")
         self.custom_box.addWidget(self.plot_options_label)
         self.custom_box.addWidget(self.plot_options_label)
 
 
-        # # Tool dia for plot
-        # tdlabel = QtWidgets.QLabel('Tool dia:')
-        # tdlabel.setToolTip(
-        #     "Diameter of the tool to be\n"
-        #     "rendered in the plot."
-        # )
-        # grid0.addWidget(tdlabel, 1, 0)
-        # self.tooldia_entry = LengthEntry()
-        # grid0.addWidget(self.tooldia_entry, 1, 1)
+        self.cncplot_method_label = QtWidgets.QLabel("Plot kind:")
+        self.cncplot_method_label.setToolTip(
+            "This selects the kind of geometries on the canvas to plot.\n"
+            "Those can be either of type 'Travel' which means the moves\n"
+            "above the work piece or it can be of type 'Cut',\n"
+            "which means the moves that cut into the material."
+        )
+
+        self.cncplot_method_combo = RadioSet([
+            {"label": "All", "value": "all"},
+            {"label": "Travel", "value": "travel"},
+            {"label": "Cut", "value": "cut"}
+        ], stretch=False)
+
+        f_lay = QtWidgets.QFormLayout()
+        self.custom_box.addLayout(f_lay)
+        f_lay.addRow(self.cncplot_method_label, self.cncplot_method_combo)
+
+        e1_lbl = QtWidgets.QLabel('')
+        self.custom_box.addWidget(e1_lbl)
 
 
         hlay = QtWidgets.QHBoxLayout()
         hlay = QtWidgets.QHBoxLayout()
         self.custom_box.addLayout(hlay)
         self.custom_box.addLayout(hlay)
@@ -1115,6 +1128,8 @@ class CNCObjectUI(ObjectUI):
         self.cnc_tools_table.setColumnWidth(0, 20)
         self.cnc_tools_table.setColumnWidth(0, 20)
         self.cnc_tools_table.setHorizontalHeaderLabels(['#', 'Dia', 'Offset', 'Type', 'TT', '', 'P'])
         self.cnc_tools_table.setHorizontalHeaderLabels(['#', 'Dia', 'Offset', 'Type', 'TT', '', 'P'])
         self.cnc_tools_table.setColumnHidden(5, True)
         self.cnc_tools_table.setColumnHidden(5, True)
+        # stylesheet = "::section{Background-color:rgb(239,239,245)}"
+        # self.cnc_tools_table.horizontalHeader().setStyleSheet(stylesheet)
 
 
         # Update plot button
         # Update plot button
         self.updateplot_button = QtWidgets.QPushButton('Update Plot')
         self.updateplot_button = QtWidgets.QPushButton('Update Plot')

+ 2 - 0
README.md

@@ -13,6 +13,8 @@ CAD program, and create G-Code for Isolation routing.
 
 
 - code cleanup in Tools
 - code cleanup in Tools
 - some GUI structure optimization's
 - some GUI structure optimization's
+- added protection against entering float numbers with comma separator instead of decimal dot separator in key points of FlatCAM (not everywhere)
+- added a choice of plotting the kind of geometry for the CNC plot (all, travel and cut kind of geometries) in CNCJob Selected Tab
 
 
 1.02.2019
 1.02.2019
 
 

+ 20 - 3
camlib.py

@@ -5527,7 +5527,7 @@ class CNCjob(Geometry):
         
         
     def plot2(self, tooldia=None, dpi=75, margin=0.1, gcode_parsed=None,
     def plot2(self, tooldia=None, dpi=75, margin=0.1, gcode_parsed=None,
               color={"T": ["#F0E24D4C", "#B5AB3A4C"], "C": ["#5E6CFFFF", "#4650BDFF"]},
               color={"T": ["#F0E24D4C", "#B5AB3A4C"], "C": ["#5E6CFFFF", "#4650BDFF"]},
-              alpha={"T": 0.3, "C": 1.0}, tool_tolerance=0.0005, obj=None, visible=False):
+              alpha={"T": 0.3, "C": 1.0}, tool_tolerance=0.0005, obj=None, visible=False, kind='all'):
         """
         """
         Plots the G-code job onto the given axes.
         Plots the G-code job onto the given axes.
 
 
@@ -5548,7 +5548,15 @@ class CNCjob(Geometry):
 
 
         if tooldia == 0:
         if tooldia == 0:
             for geo in gcode_parsed:
             for geo in gcode_parsed:
-                obj.add_shape(shape=geo['geom'], color=color[geo['kind'][0]][1], visible=visible)
+                if kind == 'all':
+                    obj.add_shape(shape=geo['geom'], color=color[geo['kind'][0]][1], visible=visible)
+                elif kind == 'travel':
+                    if geo['kind'][0] == 'T':
+                        obj.add_shape(shape=geo['geom'], color=color['T'][1], visible=visible)
+                elif kind == 'cut':
+                    if geo['kind'][0] == 'C':
+                        obj.add_shape(shape=geo['geom'], color=color['C'][1], visible=visible)
+
         else:
         else:
             text = []
             text = []
             pos = []
             pos = []
@@ -5559,8 +5567,17 @@ class CNCjob(Geometry):
                 pos.append(geo['geom'].coords[0])
                 pos.append(geo['geom'].coords[0])
 
 
                 poly = geo['geom'].buffer(tooldia / 2.0).simplify(tool_tolerance)
                 poly = geo['geom'].buffer(tooldia / 2.0).simplify(tool_tolerance)
-                obj.add_shape(shape=poly, color=color[geo['kind'][0]][1], face_color=color[geo['kind'][0]][0],
+                if kind == 'all':
+                    obj.add_shape(shape=poly, color=color[geo['kind'][0]][1], face_color=color[geo['kind'][0]][0],
                               visible=visible, layer=1 if geo['kind'][0] == 'C' else 2)
                               visible=visible, layer=1 if geo['kind'][0] == 'C' else 2)
+                elif kind == 'travel':
+                    if geo['kind'][0] == 'T':
+                        obj.add_shape(shape=poly, color=color['T'][1], face_color=color['T'][0],
+                                      visible=visible, layer=2)
+                elif kind == 'cut':
+                    if geo['kind'][0] == 'C':
+                        obj.add_shape(shape=poly, color=color['C'][1], face_color=color['C'][0],
+                                      visible=visible, layer=1)
 
 
             obj.annotation.set(text=text, pos=pos, visible=obj.options['plot'])
             obj.annotation.set(text=text, pos=pos, visible=obj.options['plot'])
 
 

+ 74 - 7
flatcamTools/ToolCalculators.py

@@ -255,10 +255,37 @@ class ToolCalculator(FlatCAMTool):
 
 
         try:
         try:
             tip_diameter = float(self.tipDia_entry.get_value())
             tip_diameter = float(self.tipDia_entry.get_value())
-            half_tip_angle = float(self.tipAngle_entry.get_value()) / 2
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                tip_diameter = float(self.tipDia_entry.get_value().replace(',', '.'))
+            except ValueError:
+                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                                     "use a number.")
+                return
+
+        try:
+            half_tip_angle = float(self.tipAngle_entry.get_value())
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                half_tip_angle = float(self.tipAngle_entry.get_value().replace(',', '.'))
+            except ValueError:
+                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                                     "use a number.")
+                return
+        half_tip_angle /= 2
+
+        try:
             cut_depth = float(self.cutDepth_entry.get_value())
             cut_depth = float(self.cutDepth_entry.get_value())
-        except:
-            return
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                cut_depth = float(self.cutDepth_entry.get_value().replace(',', '.'))
+            except ValueError:
+                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                                     "use a number.")
+                return
 
 
         tool_diameter = tip_diameter + (2 * cut_depth * math.tan(math.radians(half_tip_angle)))
         tool_diameter = tip_diameter + (2 * cut_depth * math.tan(math.radians(half_tip_angle)))
         self.effectiveToolDia_entry.set_value("%.4f" % tool_diameter)
         self.effectiveToolDia_entry.set_value("%.4f" % tool_diameter)
@@ -270,10 +297,50 @@ class ToolCalculator(FlatCAMTool):
         self.mm_entry.set_value('%.6f' % (float(self.inch_entry.get_value()) * 25.4))
         self.mm_entry.set_value('%.6f' % (float(self.inch_entry.get_value()) * 25.4))
 
 
     def on_calculate_eplate(self):
     def on_calculate_eplate(self):
-        length = float(self.pcblength_entry.get_value())
-        width = float(self.pcbwidth_entry.get_value())
-        density = float(self.cdensity_entry.get_value())
-        copper = float(self.growth_entry.get_value())
+
+        try:
+            length = float(self.pcblength_entry.get_value())
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                length = float(self.pcblength_entry.get_value().replace(',', '.'))
+            except ValueError:
+                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                                     "use a number.")
+                return
+
+        try:
+            width = float(self.pcbwidth_entry.get_value())
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                width = float(self.pcbwidth_entry.get_value().replace(',', '.'))
+            except ValueError:
+                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                                     "use a number.")
+                return
+
+        try:
+            density = float(self.cdensity_entry.get_value())
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                density = float(self.cdensity_entry.get_value().replace(',', '.'))
+            except ValueError:
+                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                                     "use a number.")
+                return
+
+        try:
+            copper = float(self.growth_entry.get_value())
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                copper = float(self.growth_entry.get_value().replace(',', '.'))
+            except ValueError:
+                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                                     "use a number.")
+                return
 
 
         calculated_current = (length * width * density) * 0.0021527820833419
         calculated_current = (length * width * density) * 0.0021527820833419
         calculated_time = copper * 2.142857142857143 * float(20 / density)
         calculated_time = copper * 2.142857142857143 * float(20 / density)

+ 55 - 19
flatcamTools/ToolCutout.py → flatcamTools/ToolCutOut.py

@@ -8,7 +8,7 @@ from GUIElements import IntEntry, RadioSet, LengthEntry
 from FlatCAMObj import FlatCAMGeometry, FlatCAMExcellon, FlatCAMGerber
 from FlatCAMObj import FlatCAMGeometry, FlatCAMExcellon, FlatCAMGerber
 
 
 
 
-class ToolCutout(FlatCAMTool):
+class ToolCutOut(FlatCAMTool):
 
 
     toolName = "Cutout PCB"
     toolName = "Cutout PCB"
 
 
@@ -228,19 +228,37 @@ class ToolCutout(FlatCAMTool):
 
 
         try:
         try:
             dia = float(self.dia.get_value())
             dia = float(self.dia.get_value())
-        except TypeError:
-            self.app.inform.emit("[warning_notcl] Tool diameter value is missing. Add it and retry.")
-            return
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                dia = float(self.dia.get_value().replace(',', '.'))
+            except ValueError:
+                self.app.inform.emit("[warning_notcl] Tool diameter value is missing or wrong format. "
+                                     "Add it and retry.")
+                return
+
         try:
         try:
             margin = float(self.margin.get_value())
             margin = float(self.margin.get_value())
-        except TypeError:
-            self.app.inform.emit("[warning_notcl] Margin value is missing. Add it and retry.")
-            return
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                margin = float(self.margin.get_value().replace(',', '.'))
+            except ValueError:
+                self.app.inform.emit("[warning_notcl] Margin value is missing or wrong format. "
+                                     "Add it and retry.")
+                return
+
         try:
         try:
             gapsize = float(self.gapsize.get_value())
             gapsize = float(self.gapsize.get_value())
-        except TypeError:
-            self.app.inform.emit("[warning_notcl] Gap size value is missing. Add it and retry.")
-            return
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                gapsize = float(self.gapsize.get_value().replace(',', '.'))
+            except ValueError:
+                self.app.inform.emit("[warning_notcl] Gap size value is missing or wrong format. "
+                                     "Add it and retry.")
+                return
+
         try:
         try:
             gaps = self.gaps.get_value()
             gaps = self.gaps.get_value()
         except TypeError:
         except TypeError:
@@ -349,19 +367,37 @@ class ToolCutout(FlatCAMTool):
 
 
         try:
         try:
             dia = float(self.dia.get_value())
             dia = float(self.dia.get_value())
-        except TypeError:
-            self.app.inform.emit("[warning_notcl] Tool diameter value is missing. Add it and retry.")
-            return
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                dia = float(self.dia.get_value().replace(',', '.'))
+            except ValueError:
+                self.app.inform.emit("[warning_notcl] Tool diameter value is missing or wrong format. "
+                                     "Add it and retry.")
+                return
+
         try:
         try:
             margin = float(self.margin.get_value())
             margin = float(self.margin.get_value())
-        except TypeError:
-            self.app.inform.emit("[warning_notcl] Margin value is missing. Add it and retry.")
-            return
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                margin = float(self.margin.get_value().replace(',', '.'))
+            except ValueError:
+                self.app.inform.emit("[warning_notcl] Margin value is missing or wrong format. "
+                                     "Add it and retry.")
+                return
+
         try:
         try:
             gapsize = float(self.gapsize.get_value())
             gapsize = float(self.gapsize.get_value())
-        except TypeError:
-            self.app.inform.emit("[warning_notcl] Gap size value is missing. Add it and retry.")
-            return
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                gapsize = float(self.gapsize.get_value().replace(',', '.'))
+            except ValueError:
+                self.app.inform.emit("[warning_notcl] Gap size value is missing or wrong format. "
+                                     "Add it and retry.")
+                return
+
         try:
         try:
             gaps = self.gaps_rect_radio.get_value()
             gaps = self.gaps_rect_radio.get_value()
         except TypeError:
         except TypeError:

+ 27 - 22
flatcamTools/ToolDblSided.py

@@ -6,6 +6,7 @@ from shapely.geometry import Point
 from shapely import affinity
 from shapely import affinity
 from PyQt5 import QtCore
 from PyQt5 import QtCore
 
 
+
 class DblSidedTool(FlatCAMTool):
 class DblSidedTool(FlatCAMTool):
 
 
     toolName = "2-Sided PCB"
     toolName = "2-Sided PCB"
@@ -113,8 +114,8 @@ class DblSidedTool(FlatCAMTool):
         self.axloc_label = QtWidgets.QLabel("Axis Ref:")
         self.axloc_label = QtWidgets.QLabel("Axis Ref:")
         self.axloc_label.setToolTip(
         self.axloc_label.setToolTip(
             "The axis should pass through a <b>point</b> or cut\n "
             "The axis should pass through a <b>point</b> or cut\n "
-            "a specified <b>box</b> (in a Geometry object) in \n"
-            "the middle."
+            "a specified <b>box</b> (in a FlatCAM object) through \n"
+            "the center."
         )
         )
         # grid_lay.addRow("Axis Location:", self.axis_location)
         # grid_lay.addRow("Axis Location:", self.axis_location)
         grid_lay.addWidget(self.axloc_label, 8, 0)
         grid_lay.addWidget(self.axloc_label, 8, 0)
@@ -127,19 +128,18 @@ class DblSidedTool(FlatCAMTool):
         self.point_box_container = QtWidgets.QVBoxLayout()
         self.point_box_container = QtWidgets.QVBoxLayout()
         self.pb_label = QtWidgets.QLabel("<b>Point/Box:</b>")
         self.pb_label = QtWidgets.QLabel("<b>Point/Box:</b>")
         self.pb_label.setToolTip(
         self.pb_label.setToolTip(
-            "Specify the point (x, y) through which the mirror axis \n "
-            "passes or the Geometry object containing a rectangle \n"
-            "that the mirror axis cuts in half."
+            "If 'Point' is selected above it store the coordinates (x, y) through which\n"
+            "the mirroring axis passes.\n"
+            "If 'Box' is selected above, select here a FlatCAM object (Gerber, Exc or Geo).\n"
+            "Through the center of this object pass the mirroring axis selected above."
         )
         )
-        # grid_lay.addRow("Point/Box:", self.point_box_container)
 
 
         self.add_point_button = QtWidgets.QPushButton("Add")
         self.add_point_button = QtWidgets.QPushButton("Add")
         self.add_point_button.setToolTip(
         self.add_point_button.setToolTip(
-            "Add the <b>point (x, y)</b> through which the mirror axis \n "
-            "passes or the Object containing a rectangle \n"
-            "that the mirror axis cuts in half.\n"
-            "The point is captured by pressing SHIFT key\n"
-            "and left mouse clicking on canvas or you can enter them manually."
+            "Add the coordinates in format <b>(x, y)</b> through which the mirroring axis \n "
+            "selected in 'MIRROR AXIS' pass.\n"
+            "The (x, y) coordinates are captured by pressing SHIFT key\n"
+            "and left mouse button click on canvas or you can enter the coords manually."
         )
         )
         self.add_point_button.setFixedWidth(40)
         self.add_point_button.setFixedWidth(40)
 
 
@@ -171,9 +171,9 @@ class DblSidedTool(FlatCAMTool):
         self.ah_label.setToolTip(
         self.ah_label.setToolTip(
             "Alignment holes (x1, y1), (x2, y2), ... "
             "Alignment holes (x1, y1), (x2, y2), ... "
             "on one side of the mirror axis. For each set of (x, y) coordinates\n"
             "on one side of the mirror axis. For each set of (x, y) coordinates\n"
-            "entered here, a pair of drills will be created: one on the\n"
-            "coordinates entered and one in mirror position over the axis\n"
-            "selected above in the 'Mirror Axis'."
+            "entered here, a pair of drills will be created:\n\n"
+            "- one drill at the coordinates from the field\n"
+            "- one drill in mirror position over the axis selected above in the 'Mirror Axis'."
         )
         )
         self.layout.addWidget(self.ah_label)
         self.layout.addWidget(self.ah_label)
 
 
@@ -184,10 +184,13 @@ class DblSidedTool(FlatCAMTool):
 
 
         self.add_drill_point_button = QtWidgets.QPushButton("Add")
         self.add_drill_point_button = QtWidgets.QPushButton("Add")
         self.add_drill_point_button.setToolTip(
         self.add_drill_point_button.setToolTip(
-            "Add alignment drill holes coords (x1, y1), (x2, y2), ... \n"
-            "on one side of the mirror axis.\n"
-            "The point(s) can be captured by pressing SHIFT key\n"
-            "and left mouse clicking on canvas. Or you can enter them manually."
+            "Add alignment drill holes coords in the format: (x1, y1), (x2, y2), ... \n"
+            "on one side of the mirror axis.\n\n"
+            "The coordinates set can be obtained:\n"
+            "- press SHIFT key and left mouse clicking on canvas. Then click Add.\n"
+            "- press SHIFT key and left mouse clicking on canvas. Then CTRL+V in the field.\n"
+            "- press SHIFT key and left mouse clicking on canvas. Then RMB click in the field and click Paste.\n"
+            "- by entering the coords manually in the format: (x1, y1), (x2, y2), ..."
         )
         )
         self.add_drill_point_button.setFixedWidth(40)
         self.add_drill_point_button.setFixedWidth(40)
 
 
@@ -195,11 +198,10 @@ class DblSidedTool(FlatCAMTool):
         grid_lay1.addWidget(self.add_drill_point_button, 0, 3)
         grid_lay1.addWidget(self.add_drill_point_button, 0, 3)
 
 
         ## Drill diameter for alignment holes
         ## Drill diameter for alignment holes
-        self.dt_label = QtWidgets.QLabel("<b>Alignment Drill Creation</b>:")
+        self.dt_label = QtWidgets.QLabel("<b>Alignment Drill Diameter</b>:")
         self.dt_label.setToolTip(
         self.dt_label.setToolTip(
-            "Create a set of alignment drill holes\n"
-            "with the specified diameter,\n"
-            "at the specified coordinates."
+            "Diameter of the drill for the "
+            "alignment holes."
         )
         )
         self.layout.addWidget(self.dt_label)
         self.layout.addWidget(self.dt_label)
 
 
@@ -295,6 +297,9 @@ class DblSidedTool(FlatCAMTool):
         xscale, yscale = {"X": (1.0, -1.0), "Y": (-1.0, 1.0)}[axis]
         xscale, yscale = {"X": (1.0, -1.0), "Y": (-1.0, 1.0)}[axis]
 
 
         dia = self.drill_dia.get_value()
         dia = self.drill_dia.get_value()
+        if dia is None:
+            self.app.inform.emit("[warning_notcl]No value or wrong format in Drill Dia entry. Add it and retry.")
+            return
         tools = {"1": {"C": dia}}
         tools = {"1": {"C": dia}}
 
 
         # holes = self.alignment_holes.get_value()
         # holes = self.alignment_holes.get_value()

+ 13 - 3
flatcamTools/ToolFilm.py

@@ -1,6 +1,6 @@
 from FlatCAMTool import FlatCAMTool
 from FlatCAMTool import FlatCAMTool
 
 
-from GUIElements import RadioSet, FloatEntry
+from GUIElements import RadioSet, FCEntry
 from PyQt5 import QtGui, QtCore, QtWidgets
 from PyQt5 import QtGui, QtCore, QtWidgets
 
 
 
 
@@ -99,7 +99,7 @@ class Film(FlatCAMTool):
 
 
         # Boundary for negative film generation
         # Boundary for negative film generation
 
 
-        self.boundary_entry = FloatEntry()
+        self.boundary_entry = FCEntry()
         self.boundary_label = QtWidgets.QLabel("Border:")
         self.boundary_label = QtWidgets.QLabel("Border:")
         self.boundary_label.setToolTip(
         self.boundary_label.setToolTip(
             "Specify a border around the object.\n"
             "Specify a border around the object.\n"
@@ -172,7 +172,17 @@ class Film(FlatCAMTool):
             self.app.inform.emit("[error_notcl] No Box object selected. Load a Box object and retry.")
             self.app.inform.emit("[error_notcl] No Box object selected. Load a Box object and retry.")
             return
             return
 
 
-        border = float(self.boundary_entry.get_value())
+        try:
+            border = float(self.boundary_entry.get_value())
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                border = float(self.boundary_entry.get_value().replace(',', '.'))
+            except ValueError:
+                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                                     "use a number.")
+                return
+
         if border is None:
         if border is None:
             border = 0
             border = 0
 
 

+ 45 - 7
flatcamTools/ToolNonCopperClear.py

@@ -96,7 +96,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
         self.addtool_entry_lbl.setToolTip(
         self.addtool_entry_lbl.setToolTip(
             "Diameter for the new tool to add in the Tool Table"
             "Diameter for the new tool to add in the Tool Table"
         )
         )
-        self.addtool_entry = FloatEntry()
+        self.addtool_entry = FCEntry()
 
 
         # hlay.addWidget(self.addtool_label)
         # hlay.addWidget(self.addtool_label)
         # hlay.addStretch()
         # hlay.addStretch()
@@ -150,7 +150,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
             "due of too many paths."
             "due of too many paths."
         )
         )
         grid3.addWidget(nccoverlabel, 1, 0)
         grid3.addWidget(nccoverlabel, 1, 0)
-        self.ncc_overlap_entry = FloatEntry()
+        self.ncc_overlap_entry = FCEntry()
         grid3.addWidget(self.ncc_overlap_entry, 1, 1)
         grid3.addWidget(self.ncc_overlap_entry, 1, 1)
 
 
         nccmarginlabel = QtWidgets.QLabel('Margin:')
         nccmarginlabel = QtWidgets.QLabel('Margin:')
@@ -158,7 +158,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
             "Bounding box margin."
             "Bounding box margin."
         )
         )
         grid3.addWidget(nccmarginlabel, 2, 0)
         grid3.addWidget(nccmarginlabel, 2, 0)
-        self.ncc_margin_entry = FloatEntry()
+        self.ncc_margin_entry = FCEntry()
         grid3.addWidget(self.ncc_margin_entry, 2, 1)
         grid3.addWidget(self.ncc_margin_entry, 2, 1)
 
 
         # Method
         # Method
@@ -430,7 +430,16 @@ class NonCopperClear(FlatCAMTool, Gerber):
         if dia:
         if dia:
             tool_dia = dia
             tool_dia = dia
         else:
         else:
-            tool_dia = self.addtool_entry.get_value()
+            try:
+                tool_dia = float(self.addtool_entry.get_value())
+            except ValueError:
+                # try to convert comma to decimal point. if it's still not working error message and return
+                try:
+                    tool_dia = float(self.addtool_entry.get_value().replace(',', '.'))
+                except ValueError:
+                    self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                                         "use a number.")
+                    return
             if tool_dia is None:
             if tool_dia is None:
                 self.build_ui()
                 self.build_ui()
                 self.app.inform.emit("[warning_notcl] Please enter a tool diameter to add, in Float format.")
                 self.app.inform.emit("[warning_notcl] Please enter a tool diameter to add, in Float format.")
@@ -487,7 +496,18 @@ class NonCopperClear(FlatCAMTool, Gerber):
                     tool_dias.append(float('%.4f' % v[tool_v]))
                     tool_dias.append(float('%.4f' % v[tool_v]))
 
 
         for row in range(self.tools_table.rowCount()):
         for row in range(self.tools_table.rowCount()):
-            new_tool_dia = float(self.tools_table.item(row, 1).text())
+
+            try:
+                new_tool_dia = float(self.tools_table.item(row, 1).text())
+            except ValueError:
+                # try to convert comma to decimal point. if it's still not working error message and return
+                try:
+                    new_tool_dia = float(self.tools_table.item(row, 1).text().replace(',', '.'))
+                except ValueError:
+                    self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                                         "use a number.")
+                    return
+
             tooluid = int(self.tools_table.item(row, 3).text())
             tooluid = int(self.tools_table.item(row, 3).text())
 
 
             # identify the tool that was edited and get it's tooluid
             # identify the tool that was edited and get it's tooluid
@@ -553,10 +573,28 @@ class NonCopperClear(FlatCAMTool, Gerber):
 
 
     def on_ncc(self):
     def on_ncc(self):
 
 
-        over = self.ncc_overlap_entry.get_value()
+        try:
+            over = float(self.ncc_overlap_entry.get_value())
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                over = float(self.ncc_overlap_entry.get_value().replace(',', '.'))
+            except ValueError:
+                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                                     "use a number.")
+                return
         over = over if over else self.app.defaults["tools_nccoverlap"]
         over = over if over else self.app.defaults["tools_nccoverlap"]
 
 
-        margin = self.ncc_margin_entry.get_value()
+        try:
+            margin = float(self.ncc_margin_entry.get_value())
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                margin = float(self.ncc_margin_entry.get_value().replace(',', '.'))
+            except ValueError:
+                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                                     "use a number.")
+                return
         margin = margin if margin else self.app.defaults["tools_nccmargin"]
         margin = margin if margin else self.app.defaults["tools_nccmargin"]
 
 
         connect = self.ncc_connect_cb.get_value()
         connect = self.ncc_connect_cb.get_value()

+ 56 - 9
flatcamTools/ToolPaint.py

@@ -93,7 +93,7 @@ class ToolPaint(FlatCAMTool, Gerber):
         self.addtool_entry_lbl.setToolTip(
         self.addtool_entry_lbl.setToolTip(
             "Diameter for the new tool."
             "Diameter for the new tool."
         )
         )
-        self.addtool_entry = FloatEntry()
+        self.addtool_entry = FCEntry()
 
 
         # hlay.addWidget(self.addtool_label)
         # hlay.addWidget(self.addtool_label)
         # hlay.addStretch()
         # hlay.addStretch()
@@ -145,7 +145,7 @@ class ToolPaint(FlatCAMTool, Gerber):
             "due of too many paths."
             "due of too many paths."
         )
         )
         grid3.addWidget(ovlabel, 1, 0)
         grid3.addWidget(ovlabel, 1, 0)
-        self.paintoverlap_entry = LengthEntry()
+        self.paintoverlap_entry = FCEntry()
         grid3.addWidget(self.paintoverlap_entry, 1, 1)
         grid3.addWidget(self.paintoverlap_entry, 1, 1)
 
 
         # Margin
         # Margin
@@ -156,7 +156,7 @@ class ToolPaint(FlatCAMTool, Gerber):
             "be painted."
             "be painted."
         )
         )
         grid3.addWidget(marginlabel, 2, 0)
         grid3.addWidget(marginlabel, 2, 0)
-        self.paintmargin_entry = LengthEntry()
+        self.paintmargin_entry = FCEntry()
         grid3.addWidget(self.paintmargin_entry, 2, 1)
         grid3.addWidget(self.paintmargin_entry, 2, 1)
 
 
         # Method
         # Method
@@ -486,7 +486,17 @@ class ToolPaint(FlatCAMTool, Gerber):
         if dia:
         if dia:
             tool_dia = dia
             tool_dia = dia
         else:
         else:
-            tool_dia = self.addtool_entry.get_value()
+            try:
+                tool_dia = float(self.addtool_entry.get_value())
+            except ValueError:
+                # try to convert comma to decimal point. if it's still not working error message and return
+                try:
+                    tool_dia = float(self.addtool_entry.get_value().replace(',', '.'))
+                except ValueError:
+                    self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                                         "use a number.")
+                    return
+
             if tool_dia is None:
             if tool_dia is None:
                 self.build_ui()
                 self.build_ui()
                 self.app.inform.emit("[warning_notcl] Please enter a tool diameter to add, in Float format.")
                 self.app.inform.emit("[warning_notcl] Please enter a tool diameter to add, in Float format.")
@@ -546,7 +556,16 @@ class ToolPaint(FlatCAMTool, Gerber):
                     tool_dias.append(float('%.4f' % v[tool_v]))
                     tool_dias.append(float('%.4f' % v[tool_v]))
 
 
         for row in range(self.tools_table.rowCount()):
         for row in range(self.tools_table.rowCount()):
-            new_tool_dia = float(self.tools_table.item(row, 1).text())
+            try:
+                new_tool_dia = float(self.tools_table.item(row, 1).text())
+            except ValueError:
+                # try to convert comma to decimal point. if it's still not working error message and return
+                try:
+                    new_tool_dia = float(self.tools_table.item(row, 1).text().replace(',', '.'))
+                except ValueError:
+                    self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                                         "use a number.")
+                    return
             tooluid = int(self.tools_table.item(row, 3).text())
             tooluid = int(self.tools_table.item(row, 3).text())
 
 
             # identify the tool that was edited and get it's tooluid
             # identify the tool that was edited and get it's tooluid
@@ -672,8 +691,17 @@ class ToolPaint(FlatCAMTool, Gerber):
         self.app.report_usage("geometry_on_paint_button")
         self.app.report_usage("geometry_on_paint_button")
 
 
         self.app.inform.emit("[warning_notcl]Click inside the desired polygon.")
         self.app.inform.emit("[warning_notcl]Click inside the desired polygon.")
+        try:
+            overlap = float(self.paintoverlap_entry.get_value())
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                overlap = float(self.paintoverlap_entry.get_value().replace(',', '.'))
+            except ValueError:
+                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                                     "use a number.")
+                return
 
 
-        overlap = self.paintoverlap_entry.get_value()
         connect = self.pathconnect_cb.get_value()
         connect = self.pathconnect_cb.get_value()
         contour = self.paintcontour_cb.get_value()
         contour = self.paintcontour_cb.get_value()
         select_method = self.selectmethod_combo.get_value()
         select_method = self.selectmethod_combo.get_value()
@@ -744,7 +772,17 @@ class ToolPaint(FlatCAMTool, Gerber):
         # poly = find_polygon(self.solid_geometry, inside_pt)
         # poly = find_polygon(self.solid_geometry, inside_pt)
         poly = obj.find_polygon(inside_pt)
         poly = obj.find_polygon(inside_pt)
         paint_method = self.paintmethod_combo.get_value()
         paint_method = self.paintmethod_combo.get_value()
-        paint_margin = self.paintmargin_entry.get_value()
+
+        try:
+            paint_margin = float(self.paintmargin_entry.get_value())
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                paint_margin = float(self.paintmargin_entry.get_value().replace(',', '.'))
+            except ValueError:
+                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                                     "use a number.")
+                return
 
 
         # No polygon?
         # No polygon?
         if poly is None:
         if poly is None:
@@ -878,10 +916,19 @@ class ToolPaint(FlatCAMTool, Gerber):
         :return:
         :return:
         """
         """
         paint_method = self.paintmethod_combo.get_value()
         paint_method = self.paintmethod_combo.get_value()
-        paint_margin = self.paintmargin_entry.get_value()
 
 
-        proc = self.app.proc_container.new("Painting polygon.")
+        try:
+            paint_margin = float(self.paintmargin_entry.get_value())
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                paint_margin = float(self.paintmargin_entry.get_value().replace(',', '.'))
+            except ValueError:
+                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                                     "use a number.")
+                return
 
 
+        proc = self.app.proc_container.new("Painting polygon.")
         name = outname if outname else self.obj_name + "_paint"
         name = outname if outname else self.obj_name + "_paint"
         over = overlap
         over = overlap
         conn = connect
         conn = connect

+ 69 - 12
flatcamTools/ToolPanelize.py

@@ -82,7 +82,7 @@ class Panelize(FlatCAMTool):
         form_layout.addRow(self.box_combo_label, self.box_combo)
         form_layout.addRow(self.box_combo_label, self.box_combo)
 
 
         ## Spacing Columns
         ## Spacing Columns
-        self.spacing_columns = FloatEntry()
+        self.spacing_columns = FCEntry()
         self.spacing_columns_label = QtWidgets.QLabel("Spacing cols:")
         self.spacing_columns_label = QtWidgets.QLabel("Spacing cols:")
         self.spacing_columns_label.setToolTip(
         self.spacing_columns_label.setToolTip(
             "Spacing between columns of the desired panel.\n"
             "Spacing between columns of the desired panel.\n"
@@ -91,7 +91,7 @@ class Panelize(FlatCAMTool):
         form_layout.addRow(self.spacing_columns_label, self.spacing_columns)
         form_layout.addRow(self.spacing_columns_label, self.spacing_columns)
 
 
         ## Spacing Rows
         ## Spacing Rows
-        self.spacing_rows = FloatEntry()
+        self.spacing_rows = FCEntry()
         self.spacing_rows_label = QtWidgets.QLabel("Spacing rows:")
         self.spacing_rows_label = QtWidgets.QLabel("Spacing rows:")
         self.spacing_rows_label.setToolTip(
         self.spacing_rows_label.setToolTip(
             "Spacing between rows of the desired panel.\n"
             "Spacing between rows of the desired panel.\n"
@@ -100,7 +100,7 @@ class Panelize(FlatCAMTool):
         form_layout.addRow(self.spacing_rows_label, self.spacing_rows)
         form_layout.addRow(self.spacing_rows_label, self.spacing_rows)
 
 
         ## Columns
         ## Columns
-        self.columns = IntEntry()
+        self.columns = FCEntry()
         self.columns_label = QtWidgets.QLabel("Columns:")
         self.columns_label = QtWidgets.QLabel("Columns:")
         self.columns_label.setToolTip(
         self.columns_label.setToolTip(
             "Number of columns of the desired panel"
             "Number of columns of the desired panel"
@@ -108,7 +108,7 @@ class Panelize(FlatCAMTool):
         form_layout.addRow(self.columns_label, self.columns)
         form_layout.addRow(self.columns_label, self.columns)
 
 
         ## Rows
         ## Rows
-        self.rows = IntEntry()
+        self.rows = FCEntry()
         self.rows_label = QtWidgets.QLabel("Rows:")
         self.rows_label = QtWidgets.QLabel("Rows:")
         self.rows_label.setToolTip(
         self.rows_label.setToolTip(
             "Number of rows of the desired panel"
             "Number of rows of the desired panel"
@@ -126,7 +126,7 @@ class Panelize(FlatCAMTool):
         )
         )
         form_layout.addRow(self.constrain_cb)
         form_layout.addRow(self.constrain_cb)
 
 
-        self.x_width_entry = FloatEntry()
+        self.x_width_entry = FCEntry()
         self.x_width_lbl = QtWidgets.QLabel("Width (DX):")
         self.x_width_lbl = QtWidgets.QLabel("Width (DX):")
         self.x_width_lbl.setToolTip(
         self.x_width_lbl.setToolTip(
             "The width (DX) within which the panel must fit.\n"
             "The width (DX) within which the panel must fit.\n"
@@ -134,7 +134,7 @@ class Panelize(FlatCAMTool):
         )
         )
         form_layout.addRow(self.x_width_lbl, self.x_width_entry)
         form_layout.addRow(self.x_width_lbl, self.x_width_entry)
 
 
-        self.y_height_entry = FloatEntry()
+        self.y_height_entry = FCEntry()
         self.y_height_lbl = QtWidgets.QLabel("Height (DY):")
         self.y_height_lbl = QtWidgets.QLabel("Height (DY):")
         self.y_height_lbl.setToolTip(
         self.y_height_lbl.setToolTip(
             "The height (DY)within which the panel must fit.\n"
             "The height (DY)within which the panel must fit.\n"
@@ -237,20 +237,77 @@ class Panelize(FlatCAMTool):
 
 
         self.outname = name + '_panelized'
         self.outname = name + '_panelized'
 
 
-        spacing_columns = self.spacing_columns.get_value()
+        try:
+            spacing_columns = float(self.spacing_columns.get_value())
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                spacing_columns = float(self.spacing_columns.get_value().replace(',', '.'))
+            except ValueError:
+                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                                     "use a number.")
+                return
         spacing_columns = spacing_columns if spacing_columns is not None else 0
         spacing_columns = spacing_columns if spacing_columns is not None else 0
 
 
-        spacing_rows = self.spacing_rows.get_value()
+        try:
+            spacing_rows = float(self.spacing_rows.get_value())
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                spacing_rows = float(self.spacing_rows.get_value().replace(',', '.'))
+            except ValueError:
+                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                                     "use a number.")
+                return
         spacing_rows = spacing_rows if spacing_rows is not None else 0
         spacing_rows = spacing_rows if spacing_rows is not None else 0
 
 
-        rows = self.rows.get_value()
+        try:
+            rows = int(self.rows.get_value())
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                rows = float(self.rows.get_value().replace(',', '.'))
+                rows = int(rows)
+            except ValueError:
+                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                                     "use a number.")
+                return
         rows = rows if rows is not None else 1
         rows = rows if rows is not None else 1
 
 
-        columns = self.columns.get_value()
+        try:
+            columns = int(self.columns.get_value())
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                columns = float(self.columns.get_value().replace(',', '.'))
+                columns = int(columns)
+            except ValueError:
+                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                                     "use a number.")
+                return
         columns = columns if columns is not None else 1
         columns = columns if columns is not None else 1
 
 
-        constrain_dx = self.x_width_entry.get_value()
-        constrain_dy = self.y_height_entry.get_value()
+        try:
+            constrain_dx = float(self.x_width_entry.get_value())
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                constrain_dx = float(self.x_width_entry.get_value().replace(',', '.'))
+            except ValueError:
+                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                                     "use a number.")
+                return
+
+        try:
+            constrain_dy = float(self.y_height_entry.get_value())
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                constrain_dy = float(self.y_height_entry.get_value().replace(',', '.'))
+            except ValueError:
+                self.app.inform.emit("[error_notcl]Wrong value format entered, "
+                                     "use a number.")
+                return
 
 
         if 0 in {columns, rows}:
         if 0 in {columns, rows}:
             self.app.inform.emit("[error_notcl]Columns or Rows are zero value. Change them to a positive integer.")
             self.app.inform.emit("[error_notcl]Columns or Rows are zero value. Change them to a positive integer.")

+ 62 - 21
flatcamTools/ToolTransform.py

@@ -377,9 +377,14 @@ class ToolTransform(FlatCAMTool):
     def on_rotate(self):
     def on_rotate(self):
         try:
         try:
             value = float(self.rotate_entry.get_value())
             value = float(self.rotate_entry.get_value())
-        except Exception as e:
-            self.app.inform.emit("[error] Failed to rotate due of: %s" % str(e))
-            return
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                value = float(self.rotate_entry.get_value().replace(',', '.'))
+            except ValueError:
+                self.app.inform.emit("[error_notcl]Wrong value format entered for Rotate, "
+                                     "use a number.")
+                return
         self.app.worker_task.emit({'fcn': self.on_rotate_action,
         self.app.worker_task.emit({'fcn': self.on_rotate_action,
                                        'params': [value]})
                                        'params': [value]})
         # self.on_rotate_action(value)
         # self.on_rotate_action(value)
@@ -406,9 +411,15 @@ class ToolTransform(FlatCAMTool):
     def on_skewx(self):
     def on_skewx(self):
         try:
         try:
             value = float(self.skewx_entry.get_value())
             value = float(self.skewx_entry.get_value())
-        except:
-            self.app.inform.emit("[warning_notcl] No value for Skew!")
-            return
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                value = float(self.skewx_entry.get_value().replace(',', '.'))
+            except ValueError:
+                self.app.inform.emit("[error_notcl]Wrong value format entered for Skew X, "
+                                     "use a number.")
+                return
+
         # self.on_skew("X", value)
         # self.on_skew("X", value)
         axis = 'X'
         axis = 'X'
         self.app.worker_task.emit({'fcn': self.on_skew,
         self.app.worker_task.emit({'fcn': self.on_skew,
@@ -418,9 +429,15 @@ class ToolTransform(FlatCAMTool):
     def on_skewy(self):
     def on_skewy(self):
         try:
         try:
             value = float(self.skewy_entry.get_value())
             value = float(self.skewy_entry.get_value())
-        except:
-            self.app.inform.emit("[warning_notcl] No value for Skew!")
-            return
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                value = float(self.skewy_entry.get_value().replace(',', '.'))
+            except ValueError:
+                self.app.inform.emit("[error_notcl]Wrong value format entered for Skew Y, "
+                                     "use a number.")
+                return
+
         # self.on_skew("Y", value)
         # self.on_skew("Y", value)
         axis = 'Y'
         axis = 'Y'
         self.app.worker_task.emit({'fcn': self.on_skew,
         self.app.worker_task.emit({'fcn': self.on_skew,
@@ -430,9 +447,15 @@ class ToolTransform(FlatCAMTool):
     def on_scalex(self):
     def on_scalex(self):
         try:
         try:
             xvalue = float(self.scalex_entry.get_value())
             xvalue = float(self.scalex_entry.get_value())
-        except:
-            self.app.inform.emit("[warning_notcl] No value for Scale!")
-            return
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                xvalue = float(self.scalex_entry.get_value().replace(',', '.'))
+            except ValueError:
+                self.app.inform.emit("[error_notcl]Wrong value format entered for Scale X, "
+                                     "use a number.")
+                return
+
         # scaling to zero has no sense so we remove it, because scaling with 1 does nothing
         # scaling to zero has no sense so we remove it, because scaling with 1 does nothing
         if xvalue == 0:
         if xvalue == 0:
             xvalue = 1
             xvalue = 1
@@ -458,9 +481,15 @@ class ToolTransform(FlatCAMTool):
         xvalue = 1
         xvalue = 1
         try:
         try:
             yvalue = float(self.scaley_entry.get_value())
             yvalue = float(self.scaley_entry.get_value())
-        except:
-            self.app.inform.emit("[warning_notcl] No value for Scale!")
-            return
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                yvalue = float(self.scaley_entry.get_value().replace(',', '.'))
+            except ValueError:
+                self.app.inform.emit("[error_notcl]Wrong value format entered for Scale Y, "
+                                     "use a number.")
+                return
+
         # scaling to zero has no sense so we remove it, because scaling with 1 does nothing
         # scaling to zero has no sense so we remove it, because scaling with 1 does nothing
         if yvalue == 0:
         if yvalue == 0:
             yvalue = 1
             yvalue = 1
@@ -481,9 +510,15 @@ class ToolTransform(FlatCAMTool):
     def on_offx(self):
     def on_offx(self):
         try:
         try:
             value = float(self.offx_entry.get_value())
             value = float(self.offx_entry.get_value())
-        except:
-            self.app.inform.emit("[warning_notcl] No value for Offset!")
-            return
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                value = float(self.offx_entry.get_value().replace(',', '.'))
+            except ValueError:
+                self.app.inform.emit("[error_notcl]Wrong value format entered for Offset X, "
+                                     "use a number.")
+                return
+
         # self.on_offset("X", value)
         # self.on_offset("X", value)
         axis = 'X'
         axis = 'X'
         self.app.worker_task.emit({'fcn': self.on_offset,
         self.app.worker_task.emit({'fcn': self.on_offset,
@@ -493,9 +528,15 @@ class ToolTransform(FlatCAMTool):
     def on_offy(self):
     def on_offy(self):
         try:
         try:
             value = float(self.offy_entry.get_value())
             value = float(self.offy_entry.get_value())
-        except:
-            self.app.inform.emit("[warning_notcl] No value for Offset!")
-            return
+        except ValueError:
+            # try to convert comma to decimal point. if it's still not working error message and return
+            try:
+                value = float(self.offy_entry.get_value().replace(',', '.'))
+            except ValueError:
+                self.app.inform.emit("[error_notcl]Wrong value format entered for Offset Y, "
+                                     "use a number.")
+                return
+
         # self.on_offset("Y", value)
         # self.on_offset("Y", value)
         axis = 'Y'
         axis = 'Y'
         self.app.worker_task.emit({'fcn': self.on_offset,
         self.app.worker_task.emit({'fcn': self.on_offset,

+ 2 - 1
flatcamTools/__init__.py

@@ -5,7 +5,8 @@ from flatcamTools.ToolPanelize import Panelize
 from flatcamTools.ToolFilm import Film
 from flatcamTools.ToolFilm import Film
 from flatcamTools.ToolMove import ToolMove
 from flatcamTools.ToolMove import ToolMove
 from flatcamTools.ToolDblSided import DblSidedTool
 from flatcamTools.ToolDblSided import DblSidedTool
-from flatcamTools.ToolCutout import ToolCutout
+
+from flatcamTools.ToolCutOut import ToolCutOut
 from flatcamTools.ToolCalculators import ToolCalculator
 from flatcamTools.ToolCalculators import ToolCalculator
 from flatcamTools.ToolProperties import Properties
 from flatcamTools.ToolProperties import Properties
 from flatcamTools.ToolImage import ToolImage
 from flatcamTools.ToolImage import ToolImage