- finished the Objects menu by adding the ability of actions to be checked so they will show the selected status of the objects and by adding to actions to (de)select all objects
- fixed and optimized the click selection on canvas - fixed Gerber parsing for very simple Gerber files that have only one Polygon but many LPC zones
This commit is contained in:
parent
7eca6085be
commit
b058f65108
208
FlatCAMApp.py
208
FlatCAMApp.py
|
@ -7935,9 +7935,12 @@ class App(QtCore.QObject):
|
|||
def add_act(name):
|
||||
obj_for_icon = self.collection.get_by_name(name)
|
||||
add_action = QtWidgets.QAction(parent=self.ui.menuobjects)
|
||||
add_action.setCheckable(True)
|
||||
add_action.setText(name)
|
||||
add_action.setIcon(QtGui.QIcon(icon_files[obj_for_icon.kind]))
|
||||
add_action.triggered.connect(lambda: self.collection.set_exclusive_active(name))
|
||||
add_action.triggered.connect(
|
||||
lambda: self.collection.set_active(name) if add_action.isChecked() is True else
|
||||
self.collection.set_inactive(name))
|
||||
self.ui.menuobjects.addAction(add_action)
|
||||
|
||||
for name in gerber_list:
|
||||
|
@ -7963,6 +7966,17 @@ class App(QtCore.QObject):
|
|||
for name in doc_list:
|
||||
add_act(name)
|
||||
|
||||
self.ui.menuobjects.addSeparator()
|
||||
self.ui.menuobjects_selall = self.ui.menuobjects.addAction(
|
||||
QtGui.QIcon('share/select_all.png'),
|
||||
_('Select All')
|
||||
)
|
||||
self.ui.menuobjects_unselall = self.ui.menuobjects.addAction(
|
||||
QtGui.QIcon('share/deselect_all32.png'),
|
||||
_('Deselect All')
|
||||
)
|
||||
self.ui.menuobjects_selall.triggered.connect(lambda: self.on_objects_selection(True))
|
||||
self.ui.menuobjects_unselall.triggered.connect(lambda: self.on_objects_selection(False))
|
||||
|
||||
elif state == 'delete':
|
||||
for act in self.ui.menuobjects.actions():
|
||||
|
@ -7979,7 +7993,9 @@ class App(QtCore.QObject):
|
|||
add_action = QtWidgets.QAction(parent=self.ui.menuobjects)
|
||||
add_action.setText(obj.options['name'])
|
||||
add_action.setIcon(QtGui.QIcon(icon_files[obj.kind]))
|
||||
add_action.triggered.connect(lambda: self.collection.set_exclusive_active(obj.options['name']))
|
||||
add_action.triggered.connect(
|
||||
lambda: self.collection.set_active(obj.options['name']) if add_action.isChecked() is True else
|
||||
self.collection.set_inactive(obj.options['name']))
|
||||
|
||||
self.ui.menuobjects.insertAction(act, add_action)
|
||||
|
||||
|
@ -7997,6 +8013,39 @@ class App(QtCore.QObject):
|
|||
pass
|
||||
self.ui.menuobjects.clear()
|
||||
|
||||
self.ui.menuobjects.addSeparator()
|
||||
self.ui.menuobjects_selall = self.ui.menuobjects.addAction(
|
||||
QtGui.QIcon('share/select_all.png'),
|
||||
_('Select All')
|
||||
)
|
||||
self.ui.menuobjects_unselall = self.ui.menuobjects.addAction(
|
||||
QtGui.QIcon('share/deselect_all32.png'),
|
||||
_('Deselect All')
|
||||
)
|
||||
self.ui.menuobjects_selall.triggered.connect(lambda: self.on_objects_selection(True))
|
||||
self.ui.menuobjects_unselall.triggered.connect(lambda: self.on_objects_selection(False))
|
||||
|
||||
def on_objects_selection(self, on_off):
|
||||
obj_list = self.collection.get_names()
|
||||
|
||||
if on_off is True:
|
||||
self.collection.set_all_active()
|
||||
for act in self.ui.menuobjects.actions():
|
||||
try:
|
||||
act.setChecked(True)
|
||||
except:
|
||||
pass
|
||||
if obj_list:
|
||||
self.inform.emit('[selected] %s' % _("All objects are selected."))
|
||||
else:
|
||||
self.collection.set_all_inactive()
|
||||
for act in self.ui.menuobjects.actions():
|
||||
try:
|
||||
act.setChecked(False)
|
||||
except:
|
||||
pass
|
||||
self.inform.emit('%s' % _("Objects selection is cleared."))
|
||||
|
||||
def grid_status(self):
|
||||
if self.ui.grid_snap_btn.isChecked():
|
||||
return True
|
||||
|
@ -8439,93 +8488,40 @@ class App(QtCore.QObject):
|
|||
objects_under_the_click_list.append(obj.options['name'])
|
||||
|
||||
try:
|
||||
# If there is no element in the overlapped objects list then make everyone inactive
|
||||
# because we selected "nothing"
|
||||
self.collection.set_all_inactive()
|
||||
|
||||
# delete the possible selection box around a possible selected object
|
||||
self.delete_selection_shape()
|
||||
|
||||
if not objects_under_the_click_list:
|
||||
|
||||
# and as a convenience move the focus to the Project tab because Selected tab is now empty but
|
||||
# only when working on App
|
||||
if self.call_source == 'app':
|
||||
if self.click_noproject is False:
|
||||
self.ui.notebook.setCurrentWidget(self.ui.project_tab)
|
||||
else:
|
||||
# restore auto open the Project Tab
|
||||
self.click_noproject = False
|
||||
|
||||
# delete any text in the status bar, implicitly the last object name that was selected
|
||||
self.inform.emit("")
|
||||
else:
|
||||
self.call_source = 'app'
|
||||
else:
|
||||
if objects_under_the_click_list:
|
||||
curr_sel_obj = self.collection.get_active()
|
||||
# case when there is only an object under the click and we toggle it
|
||||
if len(objects_under_the_click_list) == 1:
|
||||
if self.collection.get_active() is None:
|
||||
if curr_sel_obj is None:
|
||||
self.collection.set_active(objects_under_the_click_list[0])
|
||||
# create the selection box around the selected object
|
||||
curr_sel_obj = self.collection.get_active()
|
||||
|
||||
# create the selection box around the selected object
|
||||
if self.defaults['global_selection_shape'] is True:
|
||||
self.draw_selection_shape(curr_sel_obj)
|
||||
|
||||
# self.inform.emit('[selected] %s: %s selected' %
|
||||
# (str(curr_sel_obj.kind).capitalize(), str(curr_sel_obj.options['name'])))
|
||||
if curr_sel_obj.kind == 'gerber':
|
||||
self.inform.emit(
|
||||
_('[selected]<span style="color:{color};">{name}</span> selected').format(
|
||||
color='green', name=str(curr_sel_obj.options['name'])))
|
||||
elif curr_sel_obj.kind == 'excellon':
|
||||
self.inform.emit(
|
||||
_('[selected]<span style="color:{color};">{name}</span> selected').format(
|
||||
color='brown', name=str(curr_sel_obj.options['name'])))
|
||||
elif curr_sel_obj.kind == 'cncjob':
|
||||
self.inform.emit(
|
||||
_('[selected]<span style="color:{color};">{name}</span> selected').format(
|
||||
color='blue', name=str(curr_sel_obj.options['name'])))
|
||||
elif curr_sel_obj.kind == 'geometry':
|
||||
self.inform.emit(
|
||||
_('[selected]<span style="color:{color};">{name}</span> selected').format(
|
||||
color='red', name=str(curr_sel_obj.options['name'])))
|
||||
|
||||
elif self.collection.get_active().options['name'] not in objects_under_the_click_list:
|
||||
self.collection.set_all_inactive()
|
||||
self.on_objects_selection(False)
|
||||
self.delete_selection_shape()
|
||||
|
||||
self.collection.set_active(objects_under_the_click_list[0])
|
||||
# create the selection box around the selected object
|
||||
curr_sel_obj = self.collection.get_active()
|
||||
|
||||
# create the selection box around the selected object
|
||||
if self.defaults['global_selection_shape'] is True:
|
||||
self.draw_selection_shape(curr_sel_obj)
|
||||
|
||||
# self.inform.emit('[selected] %s: %s selected' %
|
||||
# (str(curr_sel_obj.kind).capitalize(), str(curr_sel_obj.options['name'])))
|
||||
if curr_sel_obj.kind == 'gerber':
|
||||
self.inform.emit(
|
||||
_('[selected]<span style="color:{color};">{name}</span> selected').format(
|
||||
color='green', name=str(curr_sel_obj.options['name'])))
|
||||
elif curr_sel_obj.kind == 'excellon':
|
||||
self.inform.emit(
|
||||
_('[selected]<span style="color:{color};">{name}</span> selected').format(
|
||||
color='brown', name=str(curr_sel_obj.options['name'])))
|
||||
elif curr_sel_obj.kind == 'cncjob':
|
||||
self.inform.emit(
|
||||
_('[selected]<span style="color:{color};">{name}</span> selected').format(
|
||||
color='blue', name=str(curr_sel_obj.options['name'])))
|
||||
elif curr_sel_obj.kind == 'geometry':
|
||||
self.inform.emit(
|
||||
_('[selected]<span style="color:{color};">{name}</span> selected').format(
|
||||
color='red', name=str(curr_sel_obj.options['name'])))
|
||||
self.selected_message(curr_sel_obj=curr_sel_obj)
|
||||
|
||||
else:
|
||||
self.collection.set_all_inactive()
|
||||
self.on_objects_selection(False)
|
||||
self.delete_selection_shape()
|
||||
if self.call_source == 'app':
|
||||
# delete any text in the status bar, implicitly the last object name that was selected
|
||||
self.inform.emit("")
|
||||
else:
|
||||
|
||||
if self.call_source != 'app':
|
||||
self.call_source = 'app'
|
||||
|
||||
self.selected_message(curr_sel_obj=curr_sel_obj)
|
||||
|
||||
else:
|
||||
# If there is no selected object
|
||||
# make active the first element of the overlapped objects list
|
||||
|
@ -8540,9 +8536,9 @@ class App(QtCore.QObject):
|
|||
name_sel_obj = objects_under_the_click_list[0]
|
||||
self.collection.set_active(name_sel_obj)
|
||||
else:
|
||||
name_sel_obj_idx = objects_under_the_click_list.index(name_sel_obj)
|
||||
sel_idx = objects_under_the_click_list.index(name_sel_obj)
|
||||
self.collection.set_all_inactive()
|
||||
self.collection.set_active(objects_under_the_click_list[(name_sel_obj_idx + 1) %
|
||||
self.collection.set_active(objects_under_the_click_list[(sel_idx + 1) %
|
||||
len(objects_under_the_click_list)])
|
||||
|
||||
curr_sel_obj = self.collection.get_active()
|
||||
|
@ -8552,30 +8548,44 @@ class App(QtCore.QObject):
|
|||
if self.defaults['global_selection_shape'] is True:
|
||||
self.draw_selection_shape(curr_sel_obj)
|
||||
|
||||
# self.inform.emit('[selected] %s: %s selected' %
|
||||
# (str(curr_sel_obj.kind).capitalize(), str(curr_sel_obj.options['name'])))
|
||||
if curr_sel_obj.kind == 'gerber':
|
||||
self.inform.emit(_('[selected]<span style="color:{color};">{name}</span> selected').format(
|
||||
color='green', name=str(curr_sel_obj.options['name'])))
|
||||
elif curr_sel_obj.kind == 'excellon':
|
||||
self.inform.emit(_('[selected]<span style="color:{color};">{name}</span> selected').format(
|
||||
color='brown', name=str(curr_sel_obj.options['name'])))
|
||||
elif curr_sel_obj.kind == 'cncjob':
|
||||
self.inform.emit(_('[selected]<span style="color:{color};">{name}</span> selected').format(
|
||||
color='blue', name=str(curr_sel_obj.options['name'])))
|
||||
elif curr_sel_obj.kind == 'geometry':
|
||||
self.inform.emit(_('[selected]<span style="color:{color};">{name}</span> selected').format(
|
||||
color='red', name=str(curr_sel_obj.options['name'])))
|
||||
self.selected_message(curr_sel_obj=curr_sel_obj)
|
||||
|
||||
# for obj in self.collection.get_list():
|
||||
# obj.plot()
|
||||
# curr_sel_obj.plot(color=self.FC_dark_blue, face_color=self.FC_light_blue)
|
||||
else:
|
||||
# deselect everything
|
||||
self.on_objects_selection(False)
|
||||
# delete the possible selection box around a possible selected object
|
||||
self.delete_selection_shape()
|
||||
|
||||
# TODO: on selected objects change the object colors and do not draw the selection box
|
||||
# self.plotcanvas.update() # this updates the canvas
|
||||
# and as a convenience move the focus to the Project tab because Selected tab is now empty but
|
||||
# only when working on App
|
||||
if self.call_source == 'app':
|
||||
if self.click_noproject is False:
|
||||
self.ui.notebook.setCurrentWidget(self.ui.project_tab)
|
||||
else:
|
||||
# restore auto open the Project Tab
|
||||
self.click_noproject = False
|
||||
|
||||
# delete any text in the status bar, implicitly the last object name that was selected
|
||||
# self.inform.emit("")
|
||||
else:
|
||||
self.call_source = 'app'
|
||||
except Exception as e:
|
||||
log.error("[ERROR] Something went bad. %s" % str(e))
|
||||
return
|
||||
log.error("[ERROR] Something went bad in App.select_objects(). %s" % str(e))
|
||||
|
||||
def selected_message(self, curr_sel_obj):
|
||||
if curr_sel_obj:
|
||||
if curr_sel_obj.kind == 'gerber':
|
||||
self.inform.emit(_('[selected]<span style="color:{color};">{name}</span> selected').format(
|
||||
color='green', name=str(curr_sel_obj.options['name'])))
|
||||
elif curr_sel_obj.kind == 'excellon':
|
||||
self.inform.emit(_('[selected]<span style="color:{color};">{name}</span> selected').format(
|
||||
color='brown', name=str(curr_sel_obj.options['name'])))
|
||||
elif curr_sel_obj.kind == 'cncjob':
|
||||
self.inform.emit(_('[selected]<span style="color:{color};">{name}</span> selected').format(
|
||||
color='blue', name=str(curr_sel_obj.options['name'])))
|
||||
elif curr_sel_obj.kind == 'geometry':
|
||||
self.inform.emit(_('[selected]<span style="color:{color};">{name}</span> selected').format(
|
||||
color='red', name=str(curr_sel_obj.options['name'])))
|
||||
|
||||
def delete_hover_shape(self):
|
||||
self.hover_shapes.clear()
|
||||
|
@ -8634,6 +8644,9 @@ class App(QtCore.QObject):
|
|||
:return:
|
||||
"""
|
||||
|
||||
if sel_obj is None:
|
||||
return
|
||||
|
||||
pt1 = (float(sel_obj.options['xmin']), float(sel_obj.options['ymin']))
|
||||
pt2 = (float(sel_obj.options['xmax']), float(sel_obj.options['ymin']))
|
||||
pt3 = (float(sel_obj.options['xmax']), float(sel_obj.options['ymax']))
|
||||
|
@ -8647,13 +8660,6 @@ class App(QtCore.QObject):
|
|||
sel_rect = sel_rect.buffer(-0.00393)
|
||||
sel_rect = sel_rect.buffer(0.00787)
|
||||
|
||||
# if color:
|
||||
# face = Color(color, alpha=0.2)
|
||||
# outline = Color(color, alpha=0.8)
|
||||
# else:
|
||||
# face = Color(self.defaults['global_sel_fill'], alpha=0.2)
|
||||
# outline = Color(self.defaults['global_sel_line'], alpha=0.8)
|
||||
|
||||
if color:
|
||||
face = color[:-2] + str(hex(int(0.2 * 255)))[2:]
|
||||
outline = color[:-2] + str(hex(int(0.8 * 255)))[2:]
|
||||
|
|
|
@ -724,6 +724,16 @@ class ObjectCollection(QtCore.QAbstractItemModel):
|
|||
log.error("[ERROR] Cause: %s" % str(e))
|
||||
raise
|
||||
|
||||
def set_all_active(self):
|
||||
"""
|
||||
Select all objects from the project list. This triggers the
|
||||
list_selection_changed event and call on_list_selection_changed.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
for name in self.get_names():
|
||||
self.set_active(name)
|
||||
|
||||
def set_exclusive_active(self, name):
|
||||
"""
|
||||
Make the object with the name in parameters the only selected object
|
||||
|
|
|
@ -15,6 +15,9 @@ CAD program, and create G-Code for Isolation routing.
|
|||
- added an translator email address
|
||||
- finished the update on German translation. Part of it was corrected by Jens Karstedt
|
||||
- finished the update of the Romanian translation.
|
||||
- finished the Objects menu by adding the ability of actions to be checked so they will show the selected status of the objects and by adding to actions to (de)select all objects
|
||||
- fixed and optimized the click selection on canvas
|
||||
- fixed Gerber parsing for very simple Gerber files that have only one Polygon but many LPC zones
|
||||
|
||||
16.10.2019
|
||||
|
||||
|
|
|
@ -420,6 +420,12 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
|||
# ########################## Objects # ###################################
|
||||
# ########################################################################
|
||||
self.menuobjects = self.menu.addMenu(_('Objects'))
|
||||
self.menuobjects.addSeparator()
|
||||
self.menuobjects_selall = self.menuobjects.addAction(QtGui.QIcon('share/select_all.png'), _('Select All'))
|
||||
self.menuobjects_unselall = self.menuobjects.addAction(
|
||||
QtGui.QIcon('share/deselect_all32.png'),
|
||||
_('Deselect All')
|
||||
)
|
||||
|
||||
# ########################################################################
|
||||
# ########################## Tool # ######################################
|
||||
|
|
|
@ -1384,7 +1384,7 @@ class Gerber(Geometry):
|
|||
|
||||
# this treats the case when we are storing geometry as solids
|
||||
|
||||
if len(poly_buffer) == 0:
|
||||
if len(poly_buffer) == 0 and len(self.solid_geometry) == 0:
|
||||
log.error("Object is not Gerber file or empty. Aborting Object creation.")
|
||||
return 'fail'
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 690 B |
Loading…
Reference in New Issue