Merged marius_stanciu/flatcam_beta/Beta into Beta
Beta 8.994 RELEASE
This commit is contained in:
commit
415716cffb
16
CHANGELOG.md
16
CHANGELOG.md
|
@ -7,6 +7,20 @@ CHANGELOG for FlatCAM beta
|
|||
|
||||
=================================================
|
||||
|
||||
7.11.2020
|
||||
|
||||
- fixed a small issue in Excellon Editor that reset the delta coordinates on right mouse button click too, which was incorrect. Only left mouse button click should reset the delta coordinates.
|
||||
- In Gerber Editor upgraded the UI
|
||||
- in Gerber Editor made sure that trying to add a Circular Pad array with null radius will fail
|
||||
- in Gerber Editor when the radius is zero the utility geometry is deleted
|
||||
- in Excellon Editor made sure that trying to add a Circular Drill/Slot array with null radius will fail
|
||||
- in Excellon Editor when the radius is zero the utility geometry is deleted
|
||||
- in Gerber Editor fixed an error in the Eraser tool trying to disconnect the Jump signal
|
||||
- small UI change in the Isolation Tool for the Reference Object selection
|
||||
- small UI changes in NCC Tool and in Paint Tool for the Reference Object selection
|
||||
- language strings recompiled to make sure that the .MO files are well optimized
|
||||
RELEASE 8.994
|
||||
|
||||
6.11.2020
|
||||
|
||||
- in Gerber Editor made the selection multithreaded in a bid to get more performance but until Shapely will start working on vectorized geometry this don't yield too much improvement
|
||||
|
@ -18,6 +32,8 @@ CHANGELOG for FlatCAM beta
|
|||
- in Excellon Editor remade the utility geometry generation for Circular Drill/Slot Array to show the array updated in real time and also fixed the adding of array in negative quadrants
|
||||
- Turkish language strings updated (by Mehmet Kaya)
|
||||
- both for Excellon and Gerber editor fixed the direction of slots/pads when adding a circular array
|
||||
- in Gerber editor added the G key shortcut to toggle the grid snapping
|
||||
- made some changes in the Region Tool from the Gerber Editor
|
||||
|
||||
5.11.2020
|
||||
|
||||
|
|
|
@ -330,7 +330,7 @@ class DrillArray(FCShapeTool):
|
|||
|
||||
self.selected_dia = None
|
||||
self.drill_axis = 'X'
|
||||
self.drill_array = 0 # 'linear'
|
||||
self.drill_array = 'linear' # 'linear'
|
||||
self.drill_array_size = None
|
||||
self.drill_pitch = None
|
||||
self.drill_linear_angle = None
|
||||
|
@ -382,7 +382,7 @@ class DrillArray(FCShapeTool):
|
|||
|
||||
def click(self, point):
|
||||
|
||||
if self.drill_array == 0: # 'Linear'
|
||||
if self.drill_array == 'linear': # 'Linear'
|
||||
self.make()
|
||||
return
|
||||
else:
|
||||
|
@ -405,7 +405,7 @@ class DrillArray(FCShapeTool):
|
|||
def utility_geometry(self, data=None, static=None):
|
||||
self.drill_axis = self.draw_app.ui.drill_axis_radio.get_value()
|
||||
self.drill_direction = self.draw_app.ui.drill_array_dir_radio.get_value()
|
||||
self.drill_array = self.draw_app.ui.array_type_combo.get_value()
|
||||
self.drill_array = self.draw_app.ui.array_type_radio.get_value()
|
||||
try:
|
||||
self.drill_array_size = int(self.draw_app.ui.drill_array_size_entry.get_value())
|
||||
try:
|
||||
|
@ -421,7 +421,7 @@ class DrillArray(FCShapeTool):
|
|||
(_("The value is mistyped. Check the value"), str(e)))
|
||||
return
|
||||
|
||||
if self.drill_array == 0: # 'Linear'
|
||||
if self.drill_array == 'linear': # 'Linear'
|
||||
if data[0] is None and data[1] is None:
|
||||
dx = self.draw_app.x
|
||||
dy = self.draw_app.y
|
||||
|
@ -454,7 +454,7 @@ class DrillArray(FCShapeTool):
|
|||
self.last_dx = dx
|
||||
self.last_dy = dy
|
||||
return DrawToolUtilityShape(geo_list)
|
||||
elif self.drill_array == 1: # 'Circular'
|
||||
elif self.drill_array == 'circular': # 'Circular'
|
||||
if data[0] is None and data[1] is None:
|
||||
cdx = self.draw_app.x
|
||||
cdy = self.draw_app.y
|
||||
|
@ -469,6 +469,9 @@ class DrillArray(FCShapeTool):
|
|||
except Exception:
|
||||
radius = 0
|
||||
|
||||
if radius == 0:
|
||||
self.draw_app.delete_utility_geometry()
|
||||
|
||||
if len(self.pt) >= 1 and radius > 0:
|
||||
try:
|
||||
if cdx < self.origin[0]:
|
||||
|
@ -553,7 +556,7 @@ class DrillArray(FCShapeTool):
|
|||
|
||||
self.draw_app.current_storage = self.draw_app.storage_dict[self.selected_dia]
|
||||
|
||||
if self.drill_array == 0: # 'Linear'
|
||||
if self.drill_array == 'linear': # 'Linear'
|
||||
for item in range(self.drill_array_size):
|
||||
if self.drill_axis == 'X':
|
||||
geo = self.util_shape(((self.points[0] + (self.drill_pitch * item)), self.points[1]))
|
||||
|
@ -575,6 +578,12 @@ class DrillArray(FCShapeTool):
|
|||
return
|
||||
|
||||
radius = distance(self.destination, self.origin)
|
||||
if radius == 0:
|
||||
self.draw_app.app.inform.emit('[ERROR_NOTCL] %s' % _("Failed."))
|
||||
self.draw_app.delete_utility_geometry()
|
||||
self.draw_app.select_tool('drill_select')
|
||||
return
|
||||
|
||||
if self.destination[0] < self.origin[0]:
|
||||
radius = -radius
|
||||
initial_angle = math.asin((self.destination[1] - self.origin[1]) / radius)
|
||||
|
@ -879,7 +888,7 @@ class SlotArray(FCShapeTool):
|
|||
self.radius = float(self.selected_dia / 2.0)
|
||||
|
||||
self.slot_axis = 'X'
|
||||
self.slot_array = 0 # 'linear'
|
||||
self.slot_array = 'linear' # 'linear'
|
||||
self.slot_array_size = None
|
||||
self.slot_pitch = None
|
||||
self.slot_linear_angle = None
|
||||
|
@ -910,7 +919,7 @@ class SlotArray(FCShapeTool):
|
|||
|
||||
def click(self, point):
|
||||
|
||||
if self.slot_array == 0: # 'Linear'
|
||||
if self.slot_array == 'linear': # 'Linear'
|
||||
self.make()
|
||||
return
|
||||
else: # 'Circular'
|
||||
|
@ -933,7 +942,7 @@ class SlotArray(FCShapeTool):
|
|||
def utility_geometry(self, data=None, static=None):
|
||||
self.slot_axis = self.draw_app.ui.slot_array_axis_radio.get_value()
|
||||
self.slot_direction = self.draw_app.ui.slot_array_direction_radio.get_value()
|
||||
self.slot_array = self.draw_app.ui.slot_array_type_combo.get_value()
|
||||
self.slot_array = self.draw_app.ui.slot_array_type_radio.get_value()
|
||||
try:
|
||||
self.slot_array_size = int(self.draw_app.ui.slot_array_size_entry.get_value())
|
||||
try:
|
||||
|
@ -948,7 +957,7 @@ class SlotArray(FCShapeTool):
|
|||
self.draw_app.app.inform.emit('[ERROR_NOTCL] %s' % _("The value is mistyped. Check the value."))
|
||||
return
|
||||
|
||||
if self.slot_array == 0: # 'Linear'
|
||||
if self.slot_array == 'linear': # 'Linear'
|
||||
if data[0] is None and data[1] is None:
|
||||
dx = self.draw_app.x
|
||||
dy = self.draw_app.y
|
||||
|
@ -999,6 +1008,9 @@ class SlotArray(FCShapeTool):
|
|||
except Exception:
|
||||
radius = 0
|
||||
|
||||
if radius == 0:
|
||||
self.draw_app.delete_utility_geometry()
|
||||
|
||||
if len(self.pt) >= 1 and radius > 0:
|
||||
try:
|
||||
if cdx < self.origin[0]:
|
||||
|
@ -1166,7 +1178,7 @@ class SlotArray(FCShapeTool):
|
|||
|
||||
self.draw_app.current_storage = self.draw_app.storage_dict[self.selected_dia]
|
||||
|
||||
if self.slot_array == 0: # 'Linear'
|
||||
if self.slot_array == 'linear': # 'Linear'
|
||||
for item in range(self.slot_array_size):
|
||||
if self.slot_axis == 'X':
|
||||
geo = self.util_shape(((self.points[0] + (self.slot_pitch * item)), self.points[1]))
|
||||
|
@ -1207,6 +1219,12 @@ class SlotArray(FCShapeTool):
|
|||
# self.geometry.append(DrawToolShape(geo))
|
||||
|
||||
radius = distance(self.destination, self.origin)
|
||||
if radius == 0:
|
||||
self.draw_app.app.inform.emit('[ERROR_NOTCL] %s' % _("Failed."))
|
||||
self.draw_app.delete_utility_geometry()
|
||||
self.draw_app.select_tool('drill_select')
|
||||
return
|
||||
|
||||
if self.destination[0] < self.origin[0]:
|
||||
radius = -radius
|
||||
initial_angle = math.asin((self.destination[1] - self.origin[1]) / radius)
|
||||
|
@ -1862,8 +1880,8 @@ class AppExcEditor(QtCore.QObject):
|
|||
# self.ui.tools_table_exc.selectionModel().currentChanged.connect(self.on_row_selected)
|
||||
self.ui.tools_table_exc.cellPressed.connect(self.on_row_selected)
|
||||
|
||||
self.ui.array_type_combo.currentIndexChanged.connect(self.on_array_type_combo)
|
||||
self.ui.slot_array_type_combo.currentIndexChanged.connect(self.on_slot_array_type_combo)
|
||||
self.ui.array_type_radio.activated_custom.connect(self.on_array_type_radio)
|
||||
self.ui.slot_array_type_radio.activated_custom.connect(self.on_slot_array_type_radio)
|
||||
|
||||
self.ui.drill_axis_radio.activated_custom.connect(self.on_linear_angle_radio)
|
||||
self.ui.slot_axis_radio.activated_custom.connect(self.on_slot_angle_radio)
|
||||
|
@ -1976,8 +1994,10 @@ class AppExcEditor(QtCore.QObject):
|
|||
# according to the set Preferences already loaded
|
||||
self.on_slot_angle_radio()
|
||||
|
||||
self.on_array_type_combo()
|
||||
self.on_slot_array_type_combo()
|
||||
self.ui.array_type_radio.set_value('linear')
|
||||
self.on_array_type_radio(val=self.ui.array_type_radio.get_value())
|
||||
self.ui.slot_array_type_radio.set_value('linear')
|
||||
self.on_slot_array_type_radio(val=self.ui.slot_array_type_radio.get_value())
|
||||
self.on_linear_angle_radio()
|
||||
self.on_slot_array_linear_angle_radio()
|
||||
|
||||
|
@ -3153,14 +3173,14 @@ class AppExcEditor(QtCore.QObject):
|
|||
# event_is_dragging = self.app.plotcanvas.is_dragging
|
||||
# right_button = 3
|
||||
|
||||
self.pos = self.canvas.translate_coords(event_pos)
|
||||
|
||||
if self.app.grid_status():
|
||||
self.pos = self.app.geo_editor.snap(self.pos[0], self.pos[1])
|
||||
else:
|
||||
self.pos = (self.pos[0], self.pos[1])
|
||||
|
||||
if event.button == 1:
|
||||
self.pos = self.canvas.translate_coords(event_pos)
|
||||
|
||||
if self.app.grid_status():
|
||||
self.pos = self.app.geo_editor.snap(self.pos[0], self.pos[1])
|
||||
else:
|
||||
self.pos = (self.pos[0], self.pos[1])
|
||||
|
||||
self.app.ui.rel_position_label.setText("<b>Dx</b>: %.4f <b>Dy</b>: "
|
||||
"%.4f " % (0, 0))
|
||||
|
||||
|
@ -3202,82 +3222,6 @@ class AppExcEditor(QtCore.QObject):
|
|||
else:
|
||||
self.app.log.debug("No active tool to respond to click!")
|
||||
|
||||
def on_exc_shape_complete(self, storage):
|
||||
self.app.log.debug("on_shape_complete()")
|
||||
|
||||
# Add shape
|
||||
if type(storage) is list:
|
||||
for item_storage in storage:
|
||||
self.add_exc_shape(self.active_tool.geometry, item_storage)
|
||||
else:
|
||||
self.add_exc_shape(self.active_tool.geometry, storage)
|
||||
|
||||
# Remove any utility shapes
|
||||
self.delete_utility_geometry()
|
||||
self.tool_shape.clear(update=True)
|
||||
|
||||
# Replot and reset tool.
|
||||
self.replot()
|
||||
# self.active_tool = type(self.active_tool)(self)
|
||||
|
||||
def add_exc_shape(self, shape, storage):
|
||||
"""
|
||||
Adds a shape to a specified shape storage.
|
||||
|
||||
:param shape: Shape to be added.
|
||||
:type shape: DrawToolShape
|
||||
:param storage: object where to store the shapes
|
||||
:return: None
|
||||
"""
|
||||
# List of DrawToolShape?
|
||||
if isinstance(shape, list):
|
||||
for subshape in shape:
|
||||
self.add_exc_shape(subshape, storage)
|
||||
return
|
||||
|
||||
assert isinstance(shape, DrawToolShape), \
|
||||
"Expected a DrawToolShape, got %s" % str(type(shape))
|
||||
|
||||
assert shape.geo is not None, \
|
||||
"Shape object has empty geometry (None)"
|
||||
|
||||
assert (isinstance(shape.geo, list) and len(shape.geo) > 0) or not isinstance(shape.geo, list), \
|
||||
"Shape objects has empty geometry ([])"
|
||||
|
||||
if isinstance(shape, DrawToolUtilityShape):
|
||||
self.utility.append(shape)
|
||||
else:
|
||||
storage.insert(shape) # TODO: Check performance
|
||||
|
||||
def add_shape(self, shape):
|
||||
"""
|
||||
Adds a shape to the shape storage.
|
||||
|
||||
:param shape: Shape to be added.
|
||||
:type shape: DrawToolShape
|
||||
:return: None
|
||||
"""
|
||||
|
||||
# List of DrawToolShape?
|
||||
if isinstance(shape, list):
|
||||
for subshape in shape:
|
||||
self.add_shape(subshape)
|
||||
return
|
||||
|
||||
assert isinstance(shape, DrawToolShape), \
|
||||
"Expected a DrawToolShape, got %s" % type(shape)
|
||||
|
||||
assert shape.geo is not None, \
|
||||
"Shape object has empty geometry (None)"
|
||||
|
||||
assert (isinstance(shape.geo, list) and len(shape.geo) > 0) or not isinstance(shape.geo, list), \
|
||||
"Shape objects has empty geometry ([])"
|
||||
|
||||
if isinstance(shape, DrawToolUtilityShape):
|
||||
self.utility.append(shape)
|
||||
# else:
|
||||
# self.storage.insert(shape)
|
||||
|
||||
def on_exc_click_release(self, event):
|
||||
"""
|
||||
Handler of the "mouse_release" event.
|
||||
|
@ -3354,90 +3298,6 @@ class AppExcEditor(QtCore.QObject):
|
|||
log.warning("AppExcEditor.on_exc_click_release() LMB click --> Error: %s" % str(e))
|
||||
raise
|
||||
|
||||
def draw_selection_area_handler(self, start, end, sel_type):
|
||||
"""
|
||||
This function is called whenever we have a left mouse click release and only we have a left mouse click drag,
|
||||
be it from left to right or from right to left. The direction of the drag is decided in the "mouse_move"
|
||||
event handler.
|
||||
Pressing a modifier key (eg. Ctrl, Shift or Alt) will change the behavior of the selection.
|
||||
|
||||
Depending on which tool belongs the selected shapes, the corresponding rows in the Tools Table are selected or
|
||||
deselected.
|
||||
|
||||
:param start: mouse position when the selection LMB click was done
|
||||
:param end: mouse position when the left mouse button is released
|
||||
:param sel_type: if True it's a left to right selection (enclosure), if False it's a 'touch' selection
|
||||
:return:
|
||||
"""
|
||||
|
||||
start_pos = (start[0], start[1])
|
||||
end_pos = (end[0], end[1])
|
||||
poly_selection = Polygon([start_pos, (end_pos[0], start_pos[1]), end_pos, (start_pos[0], end_pos[1])])
|
||||
modifiers = None
|
||||
|
||||
# delete the selection shape that was just drawn, we no longer need it
|
||||
self.app.delete_selection_shape()
|
||||
|
||||
# detect if a modifier key was pressed while the left mouse button was released
|
||||
self.modifiers = QtWidgets.QApplication.keyboardModifiers()
|
||||
if self.modifiers == QtCore.Qt.ShiftModifier:
|
||||
modifiers = 'Shift'
|
||||
elif self.modifiers == QtCore.Qt.ControlModifier:
|
||||
modifiers = 'Control'
|
||||
|
||||
if modifiers == self.app.defaults["global_mselect_key"]:
|
||||
for storage in self.storage_dict:
|
||||
for obj in self.storage_dict[storage].get_objects():
|
||||
if (sel_type is True and poly_selection.contains(obj.geo)) or \
|
||||
(sel_type is False and poly_selection.intersects(obj.geo)):
|
||||
|
||||
if obj in self.selected:
|
||||
# remove the shape object from the selected shapes storage
|
||||
self.selected.remove(obj)
|
||||
else:
|
||||
# add the shape object to the selected shapes storage
|
||||
self.selected.append(obj)
|
||||
else:
|
||||
# clear the selection shapes storage
|
||||
self.selected = []
|
||||
# then add to the selection shapes storage the shapes that are included (touched) by the selection rectangle
|
||||
for storage in self.storage_dict:
|
||||
for obj in self.storage_dict[storage].get_objects():
|
||||
if (sel_type is True and poly_selection.contains(obj.geo)) or \
|
||||
(sel_type is False and poly_selection.intersects(obj.geo)):
|
||||
self.selected.append(obj)
|
||||
|
||||
try:
|
||||
self.ui.tools_table_exc.cellPressed.disconnect()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# first deselect all rows (tools) in the Tools Table
|
||||
self.ui.tools_table_exc.clearSelection()
|
||||
# and select the rows (tools) in the tool table according to the diameter(s) of the selected shape(s)
|
||||
self.ui.tools_table_exc.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection)
|
||||
for storage in self.storage_dict:
|
||||
for shape_s in self.selected:
|
||||
if shape_s in self.storage_dict[storage].get_objects():
|
||||
for key_tool_nr in self.tool2tooldia:
|
||||
if self.tool2tooldia[key_tool_nr] == storage:
|
||||
row_to_sel = key_tool_nr - 1
|
||||
# item = self.ui.tools_table_exc.item(row_to_sel, 1)
|
||||
# self.ui.tools_table_exc.setCurrentItem(item)
|
||||
# item.setSelected(True)
|
||||
|
||||
# if the row to be selected is not already in the selected rows then select it
|
||||
# otherwise don't do it as it seems that we have a toggle effect
|
||||
if row_to_sel not in set(
|
||||
index.row() for index in self.ui.tools_table_exc.selectedIndexes()):
|
||||
self.ui.tools_table_exc.selectRow(row_to_sel)
|
||||
self.last_tool_selected = int(key_tool_nr)
|
||||
|
||||
self.ui.tools_table_exc.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
|
||||
|
||||
self.ui.tools_table_exc.cellPressed.connect(self.on_row_selected)
|
||||
self.replot()
|
||||
|
||||
def on_canvas_move(self, event):
|
||||
"""
|
||||
Called on 'mouse_move' event.
|
||||
|
@ -3547,6 +3407,166 @@ class AppExcEditor(QtCore.QObject):
|
|||
edge_width=self.app.defaults["global_cursor_width"],
|
||||
size=self.app.defaults["global_cursor_size"])
|
||||
|
||||
def add_exc_shape(self, shape, storage):
|
||||
"""
|
||||
Adds a shape to a specified shape storage.
|
||||
|
||||
:param shape: Shape to be added.
|
||||
:type shape: DrawToolShape
|
||||
:param storage: object where to store the shapes
|
||||
:return: None
|
||||
"""
|
||||
# List of DrawToolShape?
|
||||
if isinstance(shape, list):
|
||||
for subshape in shape:
|
||||
self.add_exc_shape(subshape, storage)
|
||||
return
|
||||
|
||||
assert isinstance(shape, DrawToolShape), \
|
||||
"Expected a DrawToolShape, got %s" % str(type(shape))
|
||||
|
||||
assert shape.geo is not None, \
|
||||
"Shape object has empty geometry (None)"
|
||||
|
||||
assert (isinstance(shape.geo, list) and len(shape.geo) > 0) or not isinstance(shape.geo, list), \
|
||||
"Shape objects has empty geometry ([])"
|
||||
|
||||
if isinstance(shape, DrawToolUtilityShape):
|
||||
self.utility.append(shape)
|
||||
else:
|
||||
storage.insert(shape) # TODO: Check performance
|
||||
|
||||
def add_shape(self, shape):
|
||||
"""
|
||||
Adds a shape to the shape storage.
|
||||
|
||||
:param shape: Shape to be added.
|
||||
:type shape: DrawToolShape
|
||||
:return: None
|
||||
"""
|
||||
|
||||
# List of DrawToolShape?
|
||||
if isinstance(shape, list):
|
||||
for subshape in shape:
|
||||
self.add_shape(subshape)
|
||||
return
|
||||
|
||||
assert isinstance(shape, DrawToolShape), \
|
||||
"Expected a DrawToolShape, got %s" % type(shape)
|
||||
|
||||
assert shape.geo is not None, \
|
||||
"Shape object has empty geometry (None)"
|
||||
|
||||
assert (isinstance(shape.geo, list) and len(shape.geo) > 0) or not isinstance(shape.geo, list), \
|
||||
"Shape objects has empty geometry ([])"
|
||||
|
||||
if isinstance(shape, DrawToolUtilityShape):
|
||||
self.utility.append(shape)
|
||||
# else:
|
||||
# self.storage.insert(shape)
|
||||
|
||||
def on_exc_shape_complete(self, storage):
|
||||
self.app.log.debug("on_shape_complete()")
|
||||
|
||||
# Add shape
|
||||
if type(storage) is list:
|
||||
for item_storage in storage:
|
||||
self.add_exc_shape(self.active_tool.geometry, item_storage)
|
||||
else:
|
||||
self.add_exc_shape(self.active_tool.geometry, storage)
|
||||
|
||||
# Remove any utility shapes
|
||||
self.delete_utility_geometry()
|
||||
self.tool_shape.clear(update=True)
|
||||
|
||||
# Replot and reset tool.
|
||||
self.replot()
|
||||
# self.active_tool = type(self.active_tool)(self)
|
||||
|
||||
def draw_selection_area_handler(self, start, end, sel_type):
|
||||
"""
|
||||
This function is called whenever we have a left mouse click release and only we have a left mouse click drag,
|
||||
be it from left to right or from right to left. The direction of the drag is decided in the "mouse_move"
|
||||
event handler.
|
||||
Pressing a modifier key (eg. Ctrl, Shift or Alt) will change the behavior of the selection.
|
||||
|
||||
Depending on which tool belongs the selected shapes, the corresponding rows in the Tools Table are selected or
|
||||
deselected.
|
||||
|
||||
:param start: mouse position when the selection LMB click was done
|
||||
:param end: mouse position when the left mouse button is released
|
||||
:param sel_type: if True it's a left to right selection (enclosure), if False it's a 'touch' selection
|
||||
:return:
|
||||
"""
|
||||
|
||||
start_pos = (start[0], start[1])
|
||||
end_pos = (end[0], end[1])
|
||||
poly_selection = Polygon([start_pos, (end_pos[0], start_pos[1]), end_pos, (start_pos[0], end_pos[1])])
|
||||
modifiers = None
|
||||
|
||||
# delete the selection shape that was just drawn, we no longer need it
|
||||
self.app.delete_selection_shape()
|
||||
|
||||
# detect if a modifier key was pressed while the left mouse button was released
|
||||
self.modifiers = QtWidgets.QApplication.keyboardModifiers()
|
||||
if self.modifiers == QtCore.Qt.ShiftModifier:
|
||||
modifiers = 'Shift'
|
||||
elif self.modifiers == QtCore.Qt.ControlModifier:
|
||||
modifiers = 'Control'
|
||||
|
||||
if modifiers == self.app.defaults["global_mselect_key"]:
|
||||
for storage in self.storage_dict:
|
||||
for obj in self.storage_dict[storage].get_objects():
|
||||
if (sel_type is True and poly_selection.contains(obj.geo)) or \
|
||||
(sel_type is False and poly_selection.intersects(obj.geo)):
|
||||
|
||||
if obj in self.selected:
|
||||
# remove the shape object from the selected shapes storage
|
||||
self.selected.remove(obj)
|
||||
else:
|
||||
# add the shape object to the selected shapes storage
|
||||
self.selected.append(obj)
|
||||
else:
|
||||
# clear the selection shapes storage
|
||||
self.selected = []
|
||||
# then add to the selection shapes storage the shapes that are included (touched) by the selection rectangle
|
||||
for storage in self.storage_dict:
|
||||
for obj in self.storage_dict[storage].get_objects():
|
||||
if (sel_type is True and poly_selection.contains(obj.geo)) or \
|
||||
(sel_type is False and poly_selection.intersects(obj.geo)):
|
||||
self.selected.append(obj)
|
||||
|
||||
try:
|
||||
self.ui.tools_table_exc.cellPressed.disconnect()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# first deselect all rows (tools) in the Tools Table
|
||||
self.ui.tools_table_exc.clearSelection()
|
||||
# and select the rows (tools) in the tool table according to the diameter(s) of the selected shape(s)
|
||||
self.ui.tools_table_exc.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection)
|
||||
for storage in self.storage_dict:
|
||||
for shape_s in self.selected:
|
||||
if shape_s in self.storage_dict[storage].get_objects():
|
||||
for key_tool_nr in self.tool2tooldia:
|
||||
if self.tool2tooldia[key_tool_nr] == storage:
|
||||
row_to_sel = key_tool_nr - 1
|
||||
# item = self.ui.tools_table_exc.item(row_to_sel, 1)
|
||||
# self.ui.tools_table_exc.setCurrentItem(item)
|
||||
# item.setSelected(True)
|
||||
|
||||
# if the row to be selected is not already in the selected rows then select it
|
||||
# otherwise don't do it as it seems that we have a toggle effect
|
||||
if row_to_sel not in set(
|
||||
index.row() for index in self.ui.tools_table_exc.selectedIndexes()):
|
||||
self.ui.tools_table_exc.selectRow(row_to_sel)
|
||||
self.last_tool_selected = int(key_tool_nr)
|
||||
|
||||
self.ui.tools_table_exc.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
|
||||
|
||||
self.ui.tools_table_exc.cellPressed.connect(self.on_row_selected)
|
||||
self.replot()
|
||||
|
||||
def update_utility_geometry(self, data):
|
||||
# ### Utility geometry (animated) ###
|
||||
geo = self.active_tool.utility_geometry(data=data)
|
||||
|
@ -3755,8 +3775,8 @@ class AppExcEditor(QtCore.QObject):
|
|||
if unsel_shape in self.selected:
|
||||
self.selected.remove(unsel_shape)
|
||||
|
||||
def on_array_type_combo(self):
|
||||
if self.ui.array_type_combo.currentIndex() == 0:
|
||||
def on_array_type_radio(self, val):
|
||||
if val == 'linear':
|
||||
self.ui.array_circular_frame.hide()
|
||||
self.ui.array_linear_frame.show()
|
||||
else:
|
||||
|
@ -3765,8 +3785,8 @@ class AppExcEditor(QtCore.QObject):
|
|||
self.ui.array_linear_frame.hide()
|
||||
self.app.inform.emit(_("Click on the circular array Center position"))
|
||||
|
||||
def on_slot_array_type_combo(self):
|
||||
if self.ui.slot_array_type_combo.currentIndex() == 0:
|
||||
def on_slot_array_type_radio(self, val):
|
||||
if val == 'linear':
|
||||
self.ui.slot_array_circular_frame.hide()
|
||||
self.ui.slot_array_linear_frame.show()
|
||||
else:
|
||||
|
@ -3897,11 +3917,11 @@ class AppExcEditorUI:
|
|||
self.ui_vertical_lay.setContentsMargins(0, 0, 0, 0)
|
||||
self.drills_frame.setLayout(self.ui_vertical_lay)
|
||||
|
||||
# ## Page Title box (spacing between children)
|
||||
# Page Title box (spacing between children)
|
||||
self.title_box = QtWidgets.QHBoxLayout()
|
||||
self.ui_vertical_lay.addLayout(self.title_box)
|
||||
|
||||
# ## Page Title
|
||||
# Page Title
|
||||
pixmap = QtGui.QPixmap(self.app.resource_location + '/flatcam_icon32.png')
|
||||
self.icon = FCLabel()
|
||||
self.icon.setPixmap(pixmap)
|
||||
|
@ -3912,17 +3932,18 @@ class AppExcEditorUI:
|
|||
self.title_box.addWidget(self.icon, stretch=0)
|
||||
self.title_box.addWidget(self.title_label, stretch=1)
|
||||
|
||||
# ## Object name
|
||||
# Object name box
|
||||
self.name_box = QtWidgets.QHBoxLayout()
|
||||
self.ui_vertical_lay.addLayout(self.name_box)
|
||||
|
||||
# Object Name
|
||||
name_label = FCLabel(_("Name:"))
|
||||
self.name_entry = FCEntry()
|
||||
|
||||
self.name_box.addWidget(name_label)
|
||||
self.name_box.addWidget(self.name_entry)
|
||||
|
||||
# ### Tools Drills ## ##
|
||||
# Tools Drills Table Title
|
||||
self.tools_table_label = FCLabel("<b>%s</b>" % _('Tools Table'))
|
||||
self.tools_table_label.setToolTip(
|
||||
_("Tools in this Excellon object\n"
|
||||
|
@ -3930,7 +3951,9 @@ class AppExcEditorUI:
|
|||
)
|
||||
self.ui_vertical_lay.addWidget(self.tools_table_label)
|
||||
|
||||
# Drills TABLE
|
||||
# #############################################################################################################
|
||||
# ########################################## Drills TABLE #####################################################
|
||||
# #############################################################################################################
|
||||
self.tools_table_exc = FCTable()
|
||||
self.tools_table_exc.setColumnCount(4)
|
||||
self.tools_table_exc.setHorizontalHeaderLabels(['#', _('Diameter'), 'D', 'S'])
|
||||
|
@ -3957,7 +3980,7 @@ class AppExcEditorUI:
|
|||
separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
|
||||
self.ui_vertical_lay.addWidget(separator_line)
|
||||
|
||||
# ### Add a new Tool ## ##
|
||||
# Add a new Tool
|
||||
self.addtool_label = FCLabel('<b>%s</b>' % _('Add/Delete Tool'))
|
||||
self.addtool_label.setToolTip(
|
||||
_("Add/Delete a tool to the tool list\n"
|
||||
|
@ -4089,16 +4112,20 @@ class AppExcEditorUI:
|
|||
_("Add an array of drills (linear or circular array)")
|
||||
)
|
||||
|
||||
# Special Combo - it works by indexes as opposed to the items Text
|
||||
self.array_type_combo = FCComboBox2()
|
||||
self.array_type_combo.setToolTip(
|
||||
self.array_grid.addWidget(self.drill_array_label, 0, 0, 1, 2)
|
||||
|
||||
# Array Type
|
||||
array_type_lbl = FCLabel('%s:' % _("Type"))
|
||||
array_type_lbl.setToolTip(
|
||||
_("Select the type of drills array to create.\n"
|
||||
"It can be Linear X(Y) or Circular")
|
||||
)
|
||||
self.array_type_combo.addItems([_("Linear"), _("Circular")])
|
||||
|
||||
self.array_grid.addWidget(self.drill_array_label, 0, 0, 1, 2)
|
||||
self.array_grid.addWidget(self.array_type_combo, 2, 0, 1, 2)
|
||||
self.array_type_radio = RadioSet([{'label': _('Linear'), 'value': 'linear'},
|
||||
{'label': _('Circular'), 'value': 'circular'}])
|
||||
|
||||
self.array_grid.addWidget(array_type_lbl, 2, 0)
|
||||
self.array_grid.addWidget(self.array_type_radio, 2, 1)
|
||||
|
||||
# Set the number of drill holes in the drill array
|
||||
self.drill_array_size_label = FCLabel('%s:' % _('Number'))
|
||||
|
@ -4289,9 +4316,6 @@ class AppExcEditorUI:
|
|||
# #############################################################################################################
|
||||
# ##################################### ADDING SLOT ARRAY ####################################################
|
||||
# #############################################################################################################
|
||||
# add a frame and inside add a vertical box layout. Inside this vbox layout I add
|
||||
# all the add slot widgets
|
||||
# this way I can hide/show the frame
|
||||
self.slot_array_frame = QtWidgets.QFrame()
|
||||
self.slot_array_frame.setContentsMargins(0, 0, 0, 0)
|
||||
self.ui_vertical_lay.addWidget(self.slot_array_frame)
|
||||
|
@ -4310,15 +4334,18 @@ class AppExcEditorUI:
|
|||
|
||||
self.slot_array_grid.addWidget(self.slot_array_label, 0, 0, 1, 2)
|
||||
|
||||
# Special type of Combobox that get_value() by indexes and not by items text
|
||||
self.slot_array_type_combo = FCComboBox2()
|
||||
self.slot_array_type_combo.setToolTip(
|
||||
# Array Type
|
||||
array_type_lbl = FCLabel('%s:' % _("Type"))
|
||||
array_type_lbl.setToolTip(
|
||||
_("Select the type of slot array to create.\n"
|
||||
"It can be Linear X(Y) or Circular")
|
||||
)
|
||||
self.slot_array_type_combo.addItems([_("Linear"), _("Circular")])
|
||||
|
||||
self.slot_array_grid.addWidget(self.slot_array_type_combo, 2, 0, 1, 2)
|
||||
self.slot_array_type_radio = RadioSet([{'label': _('Linear'), 'value': 'linear'},
|
||||
{'label': _('Circular'), 'value': 'circular'}])
|
||||
|
||||
self.slot_array_grid.addWidget(array_type_lbl, 2, 0)
|
||||
self.slot_array_grid.addWidget(self.slot_array_type_radio, 2, 1)
|
||||
|
||||
# Set the number of slot holes in the slot array
|
||||
self.slot_array_size_label = FCLabel('%s:' % _('Number'))
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -821,7 +821,6 @@ class ToolIsolation(AppTool, Gerber):
|
|||
|
||||
if val == 0: # ALl
|
||||
self.ui.reference_combo.hide()
|
||||
self.ui.reference_combo_label.hide()
|
||||
self.ui.reference_combo_type.hide()
|
||||
self.ui.reference_combo_type_label.hide()
|
||||
self.ui.area_shape_label.hide()
|
||||
|
@ -832,7 +831,6 @@ class ToolIsolation(AppTool, Gerber):
|
|||
self.ui.rest_cb.setDisabled(False)
|
||||
elif val == 1: # Area Selection
|
||||
self.ui.reference_combo.hide()
|
||||
self.ui.reference_combo_label.hide()
|
||||
self.ui.reference_combo_type.hide()
|
||||
self.ui.reference_combo_type_label.hide()
|
||||
self.ui.area_shape_label.show()
|
||||
|
@ -844,7 +842,6 @@ class ToolIsolation(AppTool, Gerber):
|
|||
self.ui.rest_cb.setDisabled(True)
|
||||
elif val == 2: # Polygon Selection
|
||||
self.ui.reference_combo.hide()
|
||||
self.ui.reference_combo_label.hide()
|
||||
self.ui.reference_combo_type.hide()
|
||||
self.ui.reference_combo_type_label.hide()
|
||||
self.ui.area_shape_label.hide()
|
||||
|
@ -852,7 +849,6 @@ class ToolIsolation(AppTool, Gerber):
|
|||
self.ui.poly_int_cb.show()
|
||||
else: # Reference Object
|
||||
self.ui.reference_combo.show()
|
||||
self.ui.reference_combo_label.show()
|
||||
self.ui.reference_combo_type.show()
|
||||
self.ui.reference_combo_type_label.show()
|
||||
self.ui.area_shape_label.hide()
|
||||
|
@ -3487,31 +3483,23 @@ class IsoUI:
|
|||
self.grid3.addWidget(self.select_label, 34, 0)
|
||||
self.grid3.addWidget(self.select_combo, 34, 1)
|
||||
|
||||
self.reference_combo_type_label = FCLabel('%s:' % _("Ref. Type"))
|
||||
self.reference_combo_type_label.setToolTip(
|
||||
_("The type of FlatCAM object to be used as non copper clearing reference.\n"
|
||||
"It can be Gerber, Excellon or Geometry.")
|
||||
)
|
||||
# Reference Type
|
||||
self.reference_combo_type_label = FCLabel('%s:' % _("Type"))
|
||||
|
||||
self.reference_combo_type = FCComboBox2()
|
||||
self.reference_combo_type.addItems([_("Gerber"), _("Excellon"), _("Geometry")])
|
||||
|
||||
self.grid3.addWidget(self.reference_combo_type_label, 36, 0)
|
||||
self.grid3.addWidget(self.reference_combo_type, 36, 1)
|
||||
|
||||
self.reference_combo_label = FCLabel('%s:' % _("Ref. Object"))
|
||||
self.reference_combo_label.setToolTip(
|
||||
_("The FlatCAM object to be used as non copper clearing reference.")
|
||||
)
|
||||
self.reference_combo = FCComboBox()
|
||||
self.reference_combo.setModel(self.app.collection)
|
||||
self.reference_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
|
||||
self.reference_combo.is_last = True
|
||||
|
||||
self.grid3.addWidget(self.reference_combo_label, 38, 0)
|
||||
self.grid3.addWidget(self.reference_combo, 38, 1)
|
||||
self.grid3.addWidget(self.reference_combo, 38, 0, 1, 2)
|
||||
|
||||
self.reference_combo.hide()
|
||||
self.reference_combo_label.hide()
|
||||
self.reference_combo_type.hide()
|
||||
self.reference_combo_type_label.hide()
|
||||
|
||||
|
|
|
@ -4417,10 +4417,7 @@ class NccUI:
|
|||
self.grid3.addWidget(self.select_label, 29, 0, )
|
||||
self.grid3.addWidget(self.select_combo, 29, 1)
|
||||
|
||||
form1 = QtWidgets.QFormLayout()
|
||||
self.grid3.addLayout(form1, 30, 0, 1, 2)
|
||||
|
||||
self.reference_combo_type_label = FCLabel('%s:' % _("Ref. Type"))
|
||||
self.reference_combo_type_label = FCLabel('%s:' % _("Type"))
|
||||
self.reference_combo_type_label.setToolTip(
|
||||
_("The type of FlatCAM object to be used as non copper clearing reference.\n"
|
||||
"It can be Gerber, Excellon or Geometry.")
|
||||
|
@ -4428,20 +4425,17 @@ class NccUI:
|
|||
self.reference_combo_type = FCComboBox2()
|
||||
self.reference_combo_type.addItems([_("Gerber"), _("Excellon"), _("Geometry")])
|
||||
|
||||
form1.addRow(self.reference_combo_type_label, self.reference_combo_type)
|
||||
self.grid3.addWidget(self.reference_combo_type_label, 31, 0, )
|
||||
self.grid3.addWidget(self.reference_combo_type, 31, 1)
|
||||
|
||||
self.reference_combo_label = FCLabel('%s:' % _("Ref. Object"))
|
||||
self.reference_combo_label.setToolTip(
|
||||
_("The FlatCAM object to be used as non copper clearing reference.")
|
||||
)
|
||||
self.reference_combo = FCComboBox()
|
||||
self.reference_combo.setModel(self.app.collection)
|
||||
self.reference_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
|
||||
self.reference_combo.is_last = True
|
||||
form1.addRow(self.reference_combo_label, self.reference_combo)
|
||||
|
||||
self.grid3.addWidget(self.reference_combo, 33, 0, 1, 2)
|
||||
|
||||
self.reference_combo.hide()
|
||||
self.reference_combo_label.hide()
|
||||
self.reference_combo_type.hide()
|
||||
self.reference_combo_type_label.hide()
|
||||
|
||||
|
@ -4454,8 +4448,8 @@ class NccUI:
|
|||
self.area_shape_radio = RadioSet([{'label': _("Square"), 'value': 'square'},
|
||||
{'label': _("Polygon"), 'value': 'polygon'}])
|
||||
|
||||
self.grid3.addWidget(self.area_shape_label, 31, 0)
|
||||
self.grid3.addWidget(self.area_shape_radio, 31, 1)
|
||||
self.grid3.addWidget(self.area_shape_label, 35, 0)
|
||||
self.grid3.addWidget(self.area_shape_radio, 35, 1)
|
||||
|
||||
self.area_shape_label.hide()
|
||||
self.area_shape_radio.hide()
|
||||
|
@ -4468,12 +4462,12 @@ class NccUI:
|
|||
)
|
||||
self.valid_cb.setObjectName("n_check")
|
||||
|
||||
self.grid3.addWidget(self.valid_cb, 33, 0, 1, 2)
|
||||
self.grid3.addWidget(self.valid_cb, 37, 0, 1, 2)
|
||||
|
||||
separator_line = QtWidgets.QFrame()
|
||||
separator_line.setFrameShape(QtWidgets.QFrame.HLine)
|
||||
separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
|
||||
self.grid3.addWidget(separator_line, 35, 0, 1, 2)
|
||||
self.grid3.addWidget(separator_line, 39, 0, 1, 2)
|
||||
|
||||
self.generate_ncc_button = FCButton(_('Generate Geometry'))
|
||||
self.generate_ncc_button.setIcon(QtGui.QIcon(self.app.resource_location + '/geometry32.png'))
|
||||
|
@ -4541,7 +4535,6 @@ class NccUI:
|
|||
|
||||
if sel_combo == 0: # itself
|
||||
self.reference_combo.hide()
|
||||
self.reference_combo_label.hide()
|
||||
self.reference_combo_type.hide()
|
||||
self.reference_combo_type_label.hide()
|
||||
self.area_shape_label.hide()
|
||||
|
@ -4551,7 +4544,6 @@ class NccUI:
|
|||
self.ncc_rest_cb.setDisabled(False)
|
||||
elif sel_combo == 1: # area selection
|
||||
self.reference_combo.hide()
|
||||
self.reference_combo_label.hide()
|
||||
self.reference_combo_type.hide()
|
||||
self.reference_combo_type_label.hide()
|
||||
self.area_shape_label.show()
|
||||
|
@ -4562,7 +4554,6 @@ class NccUI:
|
|||
# self.ncc_rest_cb.setDisabled(True)
|
||||
else:
|
||||
self.reference_combo.show()
|
||||
self.reference_combo_label.show()
|
||||
self.reference_combo_type.show()
|
||||
self.reference_combo_type_label.show()
|
||||
self.area_shape_label.hide()
|
||||
|
|
|
@ -3120,10 +3120,8 @@ class PaintUI:
|
|||
grid4.addWidget(selectlabel, 18, 0)
|
||||
grid4.addWidget(self.selectmethod_combo, 18, 1)
|
||||
|
||||
form1 = QtWidgets.QFormLayout()
|
||||
grid4.addLayout(form1, 20, 0, 1, 2)
|
||||
|
||||
self.reference_type_label = FCLabel('%s:' % _("Ref. Type"))
|
||||
# Type of Reference Object
|
||||
self.reference_type_label = FCLabel('%s:' % _("Type"))
|
||||
self.reference_type_label.setToolTip(
|
||||
_("The type of FlatCAM object to be used as paint reference.\n"
|
||||
"It can be Gerber, Excellon or Geometry.")
|
||||
|
@ -3131,20 +3129,18 @@ class PaintUI:
|
|||
self.reference_type_combo = FCComboBox2()
|
||||
self.reference_type_combo.addItems([_("Gerber"), _("Excellon"), _("Geometry")])
|
||||
|
||||
form1.addRow(self.reference_type_label, self.reference_type_combo)
|
||||
grid4.addWidget(self.reference_type_label, 20, 0)
|
||||
grid4.addWidget(self.reference_type_combo, 20, 1)
|
||||
|
||||
self.reference_combo_label = FCLabel('%s:' % _("Ref. Object"))
|
||||
self.reference_combo_label.setToolTip(
|
||||
_("The FlatCAM object to be used as non copper clearing reference.")
|
||||
)
|
||||
# Reference Object
|
||||
self.reference_combo = FCComboBox()
|
||||
self.reference_combo.setModel(self.app.collection)
|
||||
self.reference_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
|
||||
self.reference_combo.is_last = True
|
||||
form1.addRow(self.reference_combo_label, self.reference_combo)
|
||||
|
||||
grid4.addWidget(self.reference_combo, 22, 0, 1, 2)
|
||||
|
||||
self.reference_combo.hide()
|
||||
self.reference_combo_label.hide()
|
||||
self.reference_type_combo.hide()
|
||||
self.reference_type_label.hide()
|
||||
|
||||
|
@ -3157,8 +3153,8 @@ class PaintUI:
|
|||
self.area_shape_radio = RadioSet([{'label': _("Square"), 'value': 'square'},
|
||||
{'label': _("Polygon"), 'value': 'polygon'}])
|
||||
|
||||
grid4.addWidget(self.area_shape_label, 21, 0)
|
||||
grid4.addWidget(self.area_shape_radio, 21, 1)
|
||||
grid4.addWidget(self.area_shape_label, 24, 0)
|
||||
grid4.addWidget(self.area_shape_radio, 24, 1)
|
||||
|
||||
self.area_shape_label.hide()
|
||||
self.area_shape_radio.hide()
|
||||
|
@ -3220,12 +3216,10 @@ class PaintUI:
|
|||
|
||||
if sel_combo == 3: # _("Reference Object")
|
||||
self.reference_combo.show()
|
||||
self.reference_combo_label.show()
|
||||
self.reference_type_combo.show()
|
||||
self.reference_type_label.show()
|
||||
else:
|
||||
self.reference_combo.hide()
|
||||
self.reference_combo_label.hide()
|
||||
self.reference_type_combo.hide()
|
||||
self.reference_type_label.hide()
|
||||
|
||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue