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"
)
def new_project(self):
"""Create a new project"""
self.project = Project("New Project")
self.show_status("New project created")
print("New project created")
"""Create a new project with initial setup dialog"""
from PyQt6.QtWidgets import QDialog, QVBoxLayout, QHBoxLayout, QLabel, QDoubleSpinBox, QSpinBox, QPushButton, QGroupBox, QLineEdit
# 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(
label="Open",

View File

@ -43,20 +43,41 @@ class PageOperationsMixin:
)
def page_setup(self):
"""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:
return
current_page = self.project.pages[0]
# Create dialog
dialog = QDialog(self)
dialog.setWindowTitle("Page Setup")
dialog.setMinimumWidth(400)
dialog.setMinimumWidth(450)
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
size_group = QGroupBox("Page Size")
size_layout = QVBoxLayout()
@ -66,7 +87,6 @@ class PageOperationsMixin:
width_layout.addWidget(QLabel("Width:"))
width_spinbox = QDoubleSpinBox()
width_spinbox.setRange(10, 1000)
width_spinbox.setValue(current_page.layout.size[0])
width_spinbox.setSuffix(" mm")
width_layout.addWidget(width_spinbox)
size_layout.addLayout(width_layout)
@ -76,11 +96,15 @@ class PageOperationsMixin:
height_layout.addWidget(QLabel("Height:"))
height_spinbox = QDoubleSpinBox()
height_spinbox.setRange(10, 1000)
height_spinbox.setValue(current_page.layout.size[1])
height_spinbox.setSuffix(" mm")
height_layout.addWidget(height_spinbox)
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)
layout.addWidget(size_group)
@ -109,6 +133,24 @@ class PageOperationsMixin:
dpi_group.setLayout(dpi_layout)
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
button_layout = QHBoxLayout()
cancel_btn = QPushButton("Cancel")
@ -126,24 +168,54 @@ class PageOperationsMixin:
# Show dialog
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()
height_mm = height_spinbox.value()
# Check if size actually changed
old_size = current_page.layout.size
if old_size != (width_mm, height_mm):
# Mark page as manually sized
current_page.manually_sized = True
current_page.layout.size = (width_mm, height_mm)
print(f"Page {current_page.page_number} marked as manually sized")
# For double spreads, compare with base width
if selected_page.is_double_spread:
old_base_width = selected_page.layout.base_width if hasattr(selected_page.layout, 'base_width') else selected_page.layout.size[0] / 2
old_height = selected_page.layout.size[1]
size_changed = (old_base_width != width_mm or old_height != height_mm)
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.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.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(
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!")