Fix runner and fox issue where text editor did not open
This commit is contained in:
parent
ea4e653e66
commit
8a9a2a73f4
@ -356,15 +356,18 @@ class GLWidget(QOpenGLWidget):
|
|||||||
# No rotation - draw normally
|
# No rotation - draw normally
|
||||||
rect = QRectF(screen_x, screen_y, screen_w, screen_h)
|
rect = QRectF(screen_x, screen_y, screen_w, screen_h)
|
||||||
|
|
||||||
# Set text alignment
|
# Set text alignment with proper support for multiline text
|
||||||
alignment = Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter
|
alignment = Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignTop
|
||||||
if element.alignment == 'center':
|
if element.alignment == 'center':
|
||||||
alignment = Qt.AlignmentFlag.AlignCenter | Qt.AlignmentFlag.AlignVCenter
|
alignment = Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignTop
|
||||||
elif element.alignment == 'right':
|
elif element.alignment == 'right':
|
||||||
alignment = Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter
|
alignment = Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignTop
|
||||||
|
|
||||||
# Draw the text
|
# Enable word wrapping for multiline text support
|
||||||
painter.drawText(rect, alignment, element.text_content)
|
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
|
# Restore painter state if we rotated
|
||||||
if element.rotation != 0:
|
if element.rotation != 0:
|
||||||
@ -373,6 +376,40 @@ class GLWidget(QOpenGLWidget):
|
|||||||
finally:
|
finally:
|
||||||
painter.end()
|
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):
|
def mousePressEvent(self, event):
|
||||||
"""Handle mouse press events"""
|
"""Handle mouse press events"""
|
||||||
if event.button() == Qt.MouseButton.LeftButton:
|
if event.button() == Qt.MouseButton.LeftButton:
|
||||||
|
|||||||
@ -9,6 +9,7 @@ from reportlab.pdfgen import canvas
|
|||||||
from reportlab.lib.utils import ImageReader
|
from reportlab.lib.utils import ImageReader
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
import math
|
import math
|
||||||
|
from pyPhotoAlbum.models import ImageData, TextBoxData, PlaceholderData
|
||||||
|
|
||||||
|
|
||||||
class PDFExporter:
|
class PDFExporter:
|
||||||
@ -172,8 +173,6 @@ class PDFExporter:
|
|||||||
page_height_pt: Page height in points
|
page_height_pt: Page height in points
|
||||||
page_number: Current page number (for error messages)
|
page_number: Current page number (for error messages)
|
||||||
"""
|
"""
|
||||||
from pyPhotoAlbum.models import ImageData, TextBoxData, PlaceholderData
|
|
||||||
|
|
||||||
# Skip placeholders
|
# Skip placeholders
|
||||||
if isinstance(element, PlaceholderData):
|
if isinstance(element, PlaceholderData):
|
||||||
return
|
return
|
||||||
@ -219,8 +218,6 @@ class PDFExporter:
|
|||||||
page_number: Current page number
|
page_number: Current page number
|
||||||
side: 'left' or 'right'
|
side: 'left' or 'right'
|
||||||
"""
|
"""
|
||||||
from pyPhotoAlbum.models import ImageData, TextBoxData, PlaceholderData
|
|
||||||
|
|
||||||
# Skip placeholders
|
# Skip placeholders
|
||||||
if isinstance(element, PlaceholderData):
|
if isinstance(element, PlaceholderData):
|
||||||
return
|
return
|
||||||
|
|||||||
155
pyPhotoAlbum/text_edit_dialog.py
Normal file
155
pyPhotoAlbum/text_edit_dialog.py
Normal 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()
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user