Files
copydev-imposing-tool/app/dialogs/manual_impose_dialog.py
Jules c9212a30ea V2.1.0 — Formats personnalises + reperes de coupe
- Formats personnalises dans tous les menus deroulants de format :
  - "Personnalise..." : saisie libre largeur x hauteur en mm
  - "Ajouter un format..." : sauvegarder un format custom (persistant)
  - Formats custom affiches dans le dropdown avec separateur
- Reperes de coupe (Annotations > Reperes de coupe) :
  - Longueur, distance du bord, epaisseur configurables
  - Couleur : noir, gris, CMYK
  - Reperes de centrage optionnels
  - Appliquer a : toutes, paires, impaires, page courante
  - Enlever les reperes de coupe (menu)
- Step & Repeat : ajout des marges (haut, bas, gauche, droite)
- Tous les dialogues de format migres vers format_combo

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 08:00:55 +01:00

108 lines
3.9 KiB
Python

"""Dialogue Imposition manuelle."""
from PyQt6.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QLabel,
QGroupBox, QComboBox, QSpinBox, QDoubleSpinBox,
QDialogButtonBox, QPushButton, QListWidget, QCheckBox)
from app.engine.pdf_utils import mm_to_pt
from app.dialogs.format_combo import populate_format_combo, get_selected_size, handle_format_selection
class ManualImposeDialog(QDialog):
def __init__(self, total_pages=1, parent=None):
super().__init__(parent)
self.setWindowTitle("Imposition manuelle")
self.setMinimumWidth(500)
self._total_pages = total_pages
self._placements = []
self._setup_ui()
def _setup_ui(self):
layout = QVBoxLayout(self)
grp_sheet = QGroupBox("Taille de la feuille cible")
sl = QHBoxLayout(grp_sheet)
sl.addWidget(QLabel("Format :"))
self.combo_sheet = QComboBox()
populate_format_combo(self.combo_sheet, "A3 Paysage")
self.combo_sheet.activated.connect(lambda: handle_format_selection(self.combo_sheet, self))
sl.addWidget(self.combo_sheet)
layout.addWidget(grp_sheet)
grp_place = QGroupBox("Placer une page")
pl = QHBoxLayout(grp_place)
pl.addWidget(QLabel("Page:"))
self.spin_page = QSpinBox()
self.spin_page.setRange(1, self._total_pages)
pl.addWidget(self.spin_page)
pl.addWidget(QLabel("X:"))
self.spin_x = QDoubleSpinBox()
self.spin_x.setRange(0, 2000)
self.spin_x.setSuffix(" mm")
pl.addWidget(self.spin_x)
pl.addWidget(QLabel("Y:"))
self.spin_y = QDoubleSpinBox()
self.spin_y.setRange(0, 2000)
self.spin_y.setSuffix(" mm")
pl.addWidget(self.spin_y)
pl.addWidget(QLabel("Rot:"))
self.combo_rot = QComboBox()
self.combo_rot.addItems(["0", "90", "180", "270"])
pl.addWidget(self.combo_rot)
pl.addWidget(QLabel("Ech:"))
self.spin_scale = QDoubleSpinBox()
self.spin_scale.setRange(0.1, 10.0)
self.spin_scale.setValue(1.0)
self.spin_scale.setSingleStep(0.1)
pl.addWidget(self.spin_scale)
layout.addWidget(grp_place)
btn_layout = QHBoxLayout()
btn_add = QPushButton("Ajouter")
btn_add.clicked.connect(self._add_placement)
btn_layout.addWidget(btn_add)
btn_del = QPushButton("Supprimer")
btn_del.clicked.connect(self._del_placement)
btn_layout.addWidget(btn_del)
btn_layout.addStretch()
layout.addLayout(btn_layout)
self.list_placements = QListWidget()
layout.addWidget(self.list_placements)
self.chk_crop = QCheckBox("Reperes de coupe")
layout.addWidget(self.chk_crop)
buttons = QDialogButtonBox(
QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel
)
buttons.accepted.connect(self.accept)
buttons.rejected.connect(self.reject)
layout.addWidget(buttons)
def _add_placement(self):
p = {
"page": self.spin_page.value(),
"x": mm_to_pt(self.spin_x.value()),
"y": mm_to_pt(self.spin_y.value()),
"rotation": int(self.combo_rot.currentText()),
"scale": self.spin_scale.value(),
}
self._placements.append(p)
self.list_placements.addItem(
f"Page {p['page']} — X={self.spin_x.value():.1f} Y={self.spin_y.value():.1f} mm "
f"Rot={self.combo_rot.currentText()} Ech={self.spin_scale.value():.1f}"
)
def _del_placement(self):
row = self.list_placements.currentRow()
if row >= 0:
self.list_placements.takeItem(row)
self._placements.pop(row)
def get_settings(self):
return {
"sheet_size": get_selected_size(self.combo_sheet),
"placements": self._placements,
"crop_marks": self.chk_crop.isChecked(),
}