Fix runner and fox issue where text editor did not open
Some checks failed
Python CI / test (push) Successful in 34s
Lint / lint (push) Successful in 1m3s
Tests / test (3.11) (push) Has been cancelled
Tests / test (3.9) (push) Has been cancelled
Tests / test (3.10) (push) Has been cancelled

This commit is contained in:
Duncan Tourolle 2025-10-24 23:40:04 +02:00
parent ea4e653e66
commit 8a9a2a73f4
3 changed files with 199 additions and 10 deletions

View File

@ -356,15 +356,18 @@ class GLWidget(QOpenGLWidget):
# No rotation - draw normally
rect = QRectF(screen_x, screen_y, screen_w, screen_h)
# Set text alignment
alignment = Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter
# Set text alignment with proper support for multiline text
alignment = Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignTop
if element.alignment == 'center':
alignment = Qt.AlignmentFlag.AlignCenter | Qt.AlignmentFlag.AlignVCenter
alignment = Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignTop
elif element.alignment == 'right':
alignment = Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter
alignment = Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignTop
# Draw the text
painter.drawText(rect, alignment, element.text_content)
# Enable word wrapping for multiline text support
text_flags = Qt.TextFlag.TextWordWrap
# Draw the text with wrapping enabled
painter.drawText(rect, int(alignment | text_flags), element.text_content)
# Restore painter state if we rotated
if element.rotation != 0:
@ -373,6 +376,40 @@ class GLWidget(QOpenGLWidget):
finally:
painter.end()
def mouseDoubleClickEvent(self, event):
"""Handle mouse double-click events"""
if event.button() == Qt.MouseButton.LeftButton:
x, y = event.position().x(), event.position().y()
element = self._get_element_at(x, y)
# Check if double-clicked on a TextBoxData element
from pyPhotoAlbum.models import TextBoxData
if isinstance(element, TextBoxData):
self._edit_text_element(element)
return
# Call parent implementation for default behavior
super().mouseDoubleClickEvent(event)
def _edit_text_element(self, text_element):
"""Open dialog to edit text element"""
from pyPhotoAlbum.text_edit_dialog import TextEditDialog
dialog = TextEditDialog(text_element, self)
if dialog.exec() == TextEditDialog.DialogCode.Accepted:
# Get new values
values = dialog.get_values()
# Update text element
text_element.text_content = values['text_content']
text_element.font_settings = values['font_settings']
text_element.alignment = values['alignment']
# Update view
self.update()
print(f"Updated text element: {values['text_content'][:50]}...")
def mousePressEvent(self, event):
"""Handle mouse press events"""
if event.button() == Qt.MouseButton.LeftButton:

View File

@ -9,6 +9,7 @@ from reportlab.pdfgen import canvas
from reportlab.lib.utils import ImageReader
from PIL import Image
import math
from pyPhotoAlbum.models import ImageData, TextBoxData, PlaceholderData
class PDFExporter:
@ -172,8 +173,6 @@ class PDFExporter:
page_height_pt: Page height in points
page_number: Current page number (for error messages)
"""
from pyPhotoAlbum.models import ImageData, TextBoxData, PlaceholderData
# Skip placeholders
if isinstance(element, PlaceholderData):
return
@ -219,8 +218,6 @@ class PDFExporter:
page_number: Current page number
side: 'left' or 'right'
"""
from pyPhotoAlbum.models import ImageData, TextBoxData, PlaceholderData
# Skip placeholders
if isinstance(element, PlaceholderData):
return

View File

