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

- updated the UI in Geometry UI
- optimized the order of the defaults storage declaration and the update of the Preferences GUI from the defaults

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

Разница между файлами не показана из-за своего большого размера
+ 895 - 877
FlatCAMApp.py


+ 118 - 113
FlatCAMObj.py

@@ -3306,104 +3306,6 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
     optionChanged = QtCore.pyqtSignal(str)
     ui_type = GeometryObjectUI
 
-    def merge(self, geo_list, geo_final, multigeo=None):
-        """
-        Merges the geometry of objects in grb_list into
-        the geometry of geo_final.
-
-        :param geo_list: List of FlatCAMGerber Objects to join.
-        :param geo_final: Destination FlatCAMGerber object.
-        :return: None
-        """
-
-        if geo_final.solid_geometry is None:
-            geo_final.solid_geometry = []
-
-        if type(geo_final.solid_geometry) is not list:
-            geo_final.solid_geometry = [geo_final.solid_geometry]
-
-        for geo in geo_list:
-            for option in geo.options:
-                if option is not 'name':
-                    try:
-                        geo_final.options[option] = geo.options[option]
-                    except Exception as e:
-                        log.warning("Failed to copy option %s. Error: %s" % (str(option), str(e)))
-
-            # Expand lists
-            if type(geo) is list:
-                FlatCAMGeometry.merge(self, geo_list=geo, geo_final=geo_final)
-            # If not list, just append
-            else:
-                # merge solid_geometry, useful for singletool geometry, for multitool each is empty
-                if multigeo is None or multigeo is False:
-                    geo_final.multigeo = False
-                    try:
-                        geo_final.solid_geometry.append(geo.solid_geometry)
-                    except Exception as e:
-                        log.debug("FlatCAMGeometry.merge() --> %s" % str(e))
-                else:
-                    geo_final.multigeo = True
-                    # if multigeo the solid_geometry is empty in the object attributes because it now lives in the
-                    # tools object attribute, as a key value
-                    geo_final.solid_geometry = []
-
-                # find the tool_uid maximum value in the geo_final
-                geo_final_uid_list = []
-                for key in geo_final.tools:
-                    geo_final_uid_list.append(int(key))
-
-                try:
-                    max_uid = max(geo_final_uid_list, key=int)
-                except ValueError:
-                    max_uid = 0
-
-                # add and merge tools. If what we try to merge as Geometry is Excellon's and/or Gerber's then don't try
-                # to merge the obj.tools as it is likely there is none to merge.
-                if not isinstance(geo, FlatCAMGerber) and not isinstance(geo, FlatCAMExcellon):
-                    for tool_uid in geo.tools:
-                        max_uid += 1
-                        geo_final.tools[max_uid] = deepcopy(geo.tools[tool_uid])
-
-    @staticmethod
-    def get_pts(o):
-        """
-        Returns a list of all points in the object, where
-        the object can be a MultiPolygon, Polygon, Not a polygon, or a list
-        of such. Search is done recursively.
-
-        :param: geometric object
-        :return: List of points
-        :rtype: list
-        """
-        pts = []
-
-        # Iterable: descend into each item.
-        try:
-            for subo in o:
-                pts += FlatCAMGeometry.get_pts(subo)
-
-        # Non-iterable
-        except TypeError:
-            if o is not None:
-                if type(o) == MultiPolygon:
-                    for poly in o:
-                        pts += FlatCAMGeometry.get_pts(poly)
-                # ## Descend into .exerior and .interiors
-                elif type(o) == Polygon:
-                    pts += FlatCAMGeometry.get_pts(o.exterior)
-                    for i in o.interiors:
-                        pts += FlatCAMGeometry.get_pts(i)
-                elif type(o) == MultiLineString:
-                    for line in o:
-                        pts += FlatCAMGeometry.get_pts(line)
-                # ## Has .coords: list them.
-                else:
-                    pts += list(o.coords)
-            else:
-                return
-        return pts
-
     def __init__(self, name):
         FlatCAMObj.__init__(self, name)
         Geometry.__init__(self, geo_steps_per_circle=int(self.app.defaults["geometry_circle_steps"]))
