page size set when making a project
All checks were successful
Python CI / test (push) Successful in 59s
Lint / lint (push) Successful in 1m7s
Tests / test (3.10) (push) Successful in 45s
Tests / test (3.11) (push) Successful in 46s
Tests / test (3.9) (push) Successful in 43s

This commit is contained in:
Duncan Tourolle 2025-10-29 18:35:52 +01:00
parent 4bf978b75a
commit 3e3b604d2f
3 changed files with 315 additions and 19 deletions

View File

@ -18,10 +18,144 @@ class FileOperationsMixin:
shortcut="Ctrl+N" shortcut="Ctrl+N"
) )
def new_project(self): def new_project(self):
"""Create a new project""" """Create a new project with initial setup dialog"""
self.project = Project("New Project") from PyQt6.QtWidgets import QDialog, QVBoxLayout, QHBoxLayout, QLabel, QDoubleSpinBox, QSpinBox, QPushButton, QGroupBox, QLineEdit
self.show_status("New project created")
print("New project created") # Create new project setup dialog
dialog = QDialog(self)
dialog.setWindowTitle("New Project Setup")
dialog.setMinimumWidth(450)
layout = QVBoxLayout()
# Project name group
name_group = QGroupBox("Project Name")
name_layout = QVBoxLayout()
name_input = QLineEdit()
name_input.setText("New Project")
name_input.selectAll()
name_layout.addWidget(name_input)
name_group.setLayout(name_layout)
layout.addWidget(name_group)
# Default page size group
size_group = QGroupBox("Default Page Size")
size_layout = QVBoxLayout()
info_label = QLabel("This will be the default size for all new pages in this project.")
info_label.setWordWrap(True)
info_label.setStyleSheet("font-size: 9pt; color: gray;")
size_layout.addWidget(info_label)
# Width
width_layout = QHBoxLayout()
width_layout.addWidget(QLabel("Width:"))
width_spinbox = QDoubleSpinBox()
width_spinbox.setRange(10, 1000)
width_spinbox.setValue(140) # Default 14cm
width_spinbox.setSuffix(" mm")
width_layout.addWidget(width_spinbox)
size_layout.addLayout(width_layout)
# Height
height_layout = QHBoxLayout()
height_layout.addWidget(QLabel("Height:"))
height_spinbox = QDoubleSpinBox()
height_spinbox.setRange(10, 1000)
height_spinbox.setValue(140) # Default 14cm
height_spinbox.setSuffix(" mm")
height_layout.addWidget(height_spinbox)
size_layout.addLayout(height_layout)
# Add common size presets
presets_layout = QHBoxLayout()
presets_layout.addWidget(QLabel("Presets:"))
def set_preset(w, h):
width_spinbox.setValue(w)
height_spinbox.setValue(h)
preset_a4 = QPushButton("A4 (210×297)")
preset_a4.clicked.connect(lambda: set_preset(210, 297))
presets_layout.addWidget(preset_a4)
preset_a5 = QPushButton("A5 (148×210)")
preset_a5.clicked.connect(lambda: set_preset(148, 210))
presets_layout.addWidget(preset_a5)
preset_square = QPushButton("Square (200×200)")
preset_square.clicked.connect(lambda: set_preset(200, 200))
presets_layout.addWidget(preset_square)
presets_layout.addStretch()
size_layout.addLayout(presets_layout)
size_group.setLayout(size_layout)
layout.addWidget(size_group)
# DPI settings group
dpi_group = QGroupBox("DPI Settings")
dpi_layout = QVBoxLayout()
# Working DPI
working_dpi_layout = QHBoxLayout()
working_dpi_layout.addWidget(QLabel("Working DPI:"))
working_dpi_spinbox = QSpinBox()
working_dpi_spinbox.setRange(72, 1200)
working_dpi_spinbox.setValue(300)
working_dpi_layout.addWidget(working_dpi_spinbox)
dpi_layout.addLayout(working_dpi_layout)
# Export DPI
export_dpi_layout = QHBoxLayout()
export_dpi_layout.addWidget(QLabel("Export DPI:"))
export_dpi_spinbox = QSpinBox()
export_dpi_spinbox.setRange(72, 1200)
export_dpi_spinbox.setValue(300)
export_dpi_layout.addWidget(export_dpi_spinbox)
dpi_layout.addLayout(export_dpi_layout)
dpi_group.setLayout(dpi_layout)
layout.addWidget(dpi_group)
# Buttons
button_layout = QHBoxLayout()
cancel_btn = QPushButton("Cancel")
cancel_btn.clicked.connect(dialog.reject)
create_btn = QPushButton("Create Project")
create_btn.clicked.connect(dialog.accept)
create_btn.setDefault(True)
button_layout.addStretch()
button_layout.addWidget(cancel_btn)
button_layout.addWidget(create_btn)
layout.addLayout(button_layout)
dialog.setLayout(layout)
# Show dialog
if dialog.exec() == QDialog.DialogCode.Accepted:
# Get values
project_name = name_input.text().strip() or "New Project"
width_mm = width_spinbox.value()
height_mm = height_spinbox.value()
working_dpi = working_dpi_spinbox.value()
export_dpi = export_dpi_spinbox.value()
# Create project with custom settings
self.project = Project(project_name)
self.project.page_size_mm = (width_mm, height_mm)
self.project.working_dpi = working_dpi
self.project.export_dpi = export_dpi
# Update view
self.update_view()
self.show_status(f"New project created: {project_name} ({width_mm}×{height_mm} mm)")
print(f"New project created: {project_name}, default page size: {width_mm}×{height_mm} mm")
else:
# User cancelled - keep current project
print("New project creation cancelled")
@ribbon_action( @ribbon_action(
label="Open", label="Open",

View File

@ -43,20 +43,41 @@ class PageOperationsMixin:
) )
def page_setup(self): def page_setup(self):
"""Open page setup dialog""" """Open page setup dialog"""
from PyQt6.QtWidgets import QDialog, QVBoxLayout, QHBoxLayout, QLabel, QDoubleSpinBox, QSpinBox, QPushButton, QGroupBox from PyQt6.QtWidgets import QDialog, QVBoxLayout, QHBoxLayout, QLabel, QDoubleSpinBox, QSpinBox, QPushButton, QGroupBox, QComboBox, QCheckBox
# Use first page as reference # Check if we have pages
if not self.project.pages: if not self.project.pages:
return return
current_page = self.project.pages[0]
# Create dialog # Create dialog
dialog = QDialog(self) dialog = QDialog(self)
dialog.setWindowTitle("Page Setup") dialog.setWindowTitle("Page Setup")
dialog.setMinimumWidth(400) dialog.setMinimumWidth(450)
layout = QVBoxLayout() layout = QVBoxLayout()
# Page selection group
page_select_group = QGroupBox("Select Page")
page_select_layout = QVBoxLayout()
page_combo = QComboBox()
for i, page in enumerate(self.project.pages):
page_label = f"Page {page.page_number}"
if page.is_double_spread:
page_label += f" (Double Spread: {page.page_number}-{page.page_number + 1})"
if page.manually_sized:
page_label += " *"
page_combo.addItem(page_label, i)
page_select_layout.addWidget(page_combo)
# Add info label
info_label = QLabel("* = Manually sized page")
info_label.setStyleSheet("font-size: 9pt; color: gray;")
page_select_layout.addWidget(info_label)
page_select_group.setLayout(page_select_layout)
layout.addWidget(page_select_group)
# Page size group # Page size group
size_group = QGroupBox("Page Size") size_group = QGroupBox("Page Size")
size_layout = QVBoxLayout() size_layout = QVBoxLayout()
@ -66,7 +87,6 @@ class PageOperationsMixin:
width_layout.addWidget(QLabel("Width:")) width_layout.addWidget(QLabel("Width:"))
width_spinbox = QDoubleSpinBox() width_spinbox = QDoubleSpinBox()
width_spinbox.setRange(10, 1000) width_spinbox.setRange(10, 1000)
width_spinbox.setValue(current_page.layout.size[0])
width_spinbox.setSuffix(" mm") width_spinbox.setSuffix(" mm")
width_layout.addWidget(width_spinbox) width_layout.addWidget(width_spinbox)
size_layout.addLayout(width_layout) size_layout.addLayout(width_layout)
@ -76,11 +96,15 @@ class PageOperationsMixin:
height_layout.addWidget(QLabel("Height:")) height_layout.addWidget(QLabel("Height:"))
height_spinbox = QDoubleSpinBox() height_spinbox = QDoubleSpinBox()
height_spinbox.setRange(10, 1000) height_spinbox.setRange(10, 1000)
height_spinbox.setValue(current_page.layout.size[1])
height_spinbox.setSuffix(" mm") height_spinbox.setSuffix(" mm")
height_layout.addWidget(height_spinbox) height_layout.addWidget(height_spinbox)
size_layout.addLayout(height_layout) size_layout.addLayout(height_layout)
# Set as default checkbox
set_default_checkbox = QCheckBox("Set as default for new pages")
set_default_checkbox.setToolTip("Update project default page size for future pages")
size_layout.addWidget(set_default_checkbox)
size_group.setLayout(size_layout) size_group.setLayout(size_layout)
layout.addWidget(size_group) layout.addWidget(size_group)
@ -109,6 +133,24 @@ class PageOperationsMixin:
dpi_group.setLayout(dpi_layout) dpi_group.setLayout(dpi_layout)
layout.addWidget(dpi_group) layout.addWidget(dpi_group)
# Function to update displayed values when page selection changes
def on_page_changed(index):
selected_page = self.project.pages[index]
# Get base width (accounting for double spreads)
if selected_page.is_double_spread:
display_width = selected_page.layout.base_width if hasattr(selected_page.layout, 'base_width') else selected_page.layout.size[0] / 2
else:
display_width = selected_page.layout.size[0]
width_spinbox.setValue(display_width)
height_spinbox.setValue(selected_page.layout.size[1])
# Connect page selection change
page_combo.currentIndexChanged.connect(on_page_changed)
# Initialize with first page
on_page_changed(0)
# Buttons # Buttons
button_layout = QHBoxLayout() button_layout = QHBoxLayout()
cancel_btn = QPushButton("Cancel") cancel_btn = QPushButton("Cancel")
@ -126,24 +168,54 @@ class PageOperationsMixin:
# Show dialog # Show dialog
if dialog.exec() == QDialog.DialogCode.Accepted: if dialog.exec() == QDialog.DialogCode.Accepted:
# Apply changes # Get selected page
selected_index = page_combo.currentData()
selected_page = self.project.pages[selected_index]
# Get new values
width_mm = width_spinbox.value() width_mm = width_spinbox.value()
height_mm = height_spinbox.value() height_mm = height_spinbox.value()
# Check if size actually changed # Check if size actually changed
old_size = current_page.layout.size # For double spreads, compare with base width
if old_size != (width_mm, height_mm): if selected_page.is_double_spread:
# Mark page as manually sized old_base_width = selected_page.layout.base_width if hasattr(selected_page.layout, 'base_width') else selected_page.layout.size[0] / 2
current_page.manually_sized = True old_height = selected_page.layout.size[1]
current_page.layout.size = (width_mm, height_mm) size_changed = (old_base_width != width_mm or old_height != height_mm)
print(f"Page {current_page.page_number} marked as manually sized")
if size_changed:
# Update double spread
selected_page.layout.base_width = width_mm
selected_page.layout.size = (width_mm * 2, height_mm)
selected_page.manually_sized = True
print(f"Page {selected_page.page_number} (double spread) updated to {width_mm}×{height_mm} mm per page")
else:
old_size = selected_page.layout.size
size_changed = (old_size != (width_mm, height_mm))
if size_changed:
# Update single page
selected_page.layout.size = (width_mm, height_mm)
selected_page.layout.base_width = width_mm
selected_page.manually_sized = True
print(f"Page {selected_page.page_number} updated to {width_mm}×{height_mm} mm")
# Update DPI settings
self.project.working_dpi = working_dpi_spinbox.value() self.project.working_dpi = working_dpi_spinbox.value()
self.project.export_dpi = export_dpi_spinbox.value() self.project.export_dpi = export_dpi_spinbox.value()
# Set as default if checkbox is checked
if set_default_checkbox.isChecked():
self.project.page_size_mm = (width_mm, height_mm)
print(f"Project default page size set to {width_mm}×{height_mm} mm")
self.update_view() self.update_view()
self.show_status(f"Page size updated: {width_mm}x{height_mm} mm", 2000)
print(f"Page setup updated: {width_mm}x{height_mm} mm, Working DPI: {self.project.working_dpi}, Export DPI: {self.project.export_dpi}") # Build status message
status_msg = f"Page {selected_page.page_number} size: {width_mm}×{height_mm} mm"
if set_default_checkbox.isChecked():
status_msg += " (set as default)"
self.show_status(status_msg, 2000)
@ribbon_action( @ribbon_action(
label="Toggle Spread", label="Toggle Spread",

90
test_page_setup.py Normal file
View File

@ -0,0 +1,90 @@
#!/usr/bin/env python3
"""
Test script to verify Page Setup functionality
"""
import sys
from PyQt6.QtWidgets import QApplication
from pyPhotoAlbum.project import Project, Page
from pyPhotoAlbum.page_layout import PageLayout
def test_page_setup_behavior():
"""Test that page setup works correctly with multiple pages"""
# Create a project with default size
project = Project("Test Project")
print(f"Initial project default page size: {project.page_size_mm}")
# Add first page - should use project default
page1_layout = PageLayout(width=project.page_size_mm[0], height=project.page_size_mm[1])
page1 = Page(layout=page1_layout, page_number=1)
page1.manually_sized = False
project.add_page(page1)
print(f"Page 1 size: {page1.layout.size}, manually_sized: {page1.manually_sized}")
# Add second page - should also use project default
page2_layout = PageLayout(width=project.page_size_mm[0], height=project.page_size_mm[1])
page2 = Page(layout=page2_layout, page_number=2)
page2.manually_sized = False
project.add_page(page2)
print(f"Page 2 size: {page2.layout.size}, manually_sized: {page2.manually_sized}")
# Simulate changing page 1 size without setting as default
print("\n--- Simulating Page Setup on Page 1 (without setting as default) ---")
page1.layout.size = (200, 200)
page1.layout.base_width = 200
page1.manually_sized = True
print(f"Page 1 size after change: {page1.layout.size}, manually_sized: {page1.manually_sized}")
print(f"Project default still: {project.page_size_mm}")
print(f"Page 2 unchanged: {page2.layout.size}, manually_sized: {page2.manually_sized}")
# Add third page - should use original project default
page3_layout = PageLayout(width=project.page_size_mm[0], height=project.page_size_mm[1])
page3 = Page(layout=page3_layout, page_number=3)
page3.manually_sized = False
project.add_page(page3)
print(f"Page 3 size: {page3.layout.size}, manually_sized: {page3.manually_sized}")
# Simulate changing page 2 size AND setting as default
print("\n--- Simulating Page Setup on Page 2 (with setting as default) ---")
page2.layout.size = (250, 250)
page2.layout.base_width = 250
page2.manually_sized = True
project.page_size_mm = (250, 250) # Set as default
print(f"Page 2 size after change: {page2.layout.size}, manually_sized: {page2.manually_sized}")
print(f"Project default updated to: {project.page_size_mm}")
# Add fourth page - should use NEW project default
page4_layout = PageLayout(width=project.page_size_mm[0], height=project.page_size_mm[1])
page4 = Page(layout=page4_layout, page_number=4)
page4.manually_sized = False
project.add_page(page4)
print(f"Page 4 size: {page4.layout.size}, manually_sized: {page4.manually_sized}")
# Test double spread
print("\n--- Testing Double Spread ---")
page5_layout = PageLayout(width=project.page_size_mm[0], height=project.page_size_mm[1], is_facing_page=True)
page5 = Page(layout=page5_layout, page_number=5, is_double_spread=True)
page5.manually_sized = False
project.add_page(page5)
print(f"Page 5 (double spread) size: {page5.layout.size}, base_width: {page5.layout.base_width}")
print(f"Expected: width should be 2x base_width = {project.page_size_mm[0] * 2}")
print("\n--- Summary ---")
for i, page in enumerate(project.pages, 1):
spread_info = " (double spread)" if page.is_double_spread else ""
manual_info = " *manually sized*" if page.manually_sized else ""
print(f"Page {i}: {page.layout.size}{spread_info}{manual_info}")
print(f"Project default: {project.page_size_mm}")
print("\n✓ All tests passed!")
if __name__ == "__main__":
# Initialize Qt application (needed for PyQt6 widgets even in tests)
app = QApplication(sys.argv)
test_page_setup_behavior()
print("\nTest completed successfully!")