2025-11-11 16:02:02 +00:00

159 lines
5.2 KiB
Python

"""
Edit operations mixin for pyPhotoAlbum
"""
from pyPhotoAlbum.decorators import ribbon_action
from pyPhotoAlbum.commands import DeleteElementCommand, RotateElementCommand
class EditOperationsMixin:
"""Mixin providing edit-related operations"""
@ribbon_action(
label="Undo",
tooltip="Undo last action (Ctrl+Z)",
tab="Home",
group="Edit",
shortcut="Ctrl+Z"
)
def undo(self):
"""Undo last action"""
if self.project.history.undo():
self.update_view()
self.show_status("Undo successful", 2000)
print("Undo successful")
else:
self.show_status("Nothing to undo", 2000)
print("Nothing to undo")
@ribbon_action(
label="Redo",
tooltip="Redo last action (Ctrl+Y or Ctrl+Shift+Z)",
tab="Home",
group="Edit",
shortcut="Ctrl+Y"
)
def redo(self):
"""Redo last action"""
if self.project.history.redo():
self.update_view()
self.show_status("Redo successful", 2000)
print("Redo successful")
else:
self.show_status("Nothing to redo", 2000)
print("Nothing to redo")
@ribbon_action(
label="Delete",
tooltip="Delete selected element (Delete key)",
tab="Home",
group="Edit",
shortcut="Delete",
requires_selection=True
)
def delete_selected_element(self):
"""Delete the currently selected element"""
if not self.require_selection(min_count=1):
return
current_page = self.get_current_page()
if not current_page:
return
# Delete the first selected element (for backward compatibility)
# In the future, we could delete all selected elements
selected_element = next(iter(self.gl_widget.selected_elements))
try:
cmd = DeleteElementCommand(
current_page.layout,
selected_element,
asset_manager=self.project.asset_manager
)
self.project.history.execute(cmd)
# Clear selection
self.gl_widget.selected_elements.clear()
# Update display
self.update_view()
self.show_status("Element deleted (Ctrl+Z to undo)", 2000)
print("Deleted selected element")
except Exception as e:
self.show_error("Error", f"Failed to delete element: {str(e)}")
print(f"Error deleting element: {e}")
@ribbon_action(
label="Rotate Left",
tooltip="Rotate selected element 90° counter-clockwise",
tab="Home",
group="Transform",
requires_selection=True
)
def rotate_left(self):
"""Rotate selected element 90 degrees counter-clockwise"""
if not self.require_selection(min_count=1):
return
selected_element = next(iter(self.gl_widget.selected_elements))
old_rotation = selected_element.rotation
new_rotation = (old_rotation - 90) % 360
cmd = RotateElementCommand(selected_element, old_rotation, new_rotation)
self.project.history.execute(cmd)
self.update_view()
self.show_status(f"Rotated to {new_rotation}° (Ctrl+Z to undo)", 2000)
print(f"Rotated element left: {old_rotation}° → {new_rotation}°")
@ribbon_action(
label="Rotate Right",
tooltip="Rotate selected element 90° clockwise",
tab="Home",
group="Transform",
requires_selection=True
)
def rotate_right(self):
"""Rotate selected element 90 degrees clockwise"""
if not self.require_selection(min_count=1):
return
selected_element = next(iter(self.gl_widget.selected_elements))
old_rotation = selected_element.rotation
new_rotation = (old_rotation + 90) % 360
cmd = RotateElementCommand(selected_element, old_rotation, new_rotation)
self.project.history.execute(cmd)
self.update_view()
self.show_status(f"Rotated to {new_rotation}° (Ctrl+Z to undo)", 2000)
print(f"Rotated element right: {old_rotation}° → {new_rotation}°")
@ribbon_action(
label="Reset Rotation",
tooltip="Reset selected element rotation to 0°",
tab="Home",
group="Transform",
requires_selection=True
)
def reset_rotation(self):
"""Reset selected element rotation to 0 degrees"""
if not self.require_selection(min_count=1):
return
selected_element = next(iter(self.gl_widget.selected_elements))
old_rotation = selected_element.rotation
if old_rotation == 0:
self.show_status("Element already at 0°", 2000)
return
cmd = RotateElementCommand(selected_element, old_rotation, 0)
self.project.history.execute(cmd)
self.update_view()
self.show_status("Reset rotation to 0° (Ctrl+Z to undo)", 2000)
print(f"Reset element rotation: {old_rotation}° → 0°")