@@ -3477,7 +3379,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
 
         # flag to store if the geometry is part of a special group of geometries that can't be processed by the default
         # engine of FlatCAM. Most likely are generated by some of tools and are special cases of geometries.
-        self. special_group = None
+        self.special_group = None
 
         self.old_pp_state = self.app.defaults["geometry_multidepth"]
         self.old_toolchangeg_state = self.app.defaults["geometry_toolchange"]
@@ -3506,9 +3408,9 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
             tool_idx += 1
             row_no = tool_idx - 1
 
-            id = QtWidgets.QTableWidgetItem('%d' % int(tool_idx))
-            id.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
-            self.ui.geo_tools_table.setItem(row_no, 0, id)  # Tool name/id
+            tool_id = QtWidgets.QTableWidgetItem('%d' % int(tool_idx))
+            tool_id.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
+            self.ui.geo_tools_table.setItem(row_no, 0, tool_id)  # Tool name/id
 
             # Make sure that the tool diameter when in MM is with no more than 2 decimals.
             # There are no tool bits in MM with more than 3 decimals diameter.
@@ -3754,7 +3656,6 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
             # again float type; dict's don't like having keys changed when iterated through therefore the need for the
             # following convoluted way of changing the keys from string to float type
             temp_tools = {}
-            new_key = 0.0
             for tooluid_key in self.tools:
                 val = deepcopy(self.tools[tooluid_key])
                 new_key = deepcopy(int(tooluid_key))
@@ -3775,6 +3676,8 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
             return
 
         self.ui.geo_tools_table.setupContextMenu()
+        self.ui.geo_tools_table.addContextMenu(
+            _("Add from Tool DB"), self.on_tool_add_from_db, icon=QtGui.QIcon("share/plus16.png"))
         self.ui.geo_tools_table.addContextMenu(
             _("Copy"), self.on_tool_copy, icon=QtGui.QIcon("share/copy16.png"))
         self.ui.geo_tools_table.addContextMenu(
@@ -4076,6 +3979,9 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
         if self.ui.geo_tools_table.rowCount() != 0:
             self.ui.geo_param_frame.setDisabled(False)
 
+    def on_tool_add_from_db(self):
+        pass
+
     def on_tool_copy(self, all=None):
         self.ui_disconnect()
 
@@ -4670,16 +4576,16 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
         # test to see if we have tools available in the tool table
         if self.ui.geo_tools_table.selectedItems():
             for x in self.ui.geo_tools_table.selectedItems():
-                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] %s' %
-                                             _("Wrong value format entered, use a number."))
-                        return
+                # 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] %s' %
+                #                              _("Wrong value format entered, use a number."))
+                #         return
                 tooluid = int(self.ui.geo_tools_table.item(x.row(), 5).text())
 
                 for tooluid_key, tooluid_value in self.tools.items():
@@ -5630,6 +5536,105 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
             self.ui.plot_cb.setChecked(True)
         self.ui_connect()
 
