Coverage for pyPhotoAlbum/mixins/operations/element_ops.py: 91%
70 statements
« prev ^ index » next coverage.py v7.14.1, created at 2026-06-20 12:55 +0000
« prev ^ index » next coverage.py v7.14.1, created at 2026-06-20 12:55 +0000
1"""
2Element operations mixin for pyPhotoAlbum
3"""
5from PyQt6.QtWidgets import QFileDialog
6from pyPhotoAlbum.decorators import ribbon_action
7from pyPhotoAlbum.models import ImageData, TextBoxData, PlaceholderData
8from pyPhotoAlbum.commands import AddElementCommand
9from pyPhotoAlbum.async_backend import get_image_dimensions
12class ElementOperationsMixin:
13 """Mixin providing element creation and manipulation operations"""
15 @ribbon_action(
16 label="Image", tooltip="Add an image to the current page", tab="Insert", group="Media", requires_page=True
17 )
18 def add_image(self):
19 """Add an image to the current page"""
20 if not self.require_page():
21 return
23 file_path, _ = QFileDialog.getOpenFileName(
24 self, "Select Image", "", "Image Files (*.jpg *.jpeg *.png *.gif *.bmp *.tiff *.webp);;All Files (*)"
25 )
27 if not file_path:
28 return
30 current_page = self.get_current_page()
31 if not current_page:
32 return
34 try:
35 # Import asset to project
36 asset_path = self.project.asset_manager.import_asset(file_path)
38 # Get dimensions using centralized utility (max 300px for UI display)
39 full_asset_path = self.get_asset_full_path(asset_path)
40 dimensions = get_image_dimensions(full_asset_path, max_size=300)
41 if dimensions:
42 img_width, img_height = dimensions
43 else:
44 # Fallback dimensions if image cannot be read
45 img_width, img_height = 200, 150
47 # Create image element at center of page
48 page_width_mm = current_page.layout.size[0]
49 page_height_mm = current_page.layout.size[1]
51 # Center position
52 x = (page_width_mm - img_width) / 2
53 y = (page_height_mm - img_height) / 2
55 new_image = ImageData(image_path=asset_path, x=x, y=y, width=img_width, height=img_height)
57 # Add element using command pattern for undo/redo
58 cmd = AddElementCommand(current_page.layout, new_image, asset_manager=self.project.asset_manager)
59 self.project.history.execute(cmd)
61 self.update_view()
62 self.show_status("Added image (Ctrl+Z to undo)", 2000)
63 print(f"Added image to page {self.get_current_page_index() + 1}: {asset_path}")
65 except Exception as e:
66 self.show_error("Error", f"Failed to add image: {str(e)}")
67 print(f"Error adding image: {e}")
69 @ribbon_action(
70 label="Text", tooltip="Add a text box to the current page", tab="Insert", group="Media", requires_page=True
71 )
72 def add_text(self):
73 """Add text to the current page"""
74 if not self.require_page():
75 return
77 current_page = self.get_current_page()
78 if not current_page:
79 return
81 # Create text box element at center of page
82 page_width_mm = current_page.layout.size[0]
83 page_height_mm = current_page.layout.size[1]
85 text_width = 200
86 text_height = 50
88 # Center position
89 x = (page_width_mm - text_width) / 2
90 y = (page_height_mm - text_height) / 2
92 new_text = TextBoxData(text_content="New Text", x=x, y=y, width=text_width, height=text_height)
94 current_page.layout.add_element(new_text)
95 self.update_view()
97 print(f"Added text box to page {self.get_current_page_index() + 1}")
99 @ribbon_action(
100 label="Placeholder",
101 tooltip="Add a placeholder to the current page",
102 tab="Insert",
103 group="Media",
104 requires_page=True,
105 )
106 def add_placeholder(self):
107 """Add a placeholder to the current page"""
108 if not self.require_page():
109 return
111 current_page = self.get_current_page()
112 if not current_page:
113 return
115 # Create placeholder element at center of page
116 page_width_mm = current_page.layout.size[0]
117 page_height_mm = current_page.layout.size[1]
119 placeholder_width = 200
120 placeholder_height = 150
122 # Center position
123 x = (page_width_mm - placeholder_width) / 2
124 y = (page_height_mm - placeholder_height) / 2
126 new_placeholder = PlaceholderData(
127 placeholder_type="image", x=x, y=y, width=placeholder_width, height=placeholder_height
128 )
130 current_page.layout.add_element(new_placeholder)
131 self.update_view()
133 print(f"Added placeholder to page {self.get_current_page_index() + 1}")