Outil d'imposition PDF desktop (PyQt6) remplacant Quite Imposing Plus. 9 fonctions : livret, n-up, step & repeat, imposition manuelle, jointure pages, pages blanches, numerotation, masquage, fonds perdus. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
132 lines
4.8 KiB
Python
132 lines
4.8 KiB
Python
"""Dialogue N pages par feuille."""
|
|
|
|
from PyQt6.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QLabel,
|
|
QComboBox, QGroupBox, QSpinBox, QCheckBox,
|
|
QDialogButtonBox, QDoubleSpinBox, QFileDialog)
|
|
from app.engine.pdf_utils import PAGE_SIZES, mm_to_pt
|
|
|
|
|
|
class NupDialog(QDialog):
|
|
def __init__(self, parent=None):
|
|
super().__init__(parent)
|
|
self.setWindowTitle("N pages par feuille")
|
|
self.setMinimumWidth(450)
|
|
self._bg_path = None
|
|
self._setup_ui()
|
|
|
|
def _setup_ui(self):
|
|
layout = QVBoxLayout(self)
|
|
|
|
# Grille
|
|
grp_grid = QGroupBox("Disposition")
|
|
gl = QHBoxLayout(grp_grid)
|
|
gl.addWidget(QLabel("Colonnes :"))
|
|
self.spin_cols = QSpinBox()
|
|
self.spin_cols.setRange(1, 10)
|
|
self.spin_cols.setValue(2)
|
|
gl.addWidget(self.spin_cols)
|
|
gl.addWidget(QLabel("Lignes :"))
|
|
self.spin_rows = QSpinBox()
|
|
self.spin_rows.setRange(1, 10)
|
|
self.spin_rows.setValue(2)
|
|
gl.addWidget(self.spin_rows)
|
|
layout.addWidget(grp_grid)
|
|
|
|
# Taille feuille
|
|
grp_sheet = QGroupBox("Taille de la feuille")
|
|
sl = QHBoxLayout(grp_sheet)
|
|
sl.addWidget(QLabel("Format :"))
|
|
self.combo_sheet = QComboBox()
|
|
for name in PAGE_SIZES:
|
|
self.combo_sheet.addItem(name)
|
|
self.combo_sheet.setCurrentText("A4 Paysage")
|
|
sl.addWidget(self.combo_sheet)
|
|
layout.addWidget(grp_sheet)
|
|
|
|
# Marges
|
|
grp_margins = QGroupBox("Marges (mm)")
|
|
ml = QHBoxLayout(grp_margins)
|
|
self.margins = {}
|
|
for label in ["Haut", "Bas", "Gauche", "Droite"]:
|
|
ml.addWidget(QLabel(f"{label}:"))
|
|
spin = QDoubleSpinBox()
|
|
spin.setRange(0, 100)
|
|
spin.setValue(5)
|
|
spin.setSuffix(" mm")
|
|
ml.addWidget(spin)
|
|
self.margins[label.lower()] = spin
|
|
layout.addWidget(grp_margins)
|
|
|
|
# Gouttiere
|
|
grp_gutter = QGroupBox("Gouttiere (mm)")
|
|
gutl = QHBoxLayout(grp_gutter)
|
|
gutl.addWidget(QLabel("Horizontale :"))
|
|
self.spin_gutter_h = QDoubleSpinBox()
|
|
self.spin_gutter_h.setRange(0, 50)
|
|
self.spin_gutter_h.setValue(0)
|
|
self.spin_gutter_h.setSuffix(" mm")
|
|
gutl.addWidget(self.spin_gutter_h)
|
|
gutl.addWidget(QLabel("Verticale :"))
|
|
self.spin_gutter_v = QDoubleSpinBox()
|
|
self.spin_gutter_v.setRange(0, 50)
|
|
self.spin_gutter_v.setValue(0)
|
|
self.spin_gutter_v.setSuffix(" mm")
|
|
gutl.addWidget(self.spin_gutter_v)
|
|
layout.addWidget(grp_gutter)
|
|
|
|
# Options
|
|
grp_opts = QGroupBox("Options")
|
|
ol = QVBoxLayout(grp_opts)
|
|
self.chk_fit = QCheckBox("Ajuster les pages a la cellule")
|
|
self.chk_fit.setChecked(True)
|
|
ol.addWidget(self.chk_fit)
|
|
self.chk_crop = QCheckBox("Reperes de coupe")
|
|
ol.addWidget(self.chk_crop)
|
|
|
|
bg_layout = QHBoxLayout()
|
|
self.chk_bg = QCheckBox("Fond PDF :")
|
|
bg_layout.addWidget(self.chk_bg)
|
|
self.lbl_bg = QLabel("Aucun")
|
|
bg_layout.addWidget(self.lbl_bg)
|
|
from PyQt6.QtWidgets import QPushButton
|
|
btn_bg = QPushButton("Choisir...")
|
|
btn_bg.clicked.connect(self._choose_bg)
|
|
bg_layout.addWidget(btn_bg)
|
|
bg_layout.addStretch()
|
|
ol.addLayout(bg_layout)
|
|
|
|
layout.addWidget(grp_opts)
|
|
|
|
# Boutons
|
|
buttons = QDialogButtonBox(
|
|
QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel
|
|
)
|
|
buttons.accepted.connect(self.accept)
|
|
buttons.rejected.connect(self.reject)
|
|
layout.addWidget(buttons)
|
|
|
|
def _choose_bg(self):
|
|
path, _ = QFileDialog.getOpenFileName(self, "Choisir un fond PDF", "", "PDF (*.pdf)")
|
|
if path:
|
|
self._bg_path = path
|
|
self.lbl_bg.setText(path.split("/")[-1].split("\\")[-1])
|
|
self.chk_bg.setChecked(True)
|
|
|
|
def get_settings(self):
|
|
sheet_text = self.combo_sheet.currentText()
|
|
sheet_size = PAGE_SIZES[sheet_text]
|
|
return {
|
|
"cols": self.spin_cols.value(),
|
|
"rows": self.spin_rows.value(),
|
|
"sheet_size": sheet_size,
|
|
"margin_top": mm_to_pt(self.margins["haut"].value()),
|
|
"margin_bottom": mm_to_pt(self.margins["bas"].value()),
|
|
"margin_left": mm_to_pt(self.margins["gauche"].value()),
|
|
"margin_right": mm_to_pt(self.margins["droite"].value()),
|
|
"gutter_h": mm_to_pt(self.spin_gutter_h.value()),
|
|
"gutter_v": mm_to_pt(self.spin_gutter_v.value()),
|
|
"scale_mode": "fit" if self.chk_fit.isChecked() else "none",
|
|
"crop_marks": self.chk_crop.isChecked(),
|
|
"background_path": self._bg_path if self.chk_bg.isChecked() else None,
|
|
}
|