- 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:
Marius Stanciu 2019-10-19 00:29:29 +03:00 committed by Marius
parent 7eca6085be
commit b058f65108
6 changed files with 127 additions and 102 deletions

View File

@ -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:]

View File

@ -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

View File

@ -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

View File

@ -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 # ######################################

View File

@ -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'

BIN
share/deselect_all32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 690 B