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

- created the GUI for the Rule Check Tool
- if there are (x, y) coordinates in the clipboard, when launching the "Jump to" function, those coordinates will be preloaded in the Dialog box.
- when the combo SHIFT + LMB is executed there is no longer a deselection of objects
- when the "Jump to" function is called, the mouse cursor (if active) will be moved to the new position and the screen position labels will be updated accordingly
- changed the icon for Open Script and reused it for the Check Rules Tool

Marius Stanciu 6 лет назад
Родитель
Сommit
c5ecc7ad88
8 измененных файлов с 826 добавлено и 727 удалено
  1. 47 15
      FlatCAMApp.py
  2. 9 0
      README.md
  3. 19 7
      flatcamGUI/FlatCAMGUI.py
  4. 10 5
      flatcamGUI/GUIElements.py
  5. 740 699
      flatcamTools/ToolRulesCheck.py
  6. 1 1
      flatcamTools/ToolTransform.py
  7. BIN
      share/open_script32.png
  8. BIN
      share/rules32.png

+ 47 - 15
FlatCAMApp.py

@@ -2372,6 +2372,7 @@ class App(QtCore.QObject):
         self.film_tool = None
         self.film_tool = None
         self.paste_tool = None
         self.paste_tool = None
         self.calculator_tool = None
         self.calculator_tool = None
+        self.rules_tool = None
         self.sub_tool = None
         self.sub_tool = None
         self.move_tool = None
         self.move_tool = None
         self.cutout_tool = None
         self.cutout_tool = None
@@ -2909,6 +2910,9 @@ class App(QtCore.QObject):
         self.sub_tool = ToolSub(self)
         self.sub_tool = ToolSub(self)
         self.sub_tool.install(icon=QtGui.QIcon('share/sub32.png'), pos=self.ui.menutool, separator=True)
         self.sub_tool.install(icon=QtGui.QIcon('share/sub32.png'), pos=self.ui.menutool, separator=True)
 
 
+        self.rules_tool = RulesCheck(self)
+        self.rules_tool.install(icon=QtGui.QIcon('share/rules32.png'), pos=self.ui.menutool, separator=True)
+
         self.move_tool = ToolMove(self)
         self.move_tool = ToolMove(self)
         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)
@@ -3036,6 +3040,7 @@ class App(QtCore.QObject):
         self.ui.film_btn.triggered.connect(lambda: self.film_tool.run(toggle=True))
         self.ui.film_btn.triggered.connect(lambda: self.film_tool.run(toggle=True))
         self.ui.solder_btn.triggered.connect(lambda: self.paste_tool.run(toggle=True))
         self.ui.solder_btn.triggered.connect(lambda: self.paste_tool.run(toggle=True))
         self.ui.sub_btn.triggered.connect(lambda: self.sub_tool.run(toggle=True))
         self.ui.sub_btn.triggered.connect(lambda: self.sub_tool.run(toggle=True))
+        self.ui.rules_btn.triggered.connect(lambda: self.rules_tool.run(toggle=True))
 
 
         self.ui.calculators_btn.triggered.connect(lambda: self.calculator_tool.run(toggle=True))
         self.ui.calculators_btn.triggered.connect(lambda: self.calculator_tool.run(toggle=True))
         self.ui.transform_btn.triggered.connect(lambda: self.transform_tool.run(toggle=True))
         self.ui.transform_btn.triggered.connect(lambda: self.transform_tool.run(toggle=True))
@@ -6979,9 +6984,22 @@ class App(QtCore.QObject):
         #     return
         #     return
 
 
         if not custom_location:
         if not custom_location:
+            dia_box_location = None
+
+            try:
+                dia_box_location = eval(self.clipboard.text())
+            except Exception as e:
+                pass
+
+            if type(dia_box_location) == tuple:
+                dia_box_location = str(dia_box_location)
+            else:
+                dia_box_location = None
+
             dia_box = Dialog_box(title=_("Jump to ..."),
             dia_box = Dialog_box(title=_("Jump to ..."),
                                  label=_("Enter the coordinates in format X,Y:"),
                                  label=_("Enter the coordinates in format X,Y:"),
-                                 icon=QtGui.QIcon('share/jump_to16.png'))
+                                 icon=QtGui.QIcon('share/jump_to16.png'),
+                                 initial_text=dia_box_location)
 
 
             if dia_box.ok is True:
             if dia_box.ok is True:
                 try:
                 try:
@@ -7004,7 +7022,8 @@ class App(QtCore.QObject):
         if self.is_legacy is False:
         if self.is_legacy is False:
             canvas_origin = self.plotcanvas.native.mapToGlobal(QtCore.QPoint(0, 0))
             canvas_origin = self.plotcanvas.native.mapToGlobal(QtCore.QPoint(0, 0))
             jump_loc = self.plotcanvas.translate_coords_2((location[0], location[1]))
             jump_loc = self.plotcanvas.translate_coords_2((location[0], location[1]))
-            cursor.setPos(canvas_origin.x() + jump_loc[0], (canvas_origin.y() + jump_loc[1]))
+            j_pos = (canvas_origin.x() + jump_loc[0], (canvas_origin.y() + jump_loc[1]))
+            cursor.setPos(j_pos[0], j_pos[1])
         else:
         else:
             # find the canvas origin which is in the top left corner
             # find the canvas origin which is in the top left corner
             canvas_origin = self.plotcanvas.native.mapToGlobal(QtCore.QPoint(0, 0))
             canvas_origin = self.plotcanvas.native.mapToGlobal(QtCore.QPoint(0, 0))
@@ -7015,8 +7034,22 @@ class App(QtCore.QObject):
             # in pixels where the origin 0,0 is in the lowest left point of the display window (in our case is the
             # in pixels where the origin 0,0 is in the lowest left point of the display window (in our case is the
             # canvas) and the point (width, height) is in the top-right location
             # canvas) and the point (width, height) is in the top-right location
             loc = self.plotcanvas.axes.transData.transform_point(location)
             loc = self.plotcanvas.axes.transData.transform_point(location)
+            j_pos = (x0 + loc[0], y0 - loc[1])
+            cursor.setPos(j_pos[0], j_pos[1])
 
 
-            cursor.setPos(x0 + loc[0], y0 - loc[1])
+        if self.grid_status() == True:
+            # Update cursor
+            self.app_cursor.set_data(np.asarray([(location[0], location[1])]),
+                                     symbol='++', edge_color='black', size=self.defaults["global_cursor_size"])
+
+        # Set the position label
+        self.ui.position_label.setText("&nbsp;&nbsp;&nbsp;&nbsp;<b>X</b>: %.4f&nbsp;&nbsp;   "
+                                       "<b>Y</b>: %.4f" % (location[0], location[1]))
+        # Set the relative position label
+        dx = location[0] - float(self.rel_point1[0])
+        dy = location[1] - float(self.rel_point1[1])
+        self.ui.rel_position_label.setText("<b>Dx</b>: %.4f&nbsp;&nbsp;  <b>Dy</b>: "
+                                           "%.4f&nbsp;&nbsp;&nbsp;&nbsp;" % (dx, dy))
 
 
         self.inform.emit('[success] %s' %
         self.inform.emit('[success] %s' %
                          _("Done."))
                          _("Done."))
@@ -7799,8 +7832,6 @@ class App(QtCore.QObject):
             self.pos = (self.pos_canvas[0], self.pos_canvas[1])
             self.pos = (self.pos_canvas[0], self.pos_canvas[1])
 
 
         try:
         try:
-            modifiers = QtWidgets.QApplication.keyboardModifiers()
-
             if event.button == 1:
             if event.button == 1:
                 # Reset here the relative coordinates so there is a new reference on the click position
                 # Reset here the relative coordinates so there is a new reference on the click position
                 if self.rel_point1 is None:
                 if self.rel_point1 is None:
@@ -7809,16 +7840,6 @@ class App(QtCore.QObject):
                     self.rel_point2 = copy(self.rel_point1)
                     self.rel_point2 = copy(self.rel_point1)
                     self.rel_point1 = self.pos
                     self.rel_point1 = self.pos
 
 
-                # If the SHIFT key is pressed when LMB is clicked then the coordinates are copied to clipboard
-                if modifiers == QtCore.Qt.ShiftModifier:
-                    # do not auto open the Project Tab
-                    self.click_noproject = True
-
-                    self.clipboard.setText(self.defaults["global_point_clipboard_format"] % (self.pos[0], self.pos[1]))
-                    self.inform.emit('[success] %s' %
-                                     _("Coordinates copied to clipboard."))
-                    return
-
             self.on_mouse_move_over_plot(event, origin_click=True)
             self.on_mouse_move_over_plot(event, origin_click=True)
         except Exception as e:
         except Exception as e:
             App.log.debug("App.on_mouse_click_over_plot() --> Outside plot? --> %s" % str(e))
             App.log.debug("App.on_mouse_click_over_plot() --> Outside plot? --> %s" % str(e))
@@ -7970,6 +7991,17 @@ class App(QtCore.QObject):
         # selection and then select a type of selection ("enclosing" or "touching")
         # selection and then select a type of selection ("enclosing" or "touching")
         try:
         try:
             if event.button == 1:  # left click
             if event.button == 1:  # left click
+                modifiers = QtWidgets.QApplication.keyboardModifiers()
+                # If the SHIFT key is pressed when LMB is clicked then the coordinates are copied to clipboard
+                if modifiers == QtCore.Qt.ShiftModifier:
+                    # do not auto open the Project Tab
+                    self.click_noproject = True
+
+                    self.clipboard.setText(self.defaults["global_point_clipboard_format"] % (self.pos[0], self.pos[1]))
+                    self.inform.emit('[success] %s' %
+                                     _("Coordinates copied to clipboard."))
+                    return
+
                 if self.doubleclick is True:
                 if self.doubleclick is True:
                     self.doubleclick = False
                     self.doubleclick = False
                     if self.collection.get_selected():
                     if self.collection.get_selected():

+ 9 - 0
README.md

@@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing.
 
 
 =================================================
 =================================================
 
 
+28.09.2019
+
+- changed the icon for Open Script and reused it for the Check Rules Tool
+
 27.09.2019
 27.09.2019
 
 
 - optimized the toggle axis command
 - optimized the toggle axis command
@@ -19,6 +23,11 @@ CAD program, and create G-Code for Isolation routing.
 - if an object is edited but the result is not saved, the app will reload the edited object UI and set the Selected tab as active
 - if an object is edited but the result is not saved, the app will reload the edited object UI and set the Selected tab as active
 - made the mouse cursor (big, small) change in real time for both graphic engines
 - made the mouse cursor (big, small) change in real time for both graphic engines
 - started to work on a new FlatCAM tool: Rules Check
 - started to work on a new FlatCAM tool: Rules Check
