Browse Source

- 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 năm trước cách đây
mục cha
commit
c5ecc7ad88

+ 47 - 15
FlatCAMApp.py

@@ -2372,6 +2372,7 @@ class App(QtCore.QObject):
         self.film_tool = None
         self.paste_tool = None
         self.calculator_tool = None
+        self.rules_tool = None
         self.sub_tool = None
         self.move_tool = None
         self.cutout_tool = None
@@ -2909,6 +2910,9 @@ class App(QtCore.QObject):
         self.sub_tool = ToolSub(self)
         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.install(icon=QtGui.QIcon('share/move16.png'), pos=self.ui.menuedit,
                                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.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.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.transform_btn.triggered.connect(lambda: self.transform_tool.run(toggle=True))
@@ -6979,9 +6984,22 @@ class App(QtCore.QObject):
         #     return
 
         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 ..."),
                                  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:
                 try:
@@ -7004,7 +7022,8 @@ class App(QtCore.QObject):
         if self.is_legacy is False:
             canvas_origin = self.plotcanvas.native.mapToGlobal(QtCore.QPoint(0, 0))
             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:
             # find the canvas origin which is in the top left corner
             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
             # canvas) and the point (width, height) is in the top-right 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' %
                          _("Done."))
@@ -7799,8 +7832,6 @@ class App(QtCore.QObject):
             self.pos = (self.pos_canvas[0], self.pos_canvas[1])
 
         try:
-            modifiers = QtWidgets.QApplication.keyboardModifiers()
-
             if event.button == 1:
                 # Reset here the relative coordinates so there is a new reference on the click position
                 if self.rel_point1 is None:
@@ -7809,16 +7840,6 @@ class App(QtCore.QObject):
                     self.rel_point2 = copy(self.rel_point1)
                     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)
         except Exception as 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")
         try:
             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:
                     self.doubleclick = False
                     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
 
 - 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
 - made the mouse cursor (big, small) change in real time for both graphic engines
 - 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
 

+ 19 - 7
flatcamGUI/FlatCAMGUI.py

@@ -112,7 +112,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
         self.menufile_scripting.setToolTipsVisible(True)
 
         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'),
                                                    '%s\tSHIFT+S' % _('Run Script ...'), self)
         self.menufilerunscript.setToolTip(
@@ -664,7 +664,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
         # ## Shell Toolbar ##
         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.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 ...'))
 
         # ## Tools Toolbar ##
@@ -678,6 +678,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
         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.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()
 
@@ -1219,6 +1220,10 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
                         <td height="20"><strong>ALT+D</strong></td>
                         <td>&nbsp;%s</td>
                     </tr>
+                    <tr height="20">
+                        <td height="20"><strong>ALT+E</strong></td>
+                        <td>&nbsp;%s</td>
+                    </tr>
                     <tr height="20">
                         <td height="20"><strong>ALT+K</strong></td>
                         <td>&nbsp;%s</td>
@@ -1326,9 +1331,11 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
                 _("Open Project"), _("Save Project As"), _("Toggle Plot Area"), _("Copy Obj_Name"),
                 _("Toggle Code Editor"), _("Toggle the axis"), _("Open Preferences Window"),
                 _("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"),
-                _("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"),
                 _("Toggle Full Screen"), _("Abort current task (gracefully)"), _("Open Online Manual"),
                 _("Open Online Tutorials"), _("Refresh Plots"), _("Delete Object"), _("Alternate: Delete Tool"),
@@ -2102,7 +2109,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
         # ## Shell Toolbar # ##
         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.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 ...'))
 
         # ## Tools Toolbar # ##
@@ -2406,6 +2413,11 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
                     self.app.dblsidedtool.run(toggle=True)
                     return
 
+                # Transformation Tool
+                if key == QtCore.Qt.Key_E:
+                    self.app.transform_tool.run(toggle=True)
+                    return
+
                 # Solder Paste Dispensing Tool
                 if key == QtCore.Qt.Key_K:
                     self.app.paste_tool.run(toggle=True)
@@ -2431,9 +2443,9 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
                     self.app.pdf_tool.run()
                     return
 
-                # Transformation Tool
+                # Rules Tool
                 if key == QtCore.Qt.Key_R:
-                    self.app.transform_tool.run(toggle=True)
+                    self.app.rules_tool.run(toggle=True)
                     return
 
                 # View Source Object Content

+ 10 - 5
flatcamGUI/GUIElements.py

@@ -1734,21 +1734,26 @@ class FCDoubleSpinner(QtWidgets.QDoubleSpinBox):
 
 
 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 label: string with the message inside the dialog box
         """
         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
 
-        dialog_box = QtWidgets.QInputDialog()
-        dialog_box.setMinimumWidth(290)
+        self.dialog_box = QtWidgets.QInputDialog()
+        self.dialog_box.setMinimumWidth(290)
         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
 
     def mousePressEvent(self, e, parent=None):

+ 740 - 699
flatcamTools/ToolRulesCheck.py

@@ -22,7 +22,7 @@ if '_' not in builtins.__dict__:
 
 class RulesCheck(FlatCAMTool):
 
-    toolName = _("Check Rules PCB")
+    toolName = _("Check Rules")
 
     def __init__(self, app):
         super(RulesCheck, self).__init__(self)
@@ -40,205 +40,307 @@ class RulesCheck(FlatCAMTool):
         self.layout.addWidget(title_label)
 
         # 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"
               "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(""))
 
-        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
         hlay_2 = QtWidgets.QHBoxLayout()
         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"
               "In other words it creates multiple copies of the source object,\n"
               "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()
 
-        # 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
         self.objs = []
@@ -249,8 +351,11 @@ class RulesCheck(FlatCAMTool):
         # flag to signal the constrain was activated
         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):
-        self.app.report_usage("ToolPanelize()")
+        self.app.report_usage("ToolRulesCheck()")
 
         if toggle:
             # 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)
         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):
-        FlatCAMTool.install(self, icon, separator, shortcut='ALT+Z', **kwargs)
+        FlatCAMTool.install(self, icon, separator, shortcut='ALT+R', **kwargs)
 
     def set_tool_ui(self):
         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):
-        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"))
 
     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):
         # ## Initialize form

BIN
share/open_script32.png


BIN
share/rules32.png