diff --git a/beeref/scene.py b/beeref/scene.py index 959bdb4..8f62c21 100644 --- a/beeref/scene.py +++ b/beeref/scene.py @@ -48,7 +48,7 @@ class BeeGraphicsScene(QtWidgets.QGraphicsScene): :param mode: "width" or "height". """ - values = [getattr(i, mode) for i in self.selectedItems()] + values = [getattr(i, mode) for i in self.selectedItems(user_only=True)] if not values: return avg = sum(values) / len(values) @@ -56,10 +56,11 @@ class BeeGraphicsScene(QtWidgets.QGraphicsScene): logger.debug(f'Calculated average {mode} {avg}') scale_factors = [] - for item in self.selectedItems(): + for item in self.selectedItems(user_only=True): scale_factors.append(avg / getattr(item, mode)) self.undo_stack.push( - commands.NormalizeItems(self.selectedItems(), scale_factors)) + commands.NormalizeItems( + self.selectedItems(user_only=True), scale_factors)) def normalize_height(self): """Scale selected images to the same height.""" @@ -74,7 +75,8 @@ class BeeGraphicsScene(QtWidgets.QGraphicsScene): Size meaning the area = widh * height. """ - sizes = [i.width * i.height for i in self.selectedItems()] + sizes = [i.width * i.height + for i in self.selectedItems(user_only=True)] if not sizes: return @@ -83,15 +85,16 @@ class BeeGraphicsScene(QtWidgets.QGraphicsScene): logger.debug(f'Calculated average size {avg}') scale_factors = [] - for item in self.selectedItems(): + for item in self.selectedItems(user_only=True): scale_factors.append(math.sqrt(avg / item.width / item.height)) self.undo_stack.push( - commands.NormalizeItems(self.selectedItems(), scale_factors)) + commands.NormalizeItems( + self.selectedItems(user_only=True), scale_factors)) def flip_items(self, vertical=False): """Flip selected items.""" self.undo_stack.push( - commands.FlipItems(self.selectedItems(), + commands.FlipItems(self.selectedItems(user_only=True), self.get_selection_center(), vertical=vertical)) @@ -103,17 +106,17 @@ class BeeGraphicsScene(QtWidgets.QGraphicsScene): def has_selection(self): """Checks whether there are currently items selected.""" - return bool(self.selectedItems()) + return bool(self.selectedItems(user_only=True)) def has_single_selection(self): """Checks whether there's currently exactly one item selected.""" - return len(self.selectedItems()) == 1 + return len(self.selectedItems(user_only=True)) == 1 def has_multi_selection(self): """Checks whether there are currently more than one items selected.""" - return len(self.selectedItems()) > 1 + return len(self.selectedItems(user_only=True)) > 1 def mousePressEvent(self, event): if event.button() == Qt.MouseButtons.RightButton: @@ -169,7 +172,20 @@ class BeeGraphicsScene(QtWidgets.QGraphicsScene): self.move_active = False super().mouseReleaseEvent(event) + def selectedItems(self, user_only=False): + """If ``user_only`` is set to ``True``, only return items added + by the user (i.e. no multi select outlines and other UI items). + + User items are items that have a ``save_id`` attribute. + """ + + items = super().selectedItems() + if user_only: + return list(filter(lambda i: hasattr(i, 'save_id'), items)) + return items + def items_for_save(self): + """Returns the items that are to be saved. Items to be saved are items that have a save_id attribute. diff --git a/beeref/view.py b/beeref/view.py index 92616c4..dc86402 100644 --- a/beeref/view.py +++ b/beeref/view.py @@ -184,7 +184,8 @@ class BeeGraphicsView(QtWidgets.QGraphicsView, ActionsMixin): def on_action_delete_items(self): logger.debug('Deleting items...') self.undo_stack.push( - commands.DeleteItems(self.scene, self.scene.selectedItems())) + commands.DeleteItems( + self.scene, self.scene.selectedItems(user_only=True))) def on_action_normalize_height(self): self.scene.normalize_height() @@ -203,19 +204,19 @@ class BeeGraphicsView(QtWidgets.QGraphicsView, ActionsMixin): def on_action_reset_scale(self): self.undo_stack.push(commands.ResetScale( - self.scene.selectedItems())) + self.scene.selectedItems(user_only=True))) def on_action_reset_rotation(self): self.undo_stack.push(commands.ResetRotation( - self.scene.selectedItems())) + self.scene.selectedItems(user_only=True))) def on_action_reset_flip(self): self.undo_stack.push(commands.ResetFlip( - self.scene.selectedItems())) + self.scene.selectedItems(user_only=True))) def on_action_reset_transforms(self): self.undo_stack.push(commands.ResetTransforms( - self.scene.selectedItems())) + self.scene.selectedItems(user_only=True))) def on_items_loaded(self, value): self.scene.add_delayed_items() @@ -345,7 +346,7 @@ class BeeGraphicsView(QtWidgets.QGraphicsView, ActionsMixin): def on_selection_changed(self): logger.debug('Currently selected items: %s', - len(self.scene.selectedItems())) + len(self.scene.selectedItems(user_only=True))) self.actiongroup_set_enabled('active_when_selection', self.scene.has_selection()) self.viewport().repaint() diff --git a/tests/test_scene.py b/tests/test_scene.py index 90fd652..59ea738 100644 --- a/tests/test_scene.py +++ b/tests/test_scene.py @@ -402,6 +402,30 @@ class BeeGraphicsSceneTestCase(BeeTestCase): mouse_mock.assert_called_once_with(event) assert self.scene.move_active is False + def test_selected_items(self): + item1 = BeePixmapItem(QtGui.QImage()) + self.scene.addItem(item1) + item1.setSelected(True) + item2 = BeePixmapItem(QtGui.QImage()) + self.scene.addItem(item2) + item2.setSelected(True) + selected = self.scene.selectedItems() + assert len(selected) == 3 # Multi select item! + assert item1 in selected + assert item2 in selected + + def test_selected_items_user_only(self): + item1 = BeePixmapItem(QtGui.QImage()) + self.scene.addItem(item1) + item1.setSelected(True) + item2 = BeePixmapItem(QtGui.QImage()) + self.scene.addItem(item2) + item2.setSelected(True) + selected = self.scene.selectedItems(user_only=True) + assert len(selected) == 2 # No multi select item! + assert item1 in selected + assert item2 in selected + def test_items_for_save(self): item1 = BeePixmapItem(QtGui.QImage()) self.scene.addItem(item1)