+- created the GUI for the Rule Check Tool
+- if there are (x, y) coordinates in the clipboard, when launching the "Jump to" function, those coordinates will be preloaded in the Dialog box.
+- when the combo SHIFT + LMB is executed there is no longer a deselection of objects
+- when the "Jump to" function is called, the mouse cursor (if active) will be moved to the new position and the screen position labels will be updated accordingly
+
 
 
 27.09.2019
 27.09.2019
 
 

+ 19 - 7
flatcamGUI/FlatCAMGUI.py

@@ -112,7 +112,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
         self.menufile_scripting.setToolTipsVisible(True)
         self.menufile_scripting.setToolTipsVisible(True)
 
 
         self.menufilenewscript = QtWidgets.QAction(QtGui.QIcon('share/script_new16.png'), _('New Script ...'), self)
         self.menufilenewscript = QtWidgets.QAction(QtGui.QIcon('share/script_new16.png'), _('New Script ...'), self)
-        self.menufileopenscript = QtWidgets.QAction(QtGui.QIcon('share/script_open16.png'), _('Open Script ...'), self)
+        self.menufileopenscript = QtWidgets.QAction(QtGui.QIcon('share/open_script32.png'), _('Open Script ...'), self)
         self.menufilerunscript = QtWidgets.QAction(QtGui.QIcon('share/script16.png'),
         self.menufilerunscript = QtWidgets.QAction(QtGui.QIcon('share/script16.png'),
                                                    '%s\tSHIFT+S' % _('Run Script ...'), self)
                                                    '%s\tSHIFT+S' % _('Run Script ...'), self)
         self.menufilerunscript.setToolTip(
         self.menufilerunscript.setToolTip(
@@ -664,7 +664,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
         # ## Shell Toolbar ##
         # ## Shell Toolbar ##
         self.shell_btn = self.toolbarshell.addAction(QtGui.QIcon('share/shell32.png'), _("&Command Line"))
         self.shell_btn = self.toolbarshell.addAction(QtGui.QIcon('share/shell32.png'), _("&Command Line"))
         self.new_script_btn = self.toolbarshell.addAction(QtGui.QIcon('share/script_new24.png'), _('New Script ...'))
         self.new_script_btn = self.toolbarshell.addAction(QtGui.QIcon('share/script_new24.png'), _('New Script ...'))
-        self.open_script_btn = self.toolbarshell.addAction(QtGui.QIcon('share/script_open18.png'), _('Open Script ...'))
+        self.open_script_btn = self.toolbarshell.addAction(QtGui.QIcon('share/open_script32.png'), _('Open Script ...'))
         self.run_script_btn = self.toolbarshell.addAction(QtGui.QIcon('share/script16.png'), _('Run Script ...'))
         self.run_script_btn = self.toolbarshell.addAction(QtGui.QIcon('share/script16.png'), _('Run Script ...'))
 
 
         # ## Tools Toolbar ##
         # ## Tools Toolbar ##
@@ -678,6 +678,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
         self.film_btn = self.toolbartools.addAction(QtGui.QIcon('share/film16.png'), _("Film Tool"))
         self.film_btn = self.toolbartools.addAction(QtGui.QIcon('share/film16.png'), _("Film Tool"))
         self.solder_btn = self.toolbartools.addAction(QtGui.QIcon('share/solderpastebis32.png'), _("SolderPaste Tool"))
         self.solder_btn = self.toolbartools.addAction(QtGui.QIcon('share/solderpastebis32.png'), _("SolderPaste Tool"))
         self.sub_btn = self.toolbartools.addAction(QtGui.QIcon('share/sub32.png'), _("Substract Tool"))
         self.sub_btn = self.toolbartools.addAction(QtGui.QIcon('share/sub32.png'), _("Substract Tool"))
+        self.rules_btn = self.toolbartools.addAction(QtGui.QIcon('share/rules32.png'), _("Rules Tool"))
 
 
         self.toolbartools.addSeparator()
         self.toolbartools.addSeparator()
 
 
@@ -1219,6 +1220,10 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
                         <td height="20"><strong>ALT+D</strong></td>
                         <td height="20"><strong>ALT+D</strong></td>
                         <td>&nbsp;%s</td>
                         <td>&nbsp;%s</td>
                     </tr>
                     </tr>
+                    <tr height="20">
+                        <td height="20"><strong>ALT+E</strong></td>
+                        <td>&nbsp;%s</td>
+                    </tr>
                     <tr height="20">
                     <tr height="20">
                         <td height="20"><strong>ALT+K</strong></td>
                         <td height="20"><strong>ALT+K</strong></td>
                         <td>&nbsp;%s</td>
                         <td>&nbsp;%s</td>
@@ -1326,9 +1331,11 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
                 _("Open Project"), _("Save Project As"), _("Toggle Plot Area"), _("Copy Obj_Name"),
                 _("Open Project"), _("Save Project As"), _("Toggle Plot Area"), _("Copy Obj_Name"),
                 _("Toggle Code Editor"), _("Toggle the axis"), _("Open Preferences Window"),
                 _("Toggle Code Editor"), _("Toggle the axis"), _("Open Preferences Window"),
                 _("Rotate by 90 degree CCW"), _("Run a Script"), _("Toggle the workspace"), _("Skew on X axis"),
                 _("Rotate by 90 degree CCW"), _("Run a Script"), _("Toggle the workspace"), _("Skew on X axis"),
-                _("Skew on Y axis"), _("Calculators Tool"), _("2-Sided PCB Tool"), _("Solder Paste Dispensing Tool"),
+                _("Skew on Y axis"), _("Calculators Tool"), _("2-Sided PCB Tool"), _("Transformations Tool"),
+                _("Solder Paste Dispensing Tool"),
                 _("Film PCB Tool"), _("Non-Copper Clearing Tool"),
                 _("Film PCB Tool"), _("Non-Copper Clearing Tool"),
-                _("Paint Area Tool"), _("PDF Import Tool"), _("Transformations Tool"), _("View File Source"),
+                _("Paint Area Tool"), _("PDF Import Tool"), _("Rules Check Tool"),
+                _("View File Source"),
                 _("Cutout PCB Tool"), _("Enable all Plots"), _("Disable all Plots"), _("Disable Non-selected Plots"),
                 _("Cutout PCB Tool"), _("Enable all Plots"), _("Disable all Plots"), _("Disable Non-selected Plots"),
                 _("Toggle Full Screen"), _("Abort current task (gracefully)"), _("Open Online Manual"),
                 _("Toggle Full Screen"), _("Abort current task (gracefully)"), _("Open Online Manual"),
                 _("Open Online Tutorials"), _("Refresh Plots"), _("Delete Object"), _("Alternate: Delete Tool"),
                 _("Open Online Tutorials"), _("Refresh Plots"), _("Delete Object"), _("Alternate: Delete Tool"),
@@ -2102,7 +2109,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
         # ## Shell Toolbar # ##
         # ## Shell Toolbar # ##
         self.shell_btn = self.toolbarshell.addAction(QtGui.QIcon('share/shell32.png'), _("&Command Line"))
         self.shell_btn = self.toolbarshell.addAction(QtGui.QIcon('share/shell32.png'), _("&Command Line"))
         self.new_script_btn = self.toolbarshell.addAction(QtGui.QIcon('share/script_new24.png'), _('New Script ...'))
         self.new_script_btn = self.toolbarshell.addAction(QtGui.QIcon('share/script_new24.png'), _('New Script ...'))
-        self.open_script_btn = self.toolbarshell.addAction(QtGui.QIcon('share/script_open18.png'), _('Open Script ...'))
+        self.open_script_btn = self.toolbarshell.addAction(QtGui.QIcon('share/open_script32.png'), _('Open Script ...'))
         self.run_script_btn = self.toolbarshell.addAction(QtGui.QIcon('share/script16.png'), _('Run Script ...'))
         self.run_script_btn = self.toolbarshell.addAction(QtGui.QIcon('share/script16.png'), _('Run Script ...'))
 
 
         # ## Tools Toolbar # ##
         # ## Tools Toolbar # ##
@@ -2406,6 +2413,11 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
                     self.app.dblsidedtool.run(toggle=True)
                     self.app.dblsidedtool.run(toggle=True)
                     return
                     return
 
 
+                # Transformation Tool
+                if key == QtCore.Qt.Key_E:
+                    self.app.transform_tool.run(toggle=True)
+                    return
+
                 # Solder Paste Dispensing Tool
                 # Solder Paste Dispensing Tool
                 if key == QtCore.Qt.Key_K:
                 if key == QtCore.Qt.Key_K:
                     self.app.paste_tool.run(toggle=True)
                     self.app.paste_tool.run(toggle=True)
@@ -2431,9 +2443,9 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
                     self.app.pdf_tool.run()
                     self.app.pdf_tool.run()
                     return
                     return
 
 
-                # Transformation Tool
+                # Rules Tool
                 if key == QtCore.Qt.Key_R:
                 if key == QtCore.Qt.Key_R:
-                    self.app.transform_tool.run(toggle=True)
+                    self.app.rules_tool.run(toggle=True)
                     return
                     return
 
 
                 # View Source Object Content
                 # View Source Object Content

+ 10 - 5
flatcamGUI/GUIElements.py

@@ -1734,21 +1734,26 @@ class FCDoubleSpinner(QtWidgets.QDoubleSpinBox):
 
 
 
 
 class Dialog_box(QtWidgets.QWidget):
 class Dialog_box(QtWidgets.QWidget):
-    def __init__(self, title=None, label=None, icon=None):
+    def __init__(self, title=None, label=None, icon=None, initial_text=None):
         """
         """
 
 
         :param title: string with the window title
         :param title: string with the window title
         :param label: string with the message inside the dialog box
         :param label: string with the message inside the dialog box
         """
         """
         super(Dialog_box, self).__init__()
         super(Dialog_box, self).__init__()
-        self.location = (0, 0)
+        if initial_text is None:
+            self.location = str((0, 0))
+        else:
+            self.location = initial_text
+
         self.ok = False
         self.ok = False
 
 
-        dialog_box = QtWidgets.QInputDialog()
-        dialog_box.setMinimumWidth(290)
+        self.dialog_box = QtWidgets.QInputDialog()
+        self.dialog_box.setMinimumWidth(290)
         self.setWindowIcon(icon)
         self.setWindowIcon(icon)
 
 
-        self.location, self.ok = dialog_box.getText(self, title, label, text="0, 0")
+        self.location, self.ok = self.dialog_box.getText(self, title, label,
+                                                         text=str(self.location).replace('(', '').replace(')', ''))
         self.readyToEdit = True
         self.readyToEdit = True
 
 
     def mousePressEvent(self, e, parent=None):
     def mousePressEvent(self, e, parent=None):

+ 740 - 699
flatcamTools/ToolRulesCheck.py

@@ -22,7 +22,7 @@ if '_' not in builtins.__dict__:
 
 
 class RulesCheck(FlatCAMTool):
 class RulesCheck(FlatCAMTool):
 
 
-    toolName = _("Check Rules PCB")
+    toolName = _("Check Rules")
 
 
     def __init__(self, app):
     def __init__(self, app):
         super(RulesCheck, self).__init__(self)
         super(RulesCheck, self).__init__(self)
@@ -40,205 +40,307 @@ class RulesCheck(FlatCAMTool):
         self.layout.addWidget(title_label)
         self.layout.addWidget(title_label)
 
 
         # Form Layout
         # Form Layout
-        form_layout_0 = QtWidgets.QFormLayout()
-        self.layout.addLayout(form_layout_0)
-
-        # Type of object to be panelized
-        self.type_obj_combo = QtWidgets.QComboBox()
-        self.type_obj_combo.addItem("Gerber")
-        self.type_obj_combo.addItem("Excellon")
-        self.type_obj_combo.addItem("Geometry")
-
-        self.type_obj_combo.setItemIcon(0, QtGui.QIcon("share/flatcam_icon16.png"))
-        self.type_obj_combo.setItemIcon(1, QtGui.QIcon("share/drill16.png"))
-        self.type_obj_combo.setItemIcon(2, QtGui.QIcon("share/geometry16.png"))
-
-        self.type_obj_combo_label = QtWidgets.QLabel('%s:' % _("Object Type"))
-        self.type_obj_combo_label.setToolTip(
-            _("Specify the type of object to be panelized\n"
-              "It can be of type: Gerber, Excellon or Geometry.\n"
-              "The selection here decide the type of objects that will be\n"
-              "in the Object combobox.")
+        form_layout = QtWidgets.QFormLayout()
+        self.layout.addLayout(form_layout)
+
+        self.gerber_title_lbl = QtWidgets.QLabel('<b>%s</b>:' % _("Gerber Files"))
+        self.gerber_title_lbl.setToolTip(
+            _("Gerber files for which to check rules.")
         )
         )
-        form_layout_0.addRow(self.type_obj_combo_label, self.type_obj_combo)
 
 
-        # Object to be panelized
-        self.object_combo = QtWidgets.QComboBox()
-        self.object_combo.setModel(self.app.collection)
-        self.object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
-        self.object_combo.setCurrentIndex(1)
+        # Copper object
+        self.copper_object = QtWidgets.QComboBox()
+        self.copper_object.setModel(self.app.collection)
+        self.copper_object.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
+        self.copper_object.setCurrentIndex(1)
 
 
-        self.object_label = QtWidgets.QLabel('%s:' % _("Object"))
-        self.object_label.setToolTip(
+        self.copper_object_lbl = QtWidgets.QLabel('%s:' % _("Copper"))
+        self.copper_object_lbl.setToolTip(
             _("Object to be panelized. This means that it will\n"
             _("Object to be panelized. This means that it will\n"
               "be duplicated in an array of rows and columns.")
               "be duplicated in an array of rows and columns.")
         )
         )
-        form_layout_0.addRow(self.object_label, self.object_combo)
-        form_layout_0.addRow(QtWidgets.QLabel(""))
 
 
-        # Form Layout
-        form_layout = QtWidgets.QFormLayout()
-        self.layout.addLayout(form_layout)
+        # SolderMask object
+        self.sm_object = QtWidgets.QComboBox()
+        self.sm_object.setModel(self.app.collection)
+        self.sm_object.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
+        self.sm_object.setCurrentIndex(1)
 
 
-        # Type of box Panel object
-        self.reference_radio = RadioSet([{'label': _('Object'), 'value': 'object'},
-                                         {'label': _('Bounding Box'), 'value': 'bbox'}])
-        self.box_label = QtWidgets.QLabel("<b>%s:</b>" % _("Penelization Reference"))
-        self.box_label.setToolTip(
-            _("Choose the reference for panelization:\n"
-              "- Object = the bounding box of a different object\n"
-              "- Bounding Box = the bounding box of the object to be panelized\n"
-              "\n"
-              "The reference is useful when doing panelization for more than one\n"
-              "object. The spacings (really offsets) will be applied in reference\n"
-              "to this reference object therefore maintaining the panelized\n"
-              "objects in sync.")
+        self.sm_object_lbl = QtWidgets.QLabel('%s:' % _("SolderMask"))
+        self.sm_object_lbl.setToolTip(
+            _("Object to be panelized. This means that it will\n"
+              "be duplicated in an array of rows and columns.")
         )
         )
-        form_layout.addRow(self.box_label)
-        form_layout.addRow(self.reference_radio)
-
-        # Type of Box Object to be used as an envelope for panelization
-        self.type_box_combo = QtWidgets.QComboBox()
-        self.type_box_combo.addItem("Gerber")
-        self.type_box_combo.addItem("Excellon")
-        self.type_box_combo.addItem("Geometry")
-
-        # we get rid of item1 ("Excellon") as it is not suitable for use as a "box" for panelizing
-        self.type_box_combo.view().setRowHidden(1, True)
-        self.type_box_combo.setItemIcon(0, QtGui.QIcon("share/flatcam_icon16.png"))
-        self.type_box_combo.setItemIcon(2, QtGui.QIcon("share/geometry16.png"))
-
-        self.type_box_combo_label = QtWidgets.QLabel('%s:' % _("Box Type"))
-        self.type_box_combo_label.setToolTip(
-            _("Specify the type of object to be used as an container for\n"
-              "panelization. It can be: Gerber or Geometry type.\n"
-              "The selection here decide the type of objects that will be\n"
-              "in the Box Object combobox.")
+
+        # SilkScreen object
+        self.ss_object = QtWidgets.QComboBox()
+        self.ss_object.setModel(self.app.collection)
+        self.ss_object.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
+        self.ss_object.setCurrentIndex(1)
+
+        self.ss_object_lbl = QtWidgets.QLabel('%s:' % _("Silkscreen"))
+        self.ss_object_lbl.setToolTip(
+            _("Object to be panelized. This means that it will\n"
+              "be duplicated in an array of rows and columns.")
         )
         )
-        form_layout.addRow(self.type_box_combo_label, self.type_box_combo)
-
-        # Box
-        self.box_combo = QtWidgets.QComboBox()
-        self.box_combo.setModel(self.app.collection)
-        self.box_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
-        self.box_combo.setCurrentIndex(1)
-
-        self.box_combo_label = QtWidgets.QLabel('%s:' % _("Box Object"))
-        self.box_combo_label.setToolTip(
-            _("The actual object that is used a container for the\n "
-              "selected object that is to be panelized.")
+
+        # Outline object
+        self.outline_object = QtWidgets.QComboBox()
+        self.outline_object.setModel(self.app.collection)
+        self.outline_object.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
+        self.outline_object.setCurrentIndex(1)
+
+        self.outline_object_lbl = QtWidgets.QLabel('%s:' % _("Outline"))
+        self.outline_object_lbl.setToolTip(
+            _("Object to be panelized. This means that it will\n"
+              "be duplicated in an array of rows and columns.")
         )
         )
-        form_layout.addRow(self.box_combo_label, self.box_combo)
+        form_layout.addRow(self.gerber_title_lbl)
+        form_layout.addRow(self.copper_object_lbl, self.copper_object)
+        form_layout.addRow(self.sm_object_lbl, self.sm_object)
+        form_layout.addRow(self.ss_object_lbl, self.ss_object)
+        form_layout.addRow(self.outline_object_lbl, self.outline_object)
         form_layout.addRow(QtWidgets.QLabel(""))
         form_layout.addRow(QtWidgets.QLabel(""))
 
 
-        panel_data_label = QtWidgets.QLabel("<b>%s:</b>" % _("Panel Data"))
-        panel_data_label.setToolTip(
-            _("This informations will shape the resulting panel.\n"
-              "The number of rows and columns will set how many\n"
-              "duplicates of the original geometry will be generated.\n"
-              "\n"
-              "The spacings will set the distance between any two\n"
-              "elements of the panel array.")
+        self.excellon_title_lbl = QtWidgets.QLabel('<b>%s</b>:' % _("Excellon Files"))
+        self.excellon_title_lbl.setToolTip(
+            _("Excellon files for which to check rules.")
         )
         )
-        form_layout.addRow(panel_data_label)
-
-        # Spacing Columns
-        self.spacing_columns = FCEntry()
-        self.spacing_columns_label = QtWidgets.QLabel('%s:' % _("Spacing cols"))
-        self.spacing_columns_label.setToolTip(
-            _("Spacing between columns of the desired panel.\n"
-              "In current units.")
+
+        # Excellon 1 object
+        self.e1_object = QtWidgets.QComboBox()
+        self.e1_object.setModel(self.app.collection)
+        self.e1_object.setRootModelIndex(self.app.collection.index(1, 0, QtCore.QModelIndex()))
+        self.e1_object.setCurrentIndex(1)
+
+        self.e1_object_lbl = QtWidgets.QLabel('%s:' % _("Excellon 1"))
+        self.e1_object_lbl.setToolTip(
+            _("Object to be panelized. This means that it will\n"
+              "be duplicated in an array of rows and columns.")
         )
         )
-        form_layout.addRow(self.spacing_columns_label, self.spacing_columns)
-
-        # Spacing Rows
-        self.spacing_rows = FCEntry()
-        self.spacing_rows_label = QtWidgets.QLabel('%s:' % _("Spacing rows"))
-        self.spacing_rows_label.setToolTip(
-            _("Spacing between rows of the desired panel.\n"
-              "In current units.")
+
+        # Excellon 2 object
+        self.e2_object = QtWidgets.QComboBox()
+        self.e2_object.setModel(self.app.collection)
+        self.e2_object.setRootModelIndex(self.app.collection.index(1, 0, QtCore.QModelIndex()))
+        self.e2_object.setCurrentIndex(1)
+
+        self.e2_object_lbl = QtWidgets.QLabel('%s:' % _("Excellon 2"))
+        self.e2_object_lbl.setToolTip(
+            _("Object to be panelized. This means that it will\n"
+              "be duplicated in an array of rows and columns.")
+        )
+
+        form_layout.addRow(self.excellon_title_lbl)
+        form_layout.addRow(self.e1_object_lbl, self.e1_object)
+        form_layout.addRow(self.e2_object_lbl, self.e2_object)
+        form_layout.addRow(QtWidgets.QLabel(""))
+
+        # Form Layout
+        form_layout_1 = QtWidgets.QFormLayout()
+        self.layout.addLayout(form_layout_1)
+
+        # Copper2copper clearance
+        self.clearance_copper2copper_cb = FCCheckBox('%s:' % _("Copper to copper clearance"))
+        self.clearance_copper2copper_cb.setToolTip(
+            _("This checks if the minimum clearance between copper\n"
+              "features is met.")
         )
         )
-        form_layout.addRow(self.spacing_rows_label, self.spacing_rows)
+        form_layout_1.addRow(self.clearance_copper2copper_cb)
 
 
-        # Columns
-        self.columns = FCEntry()
-        self.columns_label = QtWidgets.QLabel('%s:' % _("Columns"))
-        self.columns_label.setToolTip(
-            _("Number of columns of the desired panel")
+        # Copper2copper clearance value
+        self.clearance_copper2copper_entry = FCEntry()
+        self.clearance_copper2copper_lbl = QtWidgets.QLabel('%s:' % _("Min value"))
+        self.clearance_copper2copper_lbl.setToolTip(
+            _("Minimum acceptable clearance value.")
         )
         )
-        form_layout.addRow(self.columns_label, self.columns)
+        form_layout_1.addRow(self.clearance_copper2copper_lbl, self.clearance_copper2copper_entry)
 
 
-        # Rows
-        self.rows = FCEntry()
-        self.rows_label = QtWidgets.QLabel('%s:' % _("Rows"))
-        self.rows_label.setToolTip(
-            _("Number of rows of the desired panel")
+        self.c2c = OptionalInputSection(
+            self.clearance_copper2copper_cb, [self.clearance_copper2copper_lbl, self.clearance_copper2copper_entry])
+
+        # Copper2soldermask clearance
+        self.clearance_copper2sm_cb = FCCheckBox('%s:' % _("Copper to soldermask clearance"))
+        self.clearance_copper2sm_cb.setToolTip(
+            _("This checks if the minimum clearance between copper\n"
+              "features and soldermask features is met.")
         )
         )
-        form_layout.addRow(self.rows_label, self.rows)
-        form_layout.addRow(QtWidgets.QLabel(""))
+        form_layout_1.addRow(self.clearance_copper2sm_cb)
 
 
-        # Type of resulting Panel object
-        self.panel_type_radio = RadioSet([{'label': _('Gerber'), 'value': 'gerber'},
-                                          {'label': _('Geo'), 'value': 'geometry'}])
-        self.panel_type_label = QtWidgets.QLabel("<b>%s:</b>" % _("Panel Type"))
-        self.panel_type_label.setToolTip(
-            _("Choose the type of object for the panel object:\n"
-              "- Geometry\n"
-              "- Gerber")
+        # Copper2soldermask clearance value
+        self.clearance_copper2sm_entry = FCEntry()
+        self.clearance_copper2sm_lbl = QtWidgets.QLabel('%s:' % _("Min value"))
+        self.clearance_copper2sm_lbl.setToolTip(
+            _("Minimum acceptable clearance value.")
         )
         )
-        form_layout.addRow(self.panel_type_label)
-        form_layout.addRow(self.panel_type_radio)
-
-        # Constrains
-        self.constrain_cb = FCCheckBox('%s:' % _("Constrain panel within"))
-        self.constrain_cb.setToolTip(
-            _("Area define by DX and DY within to constrain the panel.\n"
-              "DX and DY values are in current units.\n"
-              "Regardless of how many columns and rows are desired,\n"
-              "the final panel will have as many columns and rows as\n"
-              "they fit completely within selected area.")
+        form_layout_1.addRow(self.clearance_copper2sm_lbl, self.clearance_copper2sm_entry)
+
+        self.c2sm = OptionalInputSection(
+            self.clearance_copper2sm_cb, [self.clearance_copper2sm_lbl, self.clearance_copper2sm_entry])
+
+        # Copper2silkscreen clearance
+        self.clearance_copper2sk_cb = FCCheckBox('%s:' % _("Copper to silkscreen clearance"))
+        self.clearance_copper2sk_cb.setToolTip(
+            _("This checks if the minimum clearance between copper\n"
+              "features and silkscreen features is met.")
+        )
+        form_layout_1.addRow(self.clearance_copper2sk_cb)
+
+        # Copper2silkscreen clearance value
+        self.clearance_copper2sk_entry = FCEntry()
+        self.clearance_copper2sk_lbl = QtWidgets.QLabel('%s:' % _("Min value"))
+        self.clearance_copper2sk_lbl.setToolTip(
+            _("Minimum acceptable clearance value.")
+        )
+        form_layout_1.addRow(self.clearance_copper2sk_lbl, self.clearance_copper2sk_entry)
+
+        self.c2sk = OptionalInputSection(
+            self.clearance_copper2sk_cb, [self.clearance_copper2sk_lbl, self.clearance_copper2sk_entry])
+
+        # Copper2outline clearance
+        self.clearance_copper2ol_cb = FCCheckBox('%s:' % _("Copper to outline clearance"))
+        self.clearance_copper2ol_cb.setToolTip(
+            _("This checks if the minimum clearance between copper\n"
+              "features and the outline is met.")
         )
         )
-        form_layout.addRow(self.constrain_cb)
+        form_layout_1.addRow(self.clearance_copper2ol_cb)
+
+        # Copper2outline clearance value
+        self.clearance_copper2ol_entry = FCEntry()
+        self.clearance_copper2ol_lbl = QtWidgets.QLabel('%s:' % _("Min value"))
+        self.clearance_copper2ol_lbl.setToolTip(
+            _("Minimum acceptable clearance value.")
+        )
+        form_layout_1.addRow(self.clearance_copper2ol_lbl, self.clearance_copper2ol_entry)
+
+        self.c2ol = OptionalInputSection(
+            self.clearance_copper2ol_cb, [self.clearance_copper2ol_lbl, self.clearance_copper2ol_entry])
 
 
-        self.x_width_entry = FCEntry()
-        self.x_width_lbl = QtWidgets.QLabel('%s:' % _("Width (DX)"))
-        self.x_width_lbl.setToolTip(
-            _("The width (DX) within which the panel must fit.\n"
-              "In current units.")
+        # Silkscreen2silkscreen clearance
+        self.clearance_silk2silk_cb = FCCheckBox('%s:' % _("Silkscreen to silkscreen clearance"))
+        self.clearance_silk2silk_cb.setToolTip(
+            _("This checks if the minimum clearance between silkscreen\n"
+              "features and silkscreen features is met.")
         )
         )
-        form_layout.addRow(self.x_width_lbl, self.x_width_entry)
+        form_layout_1.addRow(self.clearance_silk2silk_cb)
 
 
-        self.y_height_entry = FCEntry()
-        self.y_height_lbl = QtWidgets.QLabel('%s:' % _("Height (DY)"))
-        self.y_height_lbl.setToolTip(
-            _("The height (DY)within which the panel must fit.\n"
-              "In current units.")
+        # Copper2silkscreen clearance value
+        self.clearance_silk2silk_entry = FCEntry()
+        self.clearance_silk2silk_lbl = QtWidgets.QLabel('%s:' % _("Min value"))
+        self.clearance_silk2silk_lbl.setToolTip(
+            _("Minimum acceptable clearance value.")
         )
         )
-        form_layout.addRow(self.y_height_lbl, self.y_height_entry)
+        form_layout_1.addRow(self.clearance_silk2silk_lbl, self.clearance_silk2silk_entry)
 
 
-        self.constrain_sel = OptionalInputSection(
-            self.constrain_cb, [self.x_width_lbl, self.x_width_entry, self.y_height_lbl, self.y_height_entry])
+        self.s2s = OptionalInputSection(
+            self.clearance_silk2silk_cb, [self.clearance_silk2silk_lbl, self.clearance_silk2silk_entry])
+
+        # Silkscreen2soldermask clearance
+        self.clearance_silk2sm_cb = FCCheckBox('%s:' % _("Silkscreen to soldermask clearance"))
+        self.clearance_silk2sm_cb.setToolTip(
+            _("This checks if the minimum clearance between silkscreen\n"
+              "features and soldermask features is met.")
+        )
+        form_layout_1.addRow(self.clearance_silk2sm_cb)
+
+        # Silkscreen2soldermask clearance value
+        self.clearance_silk2sm_entry = FCEntry()
+        self.clearance_silk2sm_lbl = QtWidgets.QLabel('%s:' % _("Min value"))
+        self.clearance_silk2sm_lbl.setToolTip(
+            _("Minimum acceptable clearance value.")
+        )
+        form_layout_1.addRow(self.clearance_silk2sm_lbl, self.clearance_silk2sm_entry)
+
+        self.s2sm = OptionalInputSection(
+            self.clearance_silk2sm_cb, [self.clearance_silk2sm_lbl, self.clearance_silk2sm_entry])
+
+        # Soldermask2soldermask clearance
+        self.clearance_sm2sm_cb = FCCheckBox('%s:' % _("Soldermask to soldermask clearance"))
+        self.clearance_sm2sm_cb.setToolTip(
+            _("This checks if the minimum clearance between soldermask\n"
+              "features and soldermask features is met.")
+        )
+        form_layout_1.addRow(self.clearance_sm2sm_cb)
+
+        # Soldermask2soldermask clearance value
+        self.clearance_sm2sm_entry = FCEntry()
+        self.clearance_sm2sm_lbl = QtWidgets.QLabel('%s:' % _("Min value"))
+        self.clearance_sm2sm_lbl.setToolTip(
+            _("Minimum acceptable clearance value.")
+        )
+        form_layout_1.addRow(self.clearance_sm2sm_lbl, self.clearance_sm2sm_entry)
+
+        self.sm2sm = OptionalInputSection(
+            self.clearance_sm2sm_cb, [self.clearance_sm2sm_lbl, self.clearance_sm2sm_entry])
+
+        form_layout_1.addRow(QtWidgets.QLabel(""))
+
+        # Drill2Drill clearance
+        self.clearance_d2d_cb = FCCheckBox('%s:' % _("Drill hole to drill hole clearance"))
+        self.clearance_d2d_cb.setToolTip(
+            _("This checks if the minimum clearance between a drill hole\n"
+              "and another drill hole is met.")
+        )
+        form_layout_1.addRow(self.clearance_d2d_cb)
+
+        # Drill2Drill clearance value
+        self.clearance_d2d_entry = FCEntry()
+        self.clearance_d2d_lbl = QtWidgets.QLabel('%s:' % _("Min value"))
+        self.clearance_d2d_lbl.setToolTip(
+            _("Minimum acceptable clearance value.")
+        )
+        form_layout_1.addRow(self.clearance_d2d_lbl, self.clearance_d2d_entry)
+
+        self.d2d = OptionalInputSection(
+            self.clearance_d2d_cb, [self.clearance_d2d_lbl, self.clearance_d2d_entry])
+
+        # Ring integrity check
+        self.ring_integrity_cb = FCCheckBox('%s:' % _("Ring integrity check"))
+        self.ring_integrity_cb.setToolTip(
+            _("This checks if the minimum copper ring left by drilling\n"
+              "a hole into a pad is met.")
+        )
+        form_layout_1.addRow(self.ring_integrity_cb)
+
+        # Ring integrity value
+        self.ring_integrity_entry = FCEntry()
+        self.ring_integrity_lbl = QtWidgets.QLabel('%s:' % _("Min value"))
+        self.ring_integrity_lbl.setToolTip(
+            _("Minimum acceptable ring value.")
+        )
+        form_layout_1.addRow(self.ring_integrity_lbl, self.ring_integrity_entry)
+
+        self.d2d = OptionalInputSection(
+            self.ring_integrity_cb, [self.ring_integrity_lbl, self.ring_integrity_entry])
+
+        # Drill holes overlap check
+        self.drill_overlap_cb = FCCheckBox('%s:' % _("Drill hole overlap check"))
+        self.drill_overlap_cb.setToolTip(
+            _("This checks if drill holes are overlapping\n"
+              "one over another.")
+        )
+        form_layout_1.addRow(self.drill_overlap_cb)
 
 
         # Buttons
         # Buttons
         hlay_2 = QtWidgets.QHBoxLayout()
         hlay_2 = QtWidgets.QHBoxLayout()
         self.layout.addLayout(hlay_2)
         self.layout.addLayout(hlay_2)
 
 
-        hlay_2.addStretch()
-        self.panelize_object_button = QtWidgets.QPushButton(_("Panelize Object"))
-        self.panelize_object_button.setToolTip(
+        # hlay_2.addStretch()
+        self.run_button = QtWidgets.QPushButton(_("Run Rules Check"))
+        self.run_button.setToolTip(
             _("Panelize the specified object around the specified box.\n"
             _("Panelize the specified object around the specified box.\n"
               "In other words it creates multiple copies of the source object,\n"
               "In other words it creates multiple copies of the source object,\n"
               "arranged in a 2D array of rows and columns.")
               "arranged in a 2D array of rows and columns.")
         )
         )
-        hlay_2.addWidget(self.panelize_object_button)
+        hlay_2.addWidget(self.run_button)
 
 
         self.layout.addStretch()
         self.layout.addStretch()
 
 
-        # Signals
-        self.reference_radio.activated_custom.connect(self.on_reference_radio_changed)
-        self.panelize_object_button.clicked.connect(self.on_panelize)
-        self.type_obj_combo.currentIndexChanged.connect(self.on_type_obj_index_changed)
-        self.type_box_combo.currentIndexChanged.connect(self.on_type_box_index_changed)
+        # #######################################################
+        # ################ SIGNALS ##############################
+        # #######################################################
+
+        # self.app.collection.rowsInserted.connect(self.on_object_loaded)
 
 
         # list to hold the temporary objects
         # list to hold the temporary objects
         self.objs = []
         self.objs = []
@@ -249,8 +351,11 @@ class RulesCheck(FlatCAMTool):
         # flag to signal the constrain was activated
         # flag to signal the constrain was activated
         self.constrain_flag = False
         self.constrain_flag = False
 
 
+    # def on_object_loaded(self, index, row):
+    #     print(index.internalPointer().child_items[row].obj.options['name'], index.data())
+
     def run(self, toggle=True):
     def run(self, toggle=True):
-        self.app.report_usage("ToolPanelize()")
+        self.app.report_usage("ToolRulesCheck()")
 
 
         if toggle:
         if toggle:
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same
             # if the splitter is hidden, display it, else hide it but only if the current widget is the same
@@ -274,549 +379,485 @@ class RulesCheck(FlatCAMTool):
         FlatCAMTool.run(self)
         FlatCAMTool.run(self)
         self.set_tool_ui()
         self.set_tool_ui()
 
 
-        self.app.ui.notebook.setTabText(2, _("Panel. Tool"))
+        self.app.ui.notebook.setTabText(2, _("Rules Tool"))
 
 
     def install(self, icon=None, separator=None, **kwargs):
     def install(self, icon=None, separator=None, **kwargs):
-        FlatCAMTool.install(self, icon, separator, shortcut='ALT+Z', **kwargs)
+        FlatCAMTool.install(self, icon, separator, shortcut='ALT+R', **kwargs)
 
 
     def set_tool_ui(self):
     def set_tool_ui(self):
         self.reset_fields()
         self.reset_fields()
 
 
-        self.reference_radio.set_value('bbox')
-
-        sp_c = self.app.defaults["tools_panelize_spacing_columns"] if \
-            self.app.defaults["tools_panelize_spacing_columns"] else 0.0
-        self.spacing_columns.set_value(float(sp_c))
-
-        sp_r = self.app.defaults["tools_panelize_spacing_rows"] if \
-            self.app.defaults["tools_panelize_spacing_rows"] else 0.0
-        self.spacing_rows.set_value(float(sp_r))
-
-        rr = self.app.defaults["tools_panelize_rows"] if \
-            self.app.defaults["tools_panelize_rows"] else 0.0
-        self.rows.set_value(int(rr))
-
-        cc = self.app.defaults["tools_panelize_columns"] if \
-            self.app.defaults["tools_panelize_columns"] else 0.0
-        self.columns.set_value(int(cc))
-
-        c_cb = self.app.defaults["tools_panelize_constrain"] if \
-            self.app.defaults["tools_panelize_constrain"] else False
-        self.constrain_cb.set_value(c_cb)
-
-        x_w = self.app.defaults["tools_panelize_constrainx"] if \
-            self.app.defaults["tools_panelize_constrainx"] else 0.0
-        self.x_width_entry.set_value(float(x_w))
-
-        y_w = self.app.defaults["tools_panelize_constrainy"] if \
-            self.app.defaults["tools_panelize_constrainy"] else 0.0
-        self.y_height_entry.set_value(float(y_w))
-
-        panel_type = self.app.defaults["tools_panelize_panel_type"] if \
-            self.app.defaults["tools_panelize_panel_type"] else 'gerber'
-        self.panel_type_radio.set_value(panel_type)
-
-    def on_type_obj_index_changed(self):
-        obj_type = self.type_obj_combo.currentIndex()
-        self.object_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex()))
-        self.object_combo.setCurrentIndex(0)
-
-        # hide the panel type for Excellons, the panel can be only of type Geometry
-        if self.type_obj_combo.currentText() != 'Excellon':
-            self.panel_type_label.setDisabled(False)
-            self.panel_type_radio.setDisabled(False)
-        else:
-            self.panel_type_label.setDisabled(True)
-            self.panel_type_radio.setDisabled(True)
-            self.panel_type_radio.set_value('geometry')
-
-    def on_type_box_index_changed(self):
-        obj_type = self.type_box_combo.currentIndex()
-        self.box_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex()))
-        self.box_combo.setCurrentIndex(0)
-
-    def on_reference_radio_changed(self, current_val):
-        if current_val == 'object':
-            self.type_box_combo.setDisabled(False)
-            self.type_box_combo_label.setDisabled(False)
-            self.box_combo.setDisabled(False)
-            self.box_combo_label.setDisabled(False)
-        else:
-            self.type_box_combo.setDisabled(True)
-            self.type_box_combo_label.setDisabled(True)
-            self.box_combo.setDisabled(True)
-            self.box_combo_label.setDisabled(True)
-
-    def on_panelize(self):
-        name = self.object_combo.currentText()
-
-        # Get source object.
-        try:
-            obj = self.app.collection.get_by_name(str(name))
-        except Exception as e:
-            log.debug("Panelize.on_panelize() --> %s" % str(e))
-            self.app.inform.emit('[ERROR_NOTCL] %s: %s' %
-                                 (_("Could not retrieve object"), name))
-            return "Could not retrieve object: %s" % name
-
-        panel_obj = obj
-
-        if panel_obj is None:
-            self.app.inform.emit('[ERROR_NOTCL] %s: %s' %
-                                 (_("Object not found"), panel_obj))
-            return "Object not found: %s" % panel_obj
-
-        boxname = self.box_combo.currentText()
-
-        try:
-            box = self.app.collection.get_by_name(boxname)
-        except Exception as e:
-            log.debug("Panelize.on_panelize() --> %s" % str(e))
-            self.app.inform.emit('[ERROR_NOTCL] %s: %s' %
-                                 (_("Could not retrieve object"), boxname))
-            return "Could not retrieve object: %s" % boxname
-
-        if box is None:
-            self.app.inform.emit('[WARNING_NOTCL]%s: %s' %
-                                 (_("No object Box. Using instead"), panel_obj))
-            self.reference_radio.set_value('bbox')
-
-        if self.reference_radio.get_value() == 'bbox':
-            box = panel_obj
-
-        self.outname = name + '_panelized'
-
-        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] %s' %
-                                     _("Wrong value format entered, use a number."))
-                return
-        spacing_columns = spacing_columns if spacing_columns is not None else 0
-
-        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] %s' %
-                                     _("Wrong value format entered, use a number."))
-                return
-        spacing_rows = spacing_rows if spacing_rows is not None else 0
-
-        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] %s' %
-                                     _("Wrong value format entered, use a number."))
-                return
-        rows = rows if rows is not None else 1
-
-        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] %s' %
-                                     _("Wrong value format entered, use a number."))
-                return
-        columns = columns if columns is not None else 1
-
-        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] %s' %
-                                     _("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] %s' %
-                                     _("Wrong value format entered, use a number."))
-                return
-
-        panel_type = str(self.panel_type_radio.get_value())
-
-        if 0 in {columns, rows}:
-            self.app.inform.emit('[ERROR_NOTCL] %s' %
-                                 _("Columns or Rows are zero value. Change them to a positive integer."))
-            return "Columns or Rows are zero value. Change them to a positive integer."
-
-        xmin, ymin, xmax, ymax = box.bounds()
-        lenghtx = xmax - xmin + spacing_columns
-        lenghty = ymax - ymin + spacing_rows
-
-        # check if constrain within an area is desired
-        if self.constrain_cb.isChecked():
-            panel_lengthx = ((xmax - xmin) * columns) + (spacing_columns * (columns - 1))
-            panel_lengthy = ((ymax - ymin) * rows) + (spacing_rows * (rows - 1))
-
-            # adjust the number of columns and/or rows so the panel will fit within the panel constraint area
-            if (panel_lengthx > constrain_dx) or (panel_lengthy > constrain_dy):
-                self.constrain_flag = True
-
-                while panel_lengthx > constrain_dx:
-                    columns -= 1
-                    panel_lengthx = ((xmax - xmin) * columns) + (spacing_columns * (columns - 1))
-                while panel_lengthy > constrain_dy:
-                    rows -= 1
-                    panel_lengthy = ((ymax - ymin) * rows) + (spacing_rows * (rows - 1))
-
-        def panelize_2():
-            if panel_obj is not None:
-                self.app.inform.emit(_("Generating panel ... "))
-
-                self.app.progress.emit(0)
-
-                def job_init_excellon(obj_fin, app_obj):
-                    currenty = 0.0
-                    self.app.progress.emit(10)
-                    obj_fin.tools = panel_obj.tools.copy()
-                    obj_fin.drills = []
-                    obj_fin.slots = []
-                    obj_fin.solid_geometry = []
-
-                    for option in panel_obj.options:
-                        if option is not 'name':
-                            try:
-                                obj_fin.options[option] = panel_obj.options[option]
-                            except KeyError:
-                                log.warning("Failed to copy option. %s" % str(option))
-
-                    geo_len_drills = len(panel_obj.drills) if panel_obj.drills else 0
-                    geo_len_slots = len(panel_obj.slots) if panel_obj.slots else 0
-
-                    element = 0
-                    for row in range(rows):
-                        currentx = 0.0
-                        for col in range(columns):
-                            element += 1
-                            disp_number = 0
-                            old_disp_number = 0
-
-                            if panel_obj.drills:
-                                drill_nr = 0
-                                for tool_dict in panel_obj.drills:
-                                    if self.app.abort_flag:
-                                        # graceful abort requested by the user
-                                        raise FlatCAMApp.GracefulException
-
-                                    point_offseted = affinity.translate(tool_dict['point'], currentx, currenty)
-                                    obj_fin.drills.append(
-                                        {
-                                            "point": point_offseted,
-                                            "tool": tool_dict['tool']
-                                        }
-                                    )
-
-                                    drill_nr += 1
-                                    disp_number = int(np.interp(drill_nr, [0, geo_len_drills], [0, 100]))
-
-                                    if disp_number > old_disp_number and disp_number <= 100:
-                                        self.app.proc_container.update_view_text(' %s: %d D:%d%%' %
-                                                                                 (_("Copy"),
-                                                                                  int(element),
-                                                                                  disp_number))
-                                        old_disp_number = disp_number
-
-                            if panel_obj.slots:
-                                slot_nr = 0
-                                for tool_dict in panel_obj.slots:
-                                    if self.app.abort_flag:
-                                        # graceful abort requested by the user
-                                        raise FlatCAMApp.GracefulException
-
-                                    start_offseted = affinity.translate(tool_dict['start'], currentx, currenty)
-                                    stop_offseted = affinity.translate(tool_dict['stop'], currentx, currenty)
-                                    obj_fin.slots.append(
-                                        {
-                                            "start": start_offseted,
-                                            "stop": stop_offseted,
-                                            "tool": tool_dict['tool']
-                                        }
-                                    )
-
-                                    slot_nr += 1
-                                    disp_number = int(np.interp(slot_nr, [0, geo_len_slots], [0, 100]))
-
-                                    if disp_number > old_disp_number and disp_number <= 100:
-                                        self.app.proc_container.update_view_text(' %s: %d S:%d%%' %
-                                                                                 (_("Copy"),
-                                                                                  int(element),
-                                                                                  disp_number))
-                                        old_disp_number = disp_number
-
-                            currentx += lenghtx
-                        currenty += lenghty
-
-                    obj_fin.create_geometry()
-                    obj_fin.zeros = panel_obj.zeros
-                    obj_fin.units = panel_obj.units
-                    self.app.proc_container.update_view_text('')
-
-                def job_init_geometry(obj_fin, app_obj):
-                    currentx = 0.0
-                    currenty = 0.0
-
-                    def translate_recursion(geom):
-                        if type(geom) == list:
-                            geoms = list()
-                            for local_geom in geom:
-                                res_geo = translate_recursion(local_geom)
-                                try:
-                                    geoms += res_geo
-                                except TypeError:
-                                    geoms.append(res_geo)
-                            return geoms
-                        else:
-                            return affinity.translate(geom, xoff=currentx, yoff=currenty)
-
-                    obj_fin.solid_geometry = []
-
-                    # create the initial structure on which to create the panel
-                    if isinstance(panel_obj, FlatCAMGeometry):
-                        obj_fin.multigeo = panel_obj.multigeo
-                        obj_fin.tools = deepcopy(panel_obj.tools)
-                        if panel_obj.multigeo is True:
-                            for tool in panel_obj.tools:
-                                obj_fin.tools[tool]['solid_geometry'][:] = []
-                    elif isinstance(panel_obj, FlatCAMGerber):
-                        obj_fin.apertures = deepcopy(panel_obj.apertures)
-                        for ap in obj_fin.apertures:
-                            obj_fin.apertures[ap]['geometry'] = list()
-
-                    # find the number of polygons in the source solid_geometry
-                    geo_len = 0
-                    if isinstance(panel_obj, FlatCAMGeometry):
-                        if panel_obj.multigeo is True:
-                            for tool in panel_obj.tools:
-                                try:
-                                    for pol in panel_obj.tools[tool]['solid_geometry']:
-                                        geo_len += 1
-                                except TypeError:
-                                    geo_len = 1
-                        else:
-                            try:
-                                for pol in panel_obj.solid_geometry:
-                                    geo_len += 1
-                            except TypeError:
-                                geo_len = 1
-                    elif isinstance(panel_obj, FlatCAMGerber):
-                        for ap in panel_obj.apertures:
-                            for elem in panel_obj.apertures[ap]['geometry']:
-                                geo_len += 1
-
-                    self.app.progress.emit(0)
-                    element = 0
-                    for row in range(rows):
-                        currentx = 0.0
-
-                        for col in range(columns):
-                            element += 1
-                            disp_number = 0
-                            old_disp_number = 0
-
-                            if isinstance(panel_obj, FlatCAMGeometry):
-                                if panel_obj.multigeo is True:
-                                    for tool in panel_obj.tools:
-                                        if self.app.abort_flag:
-                                            # graceful abort requested by the user
-                                            raise FlatCAMApp.GracefulException
-
-                                        # geo = translate_recursion(panel_obj.tools[tool]['solid_geometry'])
-                                        # if isinstance(geo, list):
-                                        #     obj_fin.tools[tool]['solid_geometry'] += geo
-                                        # else:
-                                        #     obj_fin.tools[tool]['solid_geometry'].append(geo)
-
-                                        # calculate the number of polygons
-                                        geo_len = len(panel_obj.tools[tool]['solid_geometry'])
-                                        pol_nr = 0
-                                        for geo_el in panel_obj.tools[tool]['solid_geometry']:
-                                            trans_geo = translate_recursion(geo_el)
-                                            obj_fin.tools[tool]['solid_geometry'].append(trans_geo)
-
-                                            pol_nr += 1
-                                            disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100]))
-
-                                            if old_disp_number < disp_number <= 100:
-                                                self.app.proc_container.update_view_text(' %s: %d %d%%' %
-                                                                                         (_("Copy"),
-                                                                                          int(element),
-                                                                                          disp_number))
-                                                old_disp_number = disp_number
-                                else:
-                                    # geo = translate_recursion(panel_obj.solid_geometry)
-                                    # if isinstance(geo, list):
-                                    #     obj_fin.solid_geometry += geo
-                                    # else:
-                                    #     obj_fin.solid_geometry.append(geo)
-                                    if self.app.abort_flag:
-                                        # graceful abort requested by the user
-                                        raise FlatCAMApp.GracefulException
-
-                                    try:
-                                        # calculate the number of polygons
-                                        geo_len = len(panel_obj.solid_geometry)
-                                    except TypeError:
-                                        geo_len = 1
-                                    pol_nr = 0
-                                    try:
-                                        for geo_el in panel_obj.solid_geometry:
-                                            if self.app.abort_flag:
-                                                # graceful abort requested by the user
-                                                raise FlatCAMApp.GracefulException
-
-                                            trans_geo = translate_recursion(geo_el)
-                                            obj_fin.solid_geometry.append(trans_geo)
-
-                                            pol_nr += 1
-                                            disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100]))
-
-                                            if old_disp_number < disp_number <= 100:
-                                                self.app.proc_container.update_view_text(' %s: %d %d%%' %
-                                                                                         (_("Copy"),
-                                                                                          int(element),
-                                                                                          disp_number))
-                                                old_disp_number = disp_number
-                                    except TypeError:
-                                        trans_geo = translate_recursion(panel_obj.solid_geometry)
-                                        obj_fin.solid_geometry.append(trans_geo)
-                            else:
-                                # geo = translate_recursion(panel_obj.solid_geometry)
-                                # if isinstance(geo, list):
-                                #     obj_fin.solid_geometry += geo
-                                # else:
-                                #     obj_fin.solid_geometry.append(geo)
-                                if self.app.abort_flag:
-                                    # graceful abort requested by the user
-                                    raise FlatCAMApp.GracefulException
-
-                                try:
-                                    for geo_el in panel_obj.solid_geometry:
-                                        if self.app.abort_flag:
-                                            # graceful abort requested by the user
-                                            raise FlatCAMApp.GracefulException
-
-                                        trans_geo = translate_recursion(geo_el)
-                                        obj_fin.solid_geometry.append(trans_geo)
-                                except TypeError:
-                                    trans_geo = translate_recursion(panel_obj.solid_geometry)
-                                    obj_fin.solid_geometry.append(trans_geo)
-
-                                for apid in panel_obj.apertures:
-                                    if self.app.abort_flag:
-                                        # graceful abort requested by the user
-                                        raise FlatCAMApp.GracefulException
-
-                                    try:
-                                        # calculate the number of polygons
-                                        geo_len = len(panel_obj.apertures[apid]['geometry'])
-                                    except TypeError:
-                                        geo_len = 1
-                                    pol_nr = 0
-                                    for el in panel_obj.apertures[apid]['geometry']:
-                                        if self.app.abort_flag:
-                                            # graceful abort requested by the user
-                                            raise FlatCAMApp.GracefulException
-
-                                        new_el = dict()
-                                        if 'solid' in el:
-                                            geo_aper = translate_recursion(el['solid'])
-                                            new_el['solid'] = geo_aper
-
-                                        if 'clear' in el:
-                                            geo_aper = translate_recursion(el['clear'])
-                                            new_el['clear'] = geo_aper
-
-                                        if 'follow' in el:
-                                            geo_aper = translate_recursion(el['follow'])
-                                            new_el['follow'] = geo_aper
-
-                                        obj_fin.apertures[apid]['geometry'].append(deepcopy(new_el))
-
-                                        pol_nr += 1
-                                        disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100]))
-
-                                        if old_disp_number < disp_number <= 100:
-                                            self.app.proc_container.update_view_text(' %s: %d %d%%' %
-                                                                                     (_("Copy"),
-                                                                                      int(element),
-                                                                                      disp_number))
-                                            old_disp_number = disp_number
-
-                            currentx += lenghtx
-                        currenty += lenghty
-
-                    if panel_type == 'gerber':
-                        self.app.inform.emit('%s' %
-                                             _("Generating panel ... Adding the Gerber code."))
-                        obj_fin.source_file = self.app.export_gerber(obj_name=self.outname, filename=None,
-                                                                     local_use=obj_fin, use_thread=False)
-
-                    # app_obj.log.debug("Found %s geometries. Creating a panel geometry cascaded union ..." %
-                    #                   len(obj_fin.solid_geometry))
-
-                    # obj_fin.solid_geometry = cascaded_union(obj_fin.solid_geometry)
-                    # app_obj.log.debug("Finished creating a cascaded union for the panel.")
-                    self.app.proc_container.update_view_text('')
-
-                self.app.inform.emit('%s: %d' %
-                                     (_("Generating panel... Spawning copies"), (int(rows * columns))))
-                if isinstance(panel_obj, FlatCAMExcellon):
-                    self.app.progress.emit(50)
-                    self.app.new_object("excellon", self.outname, job_init_excellon, plot=True, autoselected=True)
-                else:
-                    self.app.progress.emit(50)
-                    self.app.new_object(panel_type, self.outname, job_init_geometry,
-                                        plot=True, autoselected=True)
-
-        if self.constrain_flag is False:
-            self.app.inform.emit('[success] %s' % _("Panel done..."))
-        else:
-            self.constrain_flag = False
-            self.app.inform.emit(_("{text} Too big for the constrain area. "
-                                   "Final panel has {col} columns and {row} rows").format(
-                text='[WARNING] ', col=columns, row=rows))
-
-        proc = self.app.proc_container.new(_("Working..."))
-
-        def job_thread(app_obj):
-            try:
-                panelize_2()
-                self.app.inform.emit('[success] %s' % _("Panel created successfully."))
-            except Exception as ee:
-                proc.done()
-                log.debug(str(ee))
-                return
-            proc.done()
-
-        self.app.collection.promise(self.outname)
-        self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
+    # def on_panelize(self):
+    #     name = self.object_combo.currentText()
+    #
+    #     # Get source object.
+    #     try:
+    #         obj = self.app.collection.get_by_name(str(name))
+    #     except Exception as e:
+    #         log.debug("Panelize.on_panelize() --> %s" % str(e))
+    #         self.app.inform.emit('[ERROR_NOTCL] %s: %s' %
+    #                              (_("Could not retrieve object"), name))
+    #         return "Could not retrieve object: %s" % name
+    #
+    #     panel_obj = obj
+    #
+    #     if panel_obj is None:
+    #         self.app.inform.emit('[ERROR_NOTCL] %s: %s' %
+    #                              (_("Object not found"), panel_obj))
+    #         return "Object not found: %s" % panel_obj
+    #
+    #     boxname = self.box_combo.currentText()
+    #
+    #     try:
+    #         box = self.app.collection.get_by_name(boxname)
+    #     except Exception as e:
+    #         log.debug("Panelize.on_panelize() --> %s" % str(e))
+    #         self.app.inform.emit('[ERROR_NOTCL] %s: %s' %
+    #                              (_("Could not retrieve object"), boxname))
+    #         return "Could not retrieve object: %s" % boxname
+    #
+    #     if box is None:
+    #         self.app.inform.emit('[WARNING_NOTCL]%s: %s' %
+    #                              (_("No object Box. Using instead"), panel_obj))
+    #         self.reference_radio.set_value('bbox')
+    #
+    #     if self.reference_radio.get_value() == 'bbox':
+    #         box = panel_obj
+    #
+    #     self.outname = name + '_panelized'
+    #
+    #     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] %s' %
+    #                                  _("Wrong value format entered, use a number."))
+    #             return
+    #     spacing_columns = spacing_columns if spacing_columns is not None else 0
+    #
+    #     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] %s' %
+    #                                  _("Wrong value format entered, use a number."))
+    #             return
+    #     spacing_rows = spacing_rows if spacing_rows is not None else 0
+    #
+    #     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] %s' %
+    #                                  _("Wrong value format entered, use a number."))
+    #             return
+    #     rows = rows if rows is not None else 1
+    #
+    #     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] %s' %
+    #                                  _("Wrong value format entered, use a number."))
+    #             return
+    #     columns = columns if columns is not None else 1
+    #
+    #     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] %s' %
+    #                                  _("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] %s' %
+    #                                  _("Wrong value format entered, use a number."))
+    #             return
+    #
+    #     panel_type = str(self.panel_type_radio.get_value())
+    #
+    #     if 0 in {columns, rows}:
+    #         self.app.inform.emit('[ERROR_NOTCL] %s' %
+    #                              _("Columns or Rows are zero value. Change them to a positive integer."))
+    #         return "Columns or Rows are zero value. Change them to a positive integer."
+    #
+    #     xmin, ymin, xmax, ymax = box.bounds()
+    #     lenghtx = xmax - xmin + spacing_columns
+    #     lenghty = ymax - ymin + spacing_rows
+    #
+    #     # check if constrain within an area is desired
+    #     if self.constrain_cb.isChecked():
+    #         panel_lengthx = ((xmax - xmin) * columns) + (spacing_columns * (columns - 1))
+    #         panel_lengthy = ((ymax - ymin) * rows) + (spacing_rows * (rows - 1))
+    #
+    #         # adjust the number of columns and/or rows so the panel will fit within the panel constraint area
+    #         if (panel_lengthx > constrain_dx) or (panel_lengthy > constrain_dy):
+    #             self.constrain_flag = True
+    #
+    #             while panel_lengthx > constrain_dx:
+    #                 columns -= 1
+    #                 panel_lengthx = ((xmax - xmin) * columns) + (spacing_columns * (columns - 1))
+    #             while panel_lengthy > constrain_dy:
+    #                 rows -= 1
+    #                 panel_lengthy = ((ymax - ymin) * rows) + (spacing_rows * (rows - 1))
+    #
+    #     def panelize_2():
+    #         if panel_obj is not None:
+    #             self.app.inform.emit(_("Generating panel ... "))
+    #
+    #             self.app.progress.emit(0)
+    #
+    #             def job_init_excellon(obj_fin, app_obj):
+    #                 currenty = 0.0
+    #                 self.app.progress.emit(10)
+    #                 obj_fin.tools = panel_obj.tools.copy()
+    #                 obj_fin.drills = []
+    #                 obj_fin.slots = []
+    #                 obj_fin.solid_geometry = []
+    #
+    #                 for option in panel_obj.options:
+    #                     if option is not 'name':
+    #                         try:
+    #                             obj_fin.options[option] = panel_obj.options[option]
+    #                         except KeyError:
+    #                             log.warning("Failed to copy option. %s" % str(option))
+    #
+    #                 geo_len_drills = len(panel_obj.drills) if panel_obj.drills else 0
+    #                 geo_len_slots = len(panel_obj.slots) if panel_obj.slots else 0
+    #
+    #                 element = 0
+    #                 for row in range(rows):
+    #                     currentx = 0.0
+    #                     for col in range(columns):
+    #                         element += 1
+    #                         disp_number = 0
+    #                         old_disp_number = 0
+    #
+    #                         if panel_obj.drills:
+    #                             drill_nr = 0
+    #                             for tool_dict in panel_obj.drills:
+    #                                 if self.app.abort_flag:
+    #                                     # graceful abort requested by the user
+    #                                     raise FlatCAMApp.GracefulException
+    #
+    #                                 point_offseted = affinity.translate(tool_dict['point'], currentx, currenty)
+    #                                 obj_fin.drills.append(
+    #                                     {
+    #                                         "point": point_offseted,
+    #                                         "tool": tool_dict['tool']
+    #                                     }
+    #                                 )
+    #
+    #                                 drill_nr += 1
+    #                                 disp_number = int(np.interp(drill_nr, [0, geo_len_drills], [0, 100]))
+    #
+    #                                 if disp_number > old_disp_number and disp_number <= 100:
+    #                                     self.app.proc_container.update_view_text(' %s: %d D:%d%%' %
+    #                                                                              (_("Copy"),
+    #                                                                               int(element),
+    #                                                                               disp_number))
+    #                                     old_disp_number = disp_number
+    #
+    #                         if panel_obj.slots:
+    #                             slot_nr = 0
+    #                             for tool_dict in panel_obj.slots:
+    #                                 if self.app.abort_flag:
+    #                                     # graceful abort requested by the user
+    #                                     raise FlatCAMApp.GracefulException
+    #
+    #                                 start_offseted = affinity.translate(tool_dict['start'], currentx, currenty)
+    #                                 stop_offseted = affinity.translate(tool_dict['stop'], currentx, currenty)
+    #                                 obj_fin.slots.append(
+    #                                     {
+    #                                         "start": start_offseted,
+    #                                         "stop": stop_offseted,
+    #                                         "tool": tool_dict['tool']
+    #                                     }
+    #                                 )
+    #
+    #                                 slot_nr += 1
+    #                                 disp_number = int(np.interp(slot_nr, [0, geo_len_slots], [0, 100]))
+    #
+    #                                 if disp_number > old_disp_number and disp_number <= 100:
+    #                                     self.app.proc_container.update_view_text(' %s: %d S:%d%%' %
+    #                                                                              (_("Copy"),
+    #                                                                               int(element),
+    #                                                                               disp_number))
+    #                                     old_disp_number = disp_number
+    #
+    #                         currentx += lenghtx
+    #                     currenty += lenghty
+    #
+    #                 obj_fin.create_geometry()
+    #                 obj_fin.zeros = panel_obj.zeros
+    #                 obj_fin.units = panel_obj.units
+    #                 self.app.proc_container.update_view_text('')
+    #
+    #             def job_init_geometry(obj_fin, app_obj):
+    #                 currentx = 0.0
+    #                 currenty = 0.0
+    #
+    #                 def translate_recursion(geom):
+    #                     if type(geom) == list:
+    #                         geoms = list()
+    #                         for local_geom in geom:
+    #                             res_geo = translate_recursion(local_geom)
+    #                             try:
+    #                                 geoms += res_geo
+    #                             except TypeError:
+    #                                 geoms.append(res_geo)
+    #                         return geoms
+    #                     else:
+    #                         return affinity.translate(geom, xoff=currentx, yoff=currenty)
+    #
+    #                 obj_fin.solid_geometry = []
+    #
+    #                 # create the initial structure on which to create the panel
+    #                 if isinstance(panel_obj, FlatCAMGeometry):
+    #                     obj_fin.multigeo = panel_obj.multigeo
+    #                     obj_fin.tools = deepcopy(panel_obj.tools)
+    #                     if panel_obj.multigeo is True:
+    #                         for tool in panel_obj.tools:
+    #                             obj_fin.tools[tool]['solid_geometry'][:] = []
+    #                 elif isinstance(panel_obj, FlatCAMGerber):
+    #                     obj_fin.apertures = deepcopy(panel_obj.apertures)
+    #                     for ap in obj_fin.apertures:
+    #                         obj_fin.apertures[ap]['geometry'] = list()
+    #
+    #                 # find the number of polygons in the source solid_geometry
+    #                 geo_len = 0
+    #                 if isinstance(panel_obj, FlatCAMGeometry):
+    #                     if panel_obj.multigeo is True:
+    #                         for tool in panel_obj.tools:
+    #                             try:
+    #                                 for pol in panel_obj.tools[tool]['solid_geometry']:
+    #                                     geo_len += 1
+    #                             except TypeError:
+    #                                 geo_len = 1
+    #                     else:
+    #                         try:
+    #                             for pol in panel_obj.solid_geometry:
+    #                                 geo_len += 1
+    #                         except TypeError:
+    #                             geo_len = 1
+    #                 elif isinstance(panel_obj, FlatCAMGerber):
+    #                     for ap in panel_obj.apertures:
+    #                         for elem in panel_obj.apertures[ap]['geometry']:
+    #                             geo_len += 1
+    #
+    #                 self.app.progress.emit(0)
+    #                 element = 0
+    #                 for row in range(rows):
+    #                     currentx = 0.0
+    #
+    #                     for col in range(columns):
+    #                         element += 1
+    #                         disp_number = 0
+    #                         old_disp_number = 0
+    #
+    #                         if isinstance(panel_obj, FlatCAMGeometry):
+    #                             if panel_obj.multigeo is True:
+    #                                 for tool in panel_obj.tools:
+    #                                     if self.app.abort_flag:
+    #                                         # graceful abort requested by the user
+    #                                         raise FlatCAMApp.GracefulException
+    #
+    #                                     # geo = translate_recursion(panel_obj.tools[tool]['solid_geometry'])
+    #                                     # if isinstance(geo, list):
+    #                                     #     obj_fin.tools[tool]['solid_geometry'] += geo
+    #                                     # else:
+    #                                     #     obj_fin.tools[tool]['solid_geometry'].append(geo)
+    #
+    #                                     # calculate the number of polygons
+    #                                     geo_len = len(panel_obj.tools[tool]['solid_geometry'])
+    #                                     pol_nr = 0
+    #                                     for geo_el in panel_obj.tools[tool]['solid_geometry']:
+    #                                         trans_geo = translate_recursion(geo_el)
+    #                                         obj_fin.tools[tool]['solid_geometry'].append(trans_geo)
+    #
+    #                                         pol_nr += 1
+    #                                         disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100]))
+    #
+    #                                         if old_disp_number < disp_number <= 100:
+    #                                             self.app.proc_container.update_view_text(' %s: %d %d%%' %
+    #                                                                                      (_("Copy"),
+    #                                                                                       int(element),
+    #                                                                                       disp_number))
+    #                                             old_disp_number = disp_number
+    #                             else:
+    #                                 # geo = translate_recursion(panel_obj.solid_geometry)
+    #                                 # if isinstance(geo, list):
+    #                                 #     obj_fin.solid_geometry += geo
+    #                                 # else:
+    #                                 #     obj_fin.solid_geometry.append(geo)
+    #                                 if self.app.abort_flag:
+    #                                     # graceful abort requested by the user
+    #                                     raise FlatCAMApp.GracefulException
+    #
+    #                                 try:
+    #                                     # calculate the number of polygons
+    #                                     geo_len = len(panel_obj.solid_geometry)
+    #                                 except TypeError:
+    #                                     geo_len = 1
+    #                                 pol_nr = 0
+    #                                 try:
+    #                                     for geo_el in panel_obj.solid_geometry:
+    #                                         if self.app.abort_flag:
+    #                                             # graceful abort requested by the user
+    #                                             raise FlatCAMApp.GracefulException
+    #
+    #                                         trans_geo = translate_recursion(geo_el)
+    #                                         obj_fin.solid_geometry.append(trans_geo)
+    #
+    #                                         pol_nr += 1
+    #                                         disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100]))
+    #
+    #                                         if old_disp_number < disp_number <= 100:
+    #                                             self.app.proc_container.update_view_text(' %s: %d %d%%' %
+    #                                                                                      (_("Copy"),
+    #                                                                                       int(element),
+    #                                                                                       disp_number))
+    #                                             old_disp_number = disp_number
+    #                                 except TypeError:
+    #                                     trans_geo = translate_recursion(panel_obj.solid_geometry)
+    #                                     obj_fin.solid_geometry.append(trans_geo)
+    #                         else:
+    #                             # geo = translate_recursion(panel_obj.solid_geometry)
+    #                             # if isinstance(geo, list):
+    #                             #     obj_fin.solid_geometry += geo
+    #                             # else:
+    #                             #     obj_fin.solid_geometry.append(geo)
+    #                             if self.app.abort_flag:
+    #                                 # graceful abort requested by the user
+    #                                 raise FlatCAMApp.GracefulException
+    #
+    #                             try:
+    #                                 for geo_el in panel_obj.solid_geometry:
+    #                                     if self.app.abort_flag:
+    #                                         # graceful abort requested by the user
+    #                                         raise FlatCAMApp.GracefulException
+    #
+    #                                     trans_geo = translate_recursion(geo_el)
+    #                                     obj_fin.solid_geometry.append(trans_geo)
+    #                             except TypeError:
+    #                                 trans_geo = translate_recursion(panel_obj.solid_geometry)
+    #                                 obj_fin.solid_geometry.append(trans_geo)
+    #
+    #                             for apid in panel_obj.apertures:
+    #                                 if self.app.abort_flag:
+    #                                     # graceful abort requested by the user
+    #                                     raise FlatCAMApp.GracefulException
+    #
+    #                                 try:
+    #                                     # calculate the number of polygons
+    #                                     geo_len = len(panel_obj.apertures[apid]['geometry'])
+    #                                 except TypeError:
+    #                                     geo_len = 1
+    #                                 pol_nr = 0
+    #                                 for el in panel_obj.apertures[apid]['geometry']:
+    #                                     if self.app.abort_flag:
+    #                                         # graceful abort requested by the user
+    #                                         raise FlatCAMApp.GracefulException
+    #
+    #                                     new_el = dict()
+    #                                     if 'solid' in el:
+    #                                         geo_aper = translate_recursion(el['solid'])
+    #                                         new_el['solid'] = geo_aper
+    #
+    #                                     if 'clear' in el:
+    #                                         geo_aper = translate_recursion(el['clear'])
+    #                                         new_el['clear'] = geo_aper
+    #
+    #                                     if 'follow' in el:
+    #                                         geo_aper = translate_recursion(el['follow'])
+    #                                         new_el['follow'] = geo_aper
+    #
+    #                                     obj_fin.apertures[apid]['geometry'].append(deepcopy(new_el))
+    #
+    #                                     pol_nr += 1
+    #                                     disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100]))
+    #
+    #                                     if old_disp_number < disp_number <= 100:
+    #                                         self.app.proc_container.update_view_text(' %s: %d %d%%' %
+    #                                                                                  (_("Copy"),
+    #                                                                                   int(element),
+    #                                                                                   disp_number))
+    #                                         old_disp_number = disp_number
+    #
+    #                         currentx += lenghtx
+    #                     currenty += lenghty
+    #
+    #                 if panel_type == 'gerber':
+    #                     self.app.inform.emit('%s' %
+    #                                          _("Generating panel ... Adding the Gerber code."))
+    #                     obj_fin.source_file = self.app.export_gerber(obj_name=self.outname, filename=None,
+    #                                                                  local_use=obj_fin, use_thread=False)
+    #
+    #                 # app_obj.log.debug("Found %s geometries. Creating a panel geometry cascaded union ..." %
+    #                 #                   len(obj_fin.solid_geometry))
+    #
+    #                 # obj_fin.solid_geometry = cascaded_union(obj_fin.solid_geometry)
+    #                 # app_obj.log.debug("Finished creating a cascaded union for the panel.")
+    #                 self.app.proc_container.update_view_text('')
+    #
+    #             self.app.inform.emit('%s: %d' %
+    #                                  (_("Generating panel... Spawning copies"), (int(rows * columns))))
+    #             if isinstance(panel_obj, FlatCAMExcellon):
+    #                 self.app.progress.emit(50)
+    #                 self.app.new_object("excellon", self.outname, job_init_excellon, plot=True, autoselected=True)
+    #             else:
+    #                 self.app.progress.emit(50)
+    #                 self.app.new_object(panel_type, self.outname, job_init_geometry,
+    #                                     plot=True, autoselected=True)
+    #
+    #     if self.constrain_flag is False:
+    #         self.app.inform.emit('[success] %s' % _("Panel done..."))
+    #     else:
+    #         self.constrain_flag = False
+    #         self.app.inform.emit(_("{text} Too big for the constrain area. "
+    #                                "Final panel has {col} columns and {row} rows").format(
+    #             text='[WARNING] ', col=columns, row=rows))
+    #
+    #     proc = self.app.proc_container.new(_("Working..."))
+    #
+    #     def job_thread(app_obj):
+    #         try:
+    #             panelize_2()
+    #             self.app.inform.emit('[success] %s' % _("Panel created successfully."))
+    #         except Exception as ee:
+    #             proc.done()
+    #             log.debug(str(ee))
+    #             return
+    #         proc.done()
+    #
+    #     self.app.collection.promise(self.outname)
+    #     self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
 
 
     def reset_fields(self):
     def reset_fields(self):
-        self.object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
-        self.box_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
+        # self.object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
+        # self.box_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
+        pass

+ 1 - 1
flatcamTools/ToolTransform.py

@@ -403,7 +403,7 @@ class ToolTransform(FlatCAMTool):
         self.app.ui.notebook.setTabText(2, _("Transform Tool"))
         self.app.ui.notebook.setTabText(2, _("Transform Tool"))
 
 
     def install(self, icon=None, separator=None, **kwargs):
     def install(self, icon=None, separator=None, **kwargs):
-        FlatCAMTool.install(self, icon, separator, shortcut='ALT+R', **kwargs)
+        FlatCAMTool.install(self, icon, separator, shortcut='ALT+E', **kwargs)
 
 
     def set_tool_ui(self):
     def set_tool_ui(self):
         # ## Initialize form
         # ## Initialize form

BIN
share/open_script32.png


BIN
share/rules32.png