V3.0.0 — Rotation, Annuler/Refaire, Delivretiser, Trim&Shift, Inverser

- Rotation de pages : clic droit sur vignette → Pivoter +90/-90/180
  Aussi dans le menu Pages
- Ctrl+Z / Ctrl+Y : annuler et refaire (pile de 20 etats)
- Delivretiser : coupe les pages en 2 et remet dans l'ordre sequentiel
  (inverse de la creation de livret)
- Trim & Shift : decaler le contenu des pages
  - Decalage X/Y different pages paires/impaires
  - Compensation de creep progressive pour livrets epais
- Inverser l'ordre des pages (menu Pages)
- Fix impression : ouvre le PDF dans le lecteur par defaut
- Barre outils droite : ajout Delivretiser, Trim/Shift, Inverser

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jules
2026-03-21 16:02:07 +01:00
parent cee86f5c03
commit 673d76caa2
7 changed files with 364 additions and 12 deletions

View File

@@ -0,0 +1,84 @@
"""Dialogue Trim & Shift."""
from PyQt6.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QLabel,
QGroupBox, QDoubleSpinBox, QCheckBox,
QDialogButtonBox)
from app.engine.pdf_utils import mm_to_pt
class TrimShiftDialog(QDialog):
def __init__(self, total_pages=1, parent=None):
super().__init__(parent)
self.setWindowTitle("Trim && Shift — Decaler le contenu")
self.setMinimumWidth(420)
self._total_pages = total_pages
self._setup_ui()
def _setup_ui(self):
layout = QVBoxLayout(self)
# Decalage pages impaires
grp_odd = QGroupBox("Decalage pages impaires (mm)")
ol = QHBoxLayout(grp_odd)
ol.addWidget(QLabel("X :"))
self.spin_x = QDoubleSpinBox()
self.spin_x.setRange(-200, 200)
self.spin_x.setSuffix(" mm")
ol.addWidget(self.spin_x)
ol.addWidget(QLabel("Y :"))
self.spin_y = QDoubleSpinBox()
self.spin_y.setRange(-200, 200)
self.spin_y.setSuffix(" mm")
ol.addWidget(self.spin_y)
layout.addWidget(grp_odd)
# Pages paires differentes
self.chk_different = QCheckBox("Decalage different pour pages paires")
layout.addWidget(self.chk_different)
grp_even = QGroupBox("Decalage pages paires (mm)")
el = QHBoxLayout(grp_even)
el.addWidget(QLabel("X :"))
self.spin_x_even = QDoubleSpinBox()
self.spin_x_even.setRange(-200, 200)
self.spin_x_even.setSuffix(" mm")
self.spin_x_even.setEnabled(False)
el.addWidget(self.spin_x_even)
el.addWidget(QLabel("Y :"))
self.spin_y_even = QDoubleSpinBox()
self.spin_y_even.setRange(-200, 200)
self.spin_y_even.setSuffix(" mm")
self.spin_y_even.setEnabled(False)
el.addWidget(self.spin_y_even)
layout.addWidget(grp_even)
self.chk_different.toggled.connect(self.spin_x_even.setEnabled)
self.chk_different.toggled.connect(self.spin_y_even.setEnabled)
# Creep
grp_creep = QGroupBox("Compensation de creep (livrets)")
cl = QHBoxLayout(grp_creep)
cl.addWidget(QLabel("Creep max :"))
self.spin_creep = QDoubleSpinBox()
self.spin_creep.setRange(0, 20)
self.spin_creep.setSuffix(" mm")
self.spin_creep.setToolTip("Decalage progressif pour compenser l'epaisseur du papier")
cl.addWidget(self.spin_creep)
layout.addWidget(grp_creep)
buttons = QDialogButtonBox(
QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel
)
buttons.accepted.connect(self.accept)
buttons.rejected.connect(self.reject)
layout.addWidget(buttons)
def get_settings(self):
return {
"shift_x": mm_to_pt(self.spin_x.value()),
"shift_y": mm_to_pt(self.spin_y.value()),
"shift_x_even": mm_to_pt(self.spin_x_even.value()) if self.chk_different.isChecked() else None,
"shift_y_even": mm_to_pt(self.spin_y_even.value()) if self.chk_different.isChecked() else None,
"creep": mm_to_pt(self.spin_creep.value()),
"creep_pages": self._total_pages,
}