diff --git a/FlatCAMApp.py b/FlatCAMApp.py
index bee19cc9..31c3a45e 100644
--- a/FlatCAMApp.py
+++ b/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(" X: %.4f "
+ "Y: %.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("Dx: %.4f Dy: "
+ "%.4f " % (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():
diff --git a/README.md b/README.md
index a28150c2..0016799f 100644
--- a/README.md
+++ b/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
diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py
index a1821e5b..9950479f 100644
--- a/flatcamGUI/FlatCAMGUI.py
+++ b/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):
ALT+D |
%s |
+
+ ALT+E |
+ %s |
+
ALT+K |
%s |
@@ -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
diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py
index d0bfbbab..5508d4aa 100644
--- a/flatcamGUI/GUIElements.py
+++ b/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):
diff --git a/flatcamTools/ToolRulesCheck.py b/flatcamTools/ToolRulesCheck.py
index 1095e4db..f4158700 100644
--- a/flatcamTools/ToolRulesCheck.py
+++ b/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)
@@ -39,206 +39,308 @@ 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_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)
-
- self.object_label = QtWidgets.QLabel('%s:' % _("Object"))
- self.object_label.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)
- # Type of box Panel object
- self.reference_radio = RadioSet([{'label': _('Object'), 'value': 'object'},
- {'label': _('Bounding Box'), 'value': 'bbox'}])
- self.box_label = QtWidgets.QLabel("%s:" % _("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.gerber_title_lbl = QtWidgets.QLabel('%s:' % _("Gerber Files"))
+ self.gerber_title_lbl.setToolTip(
+ _("Gerber files for which to check rules.")
)
- 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")
+ # 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)
- # 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.")
+ 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.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)
+ # 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)
- 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.")
+ 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_combo_label, self.box_combo)
+
+ # 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.")
+ )
+
+ # 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.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("%s:" % _("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('%s:' % _("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.")
- )
- form_layout.addRow(self.spacing_columns_label, self.spacing_columns)
+ # 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)
- # 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.")
+ 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_rows_label, self.spacing_rows)
- # Columns
- self.columns = FCEntry()
- self.columns_label = QtWidgets.QLabel('%s:' % _("Columns"))
- self.columns_label.setToolTip(
- _("Number of columns of the desired panel")
- )
- form_layout.addRow(self.columns_label, self.columns)
+ # 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)
- # Rows
- self.rows = FCEntry()
- self.rows_label = QtWidgets.QLabel('%s:' % _("Rows"))
- self.rows_label.setToolTip(
- _("Number of rows of the desired panel")
+ 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.rows_label, self.rows)
+
+ 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(""))
- # Type of resulting Panel object
- self.panel_type_radio = RadioSet([{'label': _('Gerber'), 'value': 'gerber'},
- {'label': _('Geo'), 'value': 'geometry'}])
- self.panel_type_label = QtWidgets.QLabel("%s:" % _("Panel Type"))
- self.panel_type_label.setToolTip(
- _("Choose the type of object for the panel object:\n"
- "- Geometry\n"
- "- Gerber")
- )
- form_layout.addRow(self.panel_type_label)
- form_layout.addRow(self.panel_type_radio)
+ # Form Layout
+ form_layout_1 = QtWidgets.QFormLayout()
+ self.layout.addLayout(form_layout_1)
- # 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.")
+ # 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.constrain_cb)
+ form_layout_1.addRow(self.clearance_copper2copper_cb)
- 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.")
+ # 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.x_width_lbl, self.x_width_entry)
+ form_layout_1.addRow(self.clearance_copper2copper_lbl, self.clearance_copper2copper_entry)
- 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.")
+ 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.y_height_lbl, self.y_height_entry)
+ form_layout_1.addRow(self.clearance_copper2sm_cb)
- self.constrain_sel = OptionalInputSection(
- self.constrain_cb, [self.x_width_lbl, self.x_width_entry, self.y_height_lbl, self.y_height_entry])
+ # 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_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_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])
+
+ # 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_1.addRow(self.clearance_silk2silk_cb)
+
+ # 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_1.addRow(self.clearance_silk2silk_lbl, self.clearance_silk2silk_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
diff --git a/flatcamTools/ToolTransform.py b/flatcamTools/ToolTransform.py
index 04ee533c..dfb43f86 100644
--- a/flatcamTools/ToolTransform.py
+++ b/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
diff --git a/share/open_script32.png b/share/open_script32.png
new file mode 100644
index 00000000..e8b62c7e
Binary files /dev/null and b/share/open_script32.png differ
diff --git a/share/rules32.png b/share/rules32.png
new file mode 100644
index 00000000..ba558b24
Binary files /dev/null and b/share/rules32.png differ