+    def merge(self, geo_list, geo_final, multigeo=None):
+        """
+        Merges the geometry of objects in grb_list into
+        the geometry of geo_final.
+
+        :param geo_list: List of FlatCAMGerber Objects to join.
+        :param geo_final: Destination FlatCAMGerber object.
+        :param multigeo: if the merged geometry objects are of type MultiGeo
+        :return: None
+        """
+
+        if geo_final.solid_geometry is None:
+            geo_final.solid_geometry = []
+
+        if type(geo_final.solid_geometry) is not list:
+            geo_final.solid_geometry = [geo_final.solid_geometry]
+
+        for geo in geo_list:
+            for option in geo.options:
+                if option is not 'name':
+                    try:
+                        geo_final.options[option] = geo.options[option]
+                    except Exception as e:
+                        log.warning("Failed to copy option %s. Error: %s" % (str(option), str(e)))
+
+            # Expand lists
+            if type(geo) is list:
+                FlatCAMGeometry.merge(self, geo_list=geo, geo_final=geo_final)
+            # If not list, just append
+            else:
+                # merge solid_geometry, useful for singletool geometry, for multitool each is empty
+                if multigeo is None or multigeo is False:
+                    geo_final.multigeo = False
+                    try:
+                        geo_final.solid_geometry.append(geo.solid_geometry)
+                    except Exception as e:
+                        log.debug("FlatCAMGeometry.merge() --> %s" % str(e))
+                else:
+                    geo_final.multigeo = True
+                    # if multigeo the solid_geometry is empty in the object attributes because it now lives in the
+                    # tools object attribute, as a key value
+                    geo_final.solid_geometry = []
+
+                # find the tool_uid maximum value in the geo_final
+                geo_final_uid_list = []
+                for key in geo_final.tools:
+                    geo_final_uid_list.append(int(key))
+
+                try:
+                    max_uid = max(geo_final_uid_list, key=int)
+                except ValueError:
+                    max_uid = 0
+
+                # add and merge tools. If what we try to merge as Geometry is Excellon's and/or Gerber's then don't try
+                # to merge the obj.tools as it is likely there is none to merge.
+                if not isinstance(geo, FlatCAMGerber) and not isinstance(geo, FlatCAMExcellon):
+                    for tool_uid in geo.tools:
+                        max_uid += 1
+                        geo_final.tools[max_uid] = deepcopy(geo.tools[tool_uid])
+
+    @staticmethod
+    def get_pts(o):
+        """
+        Returns a list of all points in the object, where
+        the object can be a MultiPolygon, Polygon, Not a polygon, or a list
+        of such. Search is done recursively.
+
+        :param: geometric object
+        :return: List of points
+        :rtype: list
+        """
+        pts = []
+
+        # Iterable: descend into each item.
+        try:
+            for subo in o:
+                pts += FlatCAMGeometry.get_pts(subo)
+
+        # Non-iterable
+        except TypeError:
+            if o is not None:
+                if type(o) == MultiPolygon:
+                    for poly in o:
+                        pts += FlatCAMGeometry.get_pts(poly)
+                # ## Descend into .exerior and .interiors
+                elif type(o) == Polygon:
+                    pts += FlatCAMGeometry.get_pts(o.exterior)
+                    for i in o.interiors:
+                        pts += FlatCAMGeometry.get_pts(i)
+                elif type(o) == MultiLineString:
+                    for line in o:
+                        pts += FlatCAMGeometry.get_pts(line)
+                # ## Has .coords: list them.
+                else:
+                    pts += list(o.coords)
+            else:
+                return
+        return pts
+
 
 class FlatCAMCNCjob(FlatCAMObj, CNCjob):
     """

+ 2 - 0
README.md

@@ -13,6 +13,8 @@ CAD program, and create G-Code for Isolation routing.
 
 - wip
 - getting rid of all the Options GUI and related functions as it is no longer supported
+- updated the UI in Geometry UI
+- optimized the order of the defaults storage declaration and the update of the Preferences GUI from the defaults
 
 3.11.2019
 

+ 0 - 4
camlib.py

@@ -497,10 +497,6 @@ class Geometry(object):
             from flatcamGUI.PlotCanvasLegacy import ShapeCollectionLegacy
             self.temp_shapes = ShapeCollectionLegacy(obj=self, app=self.app, name='camlib.geometry')
 
-        # if geo_steps_per_circle is None:
-        #     geo_steps_per_circle = int(Geometry.defaults["geo_steps_per_circle"])
-        # self.geo_steps_per_circle = geo_steps_per_circle
-
     def plot_temp_shapes(self, element, color='red'):
 
         try:

+ 1 - 1
flatcamEditors/FlatCAMExcEditor.py

@@ -1449,7 +1449,7 @@ class FlatCAMExcEditor(QtCore.QObject):
         self.decimals = 4
 
         # ## Current application units in Upper Case
-        self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper()
+        self.units = self.app.defaults['units'].upper()
 
         self.exc_edit_widget = QtWidgets.QWidget()
         # ## Box for custom widgets

+ 2 - 2
flatcamEditors/FlatCAMGrbEditor.py

@@ -2356,7 +2356,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
         self.decimals = 4
 
         # Current application units in Upper Case
-        self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper()
+        self.units = self.app.defaults['units'].upper()
 
         self.grb_edit_widget = QtWidgets.QWidget()
         layout = QtWidgets.QVBoxLayout()
@@ -3023,7 +3023,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
 
     def set_ui(self):
         # updated units
-        self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper()
+        self.units = self.app.defaults['units'].upper()
 
         if self.units == "IN":
             self.decimals = 4

+ 42 - 58
flatcamGUI/ObjectUI.py

@@ -385,7 +385,7 @@ class GerberObjectUI(ObjectUI):
               "- conventional / useful when there is no backlash compensation")
         )
         self.milling_type_radio = RadioSet([{'label': _('Climb'), 'value': 'cl'},
-                                            {'label': _('Conv.'), 'value': 'cv'}])
+                                            {'label': _('Conventional'), 'value': 'cv'}])
         grid1.addWidget(self.milling_type_label, 7, 0)
         grid1.addWidget(self.milling_type_radio, 7, 1, 1, 2)
 
@@ -934,12 +934,11 @@ class ExcellonObjectUI(ObjectUI):
         grid2.setColumnStretch(0, 0)
         grid2.setColumnStretch(1, 1)
 
-        choose_tools_label = QtWidgets.QLabel(
-            _("Select from the Tools Table above\n"
-              "the hole dias that are to be drilled.\n"
-              "Use the # column to make the selection.")
-        )
-        grid2.addWidget(choose_tools_label, 0, 0, 1, 3)
+        # choose_tools_label = QtWidgets.QLabel(
+        #     _("Select from the Tools Table above the hole dias to be\n"
+        #       "drilled. Use the # column to make the selection.")
+        # )
+        # grid2.addWidget(choose_tools_label, 0, 0, 1, 3)
 
         # ### Choose what to use for Gcode creation: Drills, Slots or Both
         gcode_type_label = QtWidgets.QLabel('<b>%s</b>' % _('Gcode'))
@@ -967,17 +966,12 @@ class ExcellonObjectUI(ObjectUI):
         # ### Milling Holes Drills ####
         self.mill_hole_label = QtWidgets.QLabel('<b>%s</b>' % _('Mill Holes'))
         self.mill_hole_label.setToolTip(
-            _("Create Geometry for milling holes.")
+            _("Create Geometry for milling holes.\n"
+              "Select from the Tools Table above the hole dias to be\n"
+              "milled. Use the # column to make the selection.")
         )
         grid2.addWidget(self.mill_hole_label, 3, 0, 1, 3)
 
-        self.choose_tools_label2 = QtWidgets.QLabel(
-            _("Select from the Tools Table above\n"
-              "the hole dias that are to be milled.\n"
-              "Use the # column to make the selection.")
-        )
-        grid2.addWidget(self.choose_tools_label2, 4, 0, 1, 3)
-
         self.tdlabel = QtWidgets.QLabel('%s:' % _('Drill Tool dia'))
         self.tdlabel.setToolTip(
             _("Diameter of the cutting tool.")
@@ -993,9 +987,9 @@ class ExcellonObjectUI(ObjectUI):
               "for milling DRILLS toolpaths.")
         )
 
-        grid2.addWidget(self.tdlabel, 5, 0)
-        grid2.addWidget(self.tooldia_entry, 5, 1)
-        grid2.addWidget(self.generate_milling_button, 5, 2)
+        grid2.addWidget(self.tdlabel, 4, 0)
+        grid2.addWidget(self.tooldia_entry, 4, 1)
+        grid2.addWidget(self.generate_milling_button, 4, 2)
 
         self.stdlabel = QtWidgets.QLabel('%s:' % _('Slot Tool dia'))
         self.stdlabel.setToolTip(
@@ -1014,9 +1008,9 @@ class ExcellonObjectUI(ObjectUI):
               "for milling SLOTS toolpaths.")
         )
 
-        grid2.addWidget(self.stdlabel, 6, 0)
-        grid2.addWidget(self.slot_tooldia_entry, 6, 1)
-        grid2.addWidget(self.generate_milling_slots_button, 6, 2)
+        grid2.addWidget(self.stdlabel, 5, 0)
+        grid2.addWidget(self.slot_tooldia_entry, 5, 1)
+        grid2.addWidget(self.generate_milling_slots_button, 5, 2)
 
     def hide_drills(self, state=True):
         if state is True:
@@ -1152,6 +1146,8 @@ class GeometryObjectUI(ObjectUI):
         # Tool Offset
         self.grid1 = QtWidgets.QGridLayout()
         self.geo_tools_box.addLayout(self.grid1)
+        self.grid1.setColumnStretch(0, 0)
+        self.grid1.setColumnStretch(1, 1)
 
         self.tool_offset_lbl = QtWidgets.QLabel('%s:' % _('Tool Offset'))
         self.tool_offset_lbl.setToolTip(
@@ -1162,70 +1158,58 @@ class GeometryObjectUI(ObjectUI):
                 "cut and negative for 'inside' cut."
             )
         )
-        self.grid1.addWidget(self.tool_offset_lbl, 0, 0)
         self.tool_offset_entry = FCDoubleSpinner()
         self.tool_offset_entry.set_precision(self.decimals)
         self.tool_offset_entry.setRange(-9999.9999, 9999.9999)
         self.tool_offset_entry.setSingleStep(0.1)
 
-        spacer_lbl = QtWidgets.QLabel(" ")
-        spacer_lbl.setMinimumWidth(80)
-
-        self.grid1.addWidget(self.tool_offset_entry, 0, 1)
-        self.grid1.addWidget(spacer_lbl, 0, 2)
+        self.grid1.addWidget(self.tool_offset_lbl, 0, 0)
+        self.grid1.addWidget(self.tool_offset_entry, 0, 1, 1, 2)
 
-        # ### Add a new Tool ####
-        hlay = QtWidgets.QHBoxLayout()
-        self.geo_tools_box.addLayout(hlay)
 
-        # self.addtool_label = QtWidgets.QLabel('<b>Tool</b>')
-        # self.addtool_label.setToolTip(
-        #     "Add/Copy/Delete a tool to the tool list."
-        # )
         self.addtool_entry_lbl = QtWidgets.QLabel('<b>%s:</b>' % _('Tool Dia'))
         self.addtool_entry_lbl.setToolTip(
-            _(
-                "Diameter for the new tool"
-            )
+            _("Diameter for the new tool")
         )
         self.addtool_entry = FCDoubleSpinner()
         self.addtool_entry.set_precision(self.decimals)
         self.addtool_entry.setRange(0.00001, 9999.9999)
         self.addtool_entry.setSingleStep(0.1)
 
-        hlay.addWidget(self.addtool_entry_lbl)
-        hlay.addWidget(self.addtool_entry)
-
-        grid2 = QtWidgets.QGridLayout()
-        self.geo_tools_box.addLayout(grid2)
-
         self.addtool_btn = QtWidgets.QPushButton(_('Add'))
         self.addtool_btn.setToolTip(
-            _(
-                "Add a new tool to the Tool Table\n"
-                "with the diameter specified above."
-            )
+            _("Add a new tool to the Tool Table\n"
+              "with the specified diameter.")
         )
 
+        self.grid1.addWidget(self.addtool_entry_lbl, 1, 0)
+        self.grid1.addWidget(self.addtool_entry, 1, 1)
+        self.grid1.addWidget(self.addtool_btn, 1, 2)
+
+        self.addtool_from_db_btn = QtWidgets.QPushButton(_('Add Tool from DataBase'))
+        self.addtool_from_db_btn.setToolTip(
+            _("Add a new tool to the Tool Table\n"
+              "from the Tool DataBase.")
+        )
+        self.grid1.addWidget(self.addtool_from_db_btn, 2, 0, 1, 3)
+
+        grid2 = QtWidgets.QGridLayout()
+        self.geo_tools_box.addLayout(grid2)
+
         self.copytool_btn = QtWidgets.QPushButton(_('Copy'))
         self.copytool_btn.setToolTip(
-            _(
-                "Copy a selection of tools in the Tool Table\n"
-                "by first selecting a row in the Tool Table."
-            )
+            _("Copy a selection of tools in the Tool Table\n"
+              "by first selecting a row in the Tool Table.")
         )
 
         self.deltool_btn = QtWidgets.QPushButton(_('Delete'))
         self.deltool_btn.setToolTip(
-            _(
-                "Delete a selection of tools in the Tool Table\n"
-                "by first selecting a row in the Tool Table."
-            )
+            _("Delete a selection of tools in the Tool Table\n"
+              "by first selecting a row in the Tool Table.")
         )
 
-        grid2.addWidget(self.addtool_btn, 0, 0)
-        grid2.addWidget(self.copytool_btn, 0, 1)
-        grid2.addWidget(self.deltool_btn, 0, 2)
+        grid2.addWidget(self.copytool_btn, 0, 0)
+        grid2.addWidget(self.deltool_btn, 0, 1)
 
         self.empty_label = QtWidgets.QLabel('')
         self.geo_tools_box.addWidget(self.empty_label)

+ 1 - 1
flatcamGUI/PlotCanvas.py

@@ -120,7 +120,7 @@ class PlotCanvas(QtCore.QObject, VisPyCanvas):
         a3p_mm = np.array([(0, 0), (297, 0), (297, 420), (0, 420)])
         a3l_mm = np.array([(0, 0), (420, 0), (420, 297), (0, 297)])
 
-        if self.fcapp.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() == 'MM':
+        if self.fcapp.defaults['units'].upper() == 'MM':
             if self.fcapp.defaults['global_workspaceT'] == 'A4P':
                 a = a4p_mm
             elif self.fcapp.defaults['global_workspaceT'] == 'A4L':

+ 1 - 1
flatcamTools/ToolDistance.py

@@ -34,7 +34,7 @@ class Distance(FlatCAMTool):
 
         self.app = app
         self.canvas = self.app.plotcanvas
-        self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().lower()
+        self.units = self.app.defaults['units'].lower()
 
         # ## Title
         title_label = QtWidgets.QLabel("<font size=4><b>%s</b></font><br>" % self.toolName)

+ 1 - 1
flatcamTools/ToolDistanceMin.py

@@ -35,7 +35,7 @@ class DistanceMin(FlatCAMTool):
 
         self.app = app
         self.canvas = self.app.plotcanvas
-        self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().lower()
+        self.units = self.app.defaults['units'].lower()
 
         # ## Title
         title_label = QtWidgets.QLabel("<font size=4><b>%s</b></font><br>" % self.toolName)

+ 1 - 1
flatcamTools/ToolNonCopperClear.py

@@ -421,7 +421,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
         self.ncc_offset_spinner.set_precision(4)
         self.ncc_offset_spinner.setWrapping(True)
 
-        units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper()
+        units = self.app.defaults['units'].upper()
         if units == 'MM':
             self.ncc_offset_spinner.setSingleStep(0.1)
         else:

+ 1 - 1
flatcamTools/ToolOptimal.py

@@ -39,7 +39,7 @@ class ToolOptimal(FlatCAMTool):
     def __init__(self, app):
         FlatCAMTool.__init__(self, app)
 
-        self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper()
+        self.units = self.app.defaults['units'].upper()
         self.decimals = 4
 
         # ############################################################################

Некоторые файлы не были показаны из-за большого количества измененных файлов