diff --git a/app/dialogs/crop_dialog.py b/app/dialogs/crop_dialog.py index 239a6d1..075d383 100644 --- a/app/dialogs/crop_dialog.py +++ b/app/dialogs/crop_dialog.py @@ -9,7 +9,7 @@ from app.engine.pdf_utils import mm_to_pt, pt_to_mm class CropDialog(QDialog): def __init__(self, page_width_pt=595, page_height_pt=842, total_pages=1, - current_page=0, viewer=None, parent=None): + current_page=0, viewer=None, existing_crop=None, parent=None): super().__init__(parent) self.setWindowTitle("Recadrer") self.setFixedWidth(360) @@ -20,7 +20,9 @@ class CropDialog(QDialog): self._total_pages = total_pages self._current_page = current_page self._viewer = viewer + self._existing_crop = existing_crop self._setup_ui() + self._apply_existing_crop() self._update_preview() def _setup_ui(self): @@ -196,6 +198,22 @@ class CropDialog(QDialog): spin.blockSignals(False) self._update_preview() + def _apply_existing_crop(self): + """Pre-remplir les marges si on a un crop existant.""" + if not self._existing_crop: + return + from app.engine.pdf_utils import pt_to_mm + for spin in self.margin_spins.values(): + spin.blockSignals(True) + self.margin_spins["haut"].setValue(pt_to_mm(self._existing_crop.get("crop_top", 0))) + self.margin_spins["bas"].setValue(pt_to_mm(self._existing_crop.get("crop_bottom", 0))) + self.margin_spins["gauche"].setValue(pt_to_mm(self._existing_crop.get("crop_left", 0))) + self.margin_spins["droite"].setValue(pt_to_mm(self._existing_crop.get("crop_right", 0))) + for spin in self.margin_spins.values(): + spin.blockSignals(False) + # Afficher le cadre sur le viewer + self._show_selection_from_margins() + def _on_selection_changed(self, left, top, right, bottom): """Recoit les ratios de selection du viewer et met a jour les marges.""" if not self.rb_margins.isChecked(): diff --git a/app/main_window.py b/app/main_window.py index ca124b5..0cc0c34 100644 --- a/app/main_window.py +++ b/app/main_window.py @@ -56,6 +56,8 @@ class MainWindow(QMainWindow): self._current_file = None self._result_file = None + self._original_file = None # fichier avant crop (pour recadrage non-destructif) + self._crop_settings = {} # {page_index: {top, bottom, left, right} en pt} # Drag & drop self.setAcceptDrops(True) @@ -444,11 +446,12 @@ class MainWindow(QMainWindow): def _open_pdf(self, path): self._current_file = path self._result_file = None + self._original_file = path # reset l'original + self._crop_settings = {} # reset les crops self._viewer.load_pdf(path) self._page_panel.load_thumbnails(self._viewer) self._file_label.setText(os.path.basename(path)) self._status_label.setText(f"Fichier charge : {os.path.basename(path)}") - # Ajuster apres affichage QTimer.singleShot(100, self._viewer.zoom_fit) def _save_result(self): @@ -701,15 +704,30 @@ class MainWindow(QMainWindow): if not self._require_file(): return from pypdf import PdfReader - from app.engine.pdf_utils import get_page_size - reader = PdfReader(self._current_file) - page = reader.pages[self._viewer.current_page] + from app.engine.pdf_utils import get_page_size, pt_to_mm + + # Toujours travailler depuis l'original pour permettre la re-edition + source = self._original_file or self._current_file + reader = PdfReader(source) + cur_page = self._viewer.current_page + page = reader.pages[cur_page] w, h = get_page_size(page) + + # Recharger l'original dans le viewer pour voir la page entiere + self._viewer.load_pdf(source) + self._viewer.go_to_page(cur_page) + self._page_panel.load_thumbnails(self._viewer) + QApplication.processEvents() + + # Si on a des settings de crop existants pour cette page, pre-remplir + existing = self._crop_settings.get(cur_page, None) + self._crop_dlg = CropDialog( page_width_pt=w, page_height_pt=h, total_pages=len(reader.pages), - current_page=self._viewer.current_page, + current_page=cur_page, viewer=self._viewer, + existing_crop=existing, parent=self ) @@ -724,30 +742,59 @@ class MainWindow(QMainWindow): return if not settings.get("pages"): return + + # Sauvegarder les settings de crop par page + for pg in settings["pages"]: + self._crop_settings[pg] = { + "crop_top": settings["crop_top"], + "crop_bottom": settings["crop_bottom"], + "crop_left": settings["crop_left"], + "crop_right": settings["crop_right"], + } + + # Appliquer le crop depuis l'original self._show_progress() + source_file = self._original_file or self._current_file output = self._make_temp() try: - crop_pages(self._current_file, output, **settings) - self._show_result(output) + crop_pages(source_file, output, **settings) + self._result_file = output + self._current_file = output + self._viewer.load_pdf(output) + self._viewer.go_to_page(cur_page) + self._page_panel.load_thumbnails(self._viewer) + self._hide_progress() self._status_label.setText( f"Recadrage applique — {len(settings['pages'])} page(s)" ) + QTimer.singleShot(100, self._viewer.zoom_fit) except Exception as e: self._hide_progress() QMessageBox.critical(self, "Erreur", str(e)) + def on_crop_rejected(): + # Revenir au fichier actuel (croppe ou non) + current = self._current_file + self._viewer.load_pdf(current) + self._viewer.go_to_page(cur_page) + self._page_panel.load_thumbnails(self._viewer) + self._crop_dlg = None + self._crop_dlg.accepted.connect(on_crop_accepted) - self._crop_dlg.rejected.connect(lambda: setattr(self, '_crop_dlg', None)) + self._crop_dlg.rejected.connect(on_crop_rejected) self._crop_dlg.show() def _do_print(self): if not self._require_file(): return - import subprocess try: source = self._result_file or self._current_file - subprocess.Popen(["cmd", "/c", "start", "", source], shell=True) - self._status_label.setText("Ouverture pour impression...") + if sys.platform == "win32": + os.startfile(source, "print") + else: + import subprocess + subprocess.Popen(["lp", source]) + self._status_label.setText("Impression lancee...") except Exception as e: QMessageBox.critical(self, "Erreur", f"Impossible d'imprimer :\n{e}") diff --git a/app/updater.py b/app/updater.py index 958f498..802ea38 100644 --- a/app/updater.py +++ b/app/updater.py @@ -14,7 +14,7 @@ REPO = "jules/copydev-imposing-tool" BRANCH = "master" # Version actuelle (incrementee a chaque release) -VERSION = "2.5.2" +VERSION = "2.6.0" def get_remote_version(): diff --git a/version.txt b/version.txt index f225a78..e70b452 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -2.5.2 +2.6.0