V3.3.0 — Edition contenu, actions CLI, menu contextuel enrichi
- Edition de contenu PDF (Annotations > Editer le contenu) : - Onglet Texte : liste le texte detecte, masquer des lignes - Onglet Images : liste les images, remplacer ou masquer - Actions en ligne de commande (--action booklet_a4|booklet_a3|nup_2x2|unbooklet) - Menu contextuel Windows enrichi : - Ouvrir, Livret A4, Livret A3, 2x2 par feuille, Delivretiser - Bouton Editer dans la barre d'outils droite Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
110
app/dialogs/edit_content_dialog.py
Normal file
110
app/dialogs/edit_content_dialog.py
Normal file
@@ -0,0 +1,110 @@
|
||||
"""Dialogue Edition de contenu — texte et images existants."""
|
||||
|
||||
from PyQt6.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QLabel,
|
||||
QGroupBox, QListWidget, QListWidgetItem,
|
||||
QPushButton, QDialogButtonBox, QTextEdit,
|
||||
QFileDialog, QTabWidget, QWidget, QMessageBox)
|
||||
from PyQt6.QtCore import Qt
|
||||
|
||||
|
||||
class EditContentDialog(QDialog):
|
||||
def __init__(self, text_items=None, image_items=None, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setWindowTitle("Edition de contenu")
|
||||
self.setMinimumSize(500, 400)
|
||||
self._text_items = text_items or []
|
||||
self._image_items = image_items or []
|
||||
self._actions = [] # liste de {"type": "mask_text"|"replace_image", ...}
|
||||
self._setup_ui()
|
||||
|
||||
def _setup_ui(self):
|
||||
layout = QVBoxLayout(self)
|
||||
|
||||
tabs = QTabWidget()
|
||||
|
||||
# Onglet Texte
|
||||
text_tab = QWidget()
|
||||
tl = QVBoxLayout(text_tab)
|
||||
tl.addWidget(QLabel("Texte detecte sur la page (cliquez pour masquer) :"))
|
||||
self._text_list = QListWidget()
|
||||
for item in self._text_items:
|
||||
li = QListWidgetItem(item["text"])
|
||||
li.setData(Qt.ItemDataRole.UserRole, item)
|
||||
self._text_list.addItem(li)
|
||||
tl.addWidget(self._text_list)
|
||||
|
||||
btn_mask = QPushButton("Masquer le texte selectionne")
|
||||
btn_mask.clicked.connect(self._mask_text)
|
||||
tl.addWidget(btn_mask)
|
||||
|
||||
tabs.addTab(text_tab, "Texte")
|
||||
|
||||
# Onglet Images
|
||||
img_tab = QWidget()
|
||||
il = QVBoxLayout(img_tab)
|
||||
il.addWidget(QLabel("Images detectees sur la page :"))
|
||||
self._img_list = QListWidget()
|
||||
for item in self._image_items:
|
||||
li = QListWidgetItem(f"{item['name']} ({item['width']}x{item['height']})")
|
||||
li.setData(Qt.ItemDataRole.UserRole, item)
|
||||
self._img_list.addItem(li)
|
||||
il.addWidget(self._img_list)
|
||||
|
||||
btn_layout = QHBoxLayout()
|
||||
btn_replace = QPushButton("Remplacer par une image...")
|
||||
btn_replace.clicked.connect(self._replace_image)
|
||||
btn_layout.addWidget(btn_replace)
|
||||
btn_delete = QPushButton("Masquer cette image")
|
||||
btn_delete.clicked.connect(self._delete_image)
|
||||
btn_layout.addWidget(btn_delete)
|
||||
il.addLayout(btn_layout)
|
||||
|
||||
tabs.addTab(img_tab, "Images")
|
||||
|
||||
layout.addWidget(tabs)
|
||||
|
||||
# Actions en attente
|
||||
self._actions_label = QLabel("Actions en attente : 0")
|
||||
layout.addWidget(self._actions_label)
|
||||
|
||||
buttons = QDialogButtonBox(
|
||||
QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel
|
||||
)
|
||||
buttons.accepted.connect(self.accept)
|
||||
buttons.rejected.connect(self.reject)
|
||||
layout.addWidget(buttons)
|
||||
|
||||
def _mask_text(self):
|
||||
item = self._text_list.currentItem()
|
||||
if not item:
|
||||
return
|
||||
data = item.data(Qt.ItemDataRole.UserRole)
|
||||
self._actions.append({"type": "mask_text", "text": data["text"], "line_index": data["line_index"]})
|
||||
item.setForeground(Qt.GlobalColor.red)
|
||||
item.setText(f"[MASQUE] {data['text']}")
|
||||
self._actions_label.setText(f"Actions en attente : {len(self._actions)}")
|
||||
|
||||
def _replace_image(self):
|
||||
item = self._img_list.currentItem()
|
||||
if not item:
|
||||
return
|
||||
path, _ = QFileDialog.getOpenFileName(self, "Image de remplacement", "",
|
||||
"Images (*.png *.jpg *.jpeg *.bmp)")
|
||||
if path:
|
||||
data = item.data(Qt.ItemDataRole.UserRole)
|
||||
self._actions.append({"type": "replace_image", "name": data["name"], "new_path": path})
|
||||
item.setText(f"[REMPLACE] {data['name']}")
|
||||
self._actions_label.setText(f"Actions en attente : {len(self._actions)}")
|
||||
|
||||
def _delete_image(self):
|
||||
item = self._img_list.currentItem()
|
||||
if not item:
|
||||
return
|
||||
data = item.data(Qt.ItemDataRole.UserRole)
|
||||
self._actions.append({"type": "mask_image", "name": data["name"]})
|
||||
item.setForeground(Qt.GlobalColor.red)
|
||||
item.setText(f"[MASQUE] {data['name']}")
|
||||
self._actions_label.setText(f"Actions en attente : {len(self._actions)}")
|
||||
|
||||
def get_actions(self):
|
||||
return self._actions
|
||||
Reference in New Issue
Block a user