@ -0,0 +1,155 @@
"""
Text editing dialog for pyPhotoAlbum
"""
from PyQt6.QtWidgets import (
QDialog, QVBoxLayout, QHBoxLayout, QPushButton,
QTextEdit, QLabel, QComboBox, QSpinBox, QColorDialog
)
from PyQt6.QtCore import Qt
from PyQt6.QtGui import QFont, QColor
class TextEditDialog(QDialog):
"""Dialog for editing text box content and properties"""
def __init__(self, text_element, parent=None):
super().__init__(parent)
self.text_element = text_element
self.setWindowTitle("Edit Text")
self.resize(500, 400)
# Create UI
self._init_ui()
# Load current values
self._load_values()
def _init_ui(self):
"""Initialize the user interface"""
layout = QVBoxLayout()
# Text editor
text_label = QLabel("Text:")
self.text_edit = QTextEdit()
self.text_edit.setAcceptRichText(False) # Plain text only
layout.addWidget(text_label)
layout.addWidget(self.text_edit)
# Font settings
font_layout = QHBoxLayout()
# Font family
font_layout.addWidget(QLabel("Font:"))
self.font_combo = QComboBox()
self.font_combo.addItems([
"Arial", "Times New Roman", "Courier New",
"Helvetica", "Verdana", "Georgia", "Comic Sans MS"
])
font_layout.addWidget(self.font_combo)
# Font size
font_layout.addWidget(QLabel("Size:"))
self.font_size_spin = QSpinBox()
self.font_size_spin.setRange(6, 72)
self.font_size_spin.setValue(12)
font_layout.addWidget(self.font_size_spin)
# Text color
self.color_button = QPushButton("Color")
self.color_button.clicked.connect(self._choose_color)
self.current_color = QColor(0, 0, 0) # Default black
font_layout.addWidget(self.color_button)
font_layout.addStretch()
layout.addLayout(font_layout)
# Alignment
alignment_layout = QHBoxLayout()
alignment_layout.addWidget(QLabel("Alignment:"))
self.alignment_combo = QComboBox()
self.alignment_combo.addItems(["left", "center", "right"])
alignment_layout.addWidget(self.alignment_combo)
alignment_layout.addStretch()
layout.addLayout(alignment_layout)
# Buttons
button_layout = QHBoxLayout()
button_layout.addStretch()
cancel_button = QPushButton("Cancel")
cancel_button.clicked.connect(self.reject)
button_layout.addWidget(cancel_button)
ok_button = QPushButton("OK")
ok_button.clicked.connect(self.accept)
ok_button.setDefault(True)
button_layout.addWidget(ok_button)
layout.addLayout(button_layout)
self.setLayout(layout)
def _load_values(self):
"""Load current values from text element"""
# Load text content
self.text_edit.setPlainText(self.text_element.text_content)
# Load font settings
font_family = self.text_element.font_settings.get('family', 'Arial')
index = self.font_combo.findText(font_family)
if index >= 0:
self.font_combo.setCurrentIndex(index)
font_size = self.text_element.font_settings.get('size', 12)
self.font_size_spin.setValue(int(font_size))
# Load color
color = self.text_element.font_settings.get('color', (0, 0, 0))
if all(isinstance(c, int) and c > 1 for c in color):
# Color in 0-255 range
self.current_color = QColor(*color)
else:
# Color in 0-1 range
self.current_color = QColor(
int(color[0] * 255),
int(color[1] * 255),
int(color[2] * 255)
)
self._update_color_button()
# Load alignment
alignment = self.text_element.alignment
index = self.alignment_combo.findText(alignment)
if index >= 0:
self.alignment_combo.setCurrentIndex(index)
def _choose_color(self):
"""Open color picker dialog"""
color = QColorDialog.getColor(self.current_color, self, "Choose Text Color")
if color.isValid():
self.current_color = color
self._update_color_button()
def _update_color_button(self):
"""Update color button appearance"""
self.color_button.setStyleSheet(
f"background-color: {self.current_color.name()}; "
f"color: {'white' if self.current_color.lightness() < 128 else 'black'};"
)
def get_values(self):
"""Get the edited values"""
return {
'text_content': self.text_edit.toPlainText(),
'font_settings': {
'family': self.font_combo.currentText(),
'size': self.font_size_spin.value(),
'color': (
self.current_color.red(),
self.current_color.green(),
self.current_color.blue()
)
},
'alignment': self.alignment_combo.currentText()
}