From adecf1f281e345883e526b1c0c9b3d129e845a92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Miquel?= Date: Wed, 11 Mar 2026 07:41:22 +0100 Subject: [PATCH] Add `P'revious support to page_splitter. --- gemini_for_labels.py | 2 +- page_splitter.py | 43 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/gemini_for_labels.py b/gemini_for_labels.py index 5e77b64..a02383e 100644 --- a/gemini_for_labels.py +++ b/gemini_for_labels.py @@ -306,7 +306,7 @@ def process_copy_group(group_key, files): # Run ThreadPool on GROUPS (Copies), not individual files # Each thread handles one student's full exam copy sequentially -with ThreadPoolExecutor(max_workers=6) as executor: +with ThreadPoolExecutor(max_workers=8) as executor: # Convert dict items to arguments for map # executor.map expects a function and an iterable. # We use a lambda or separate function to unpack the tuple if needed, diff --git a/page_splitter.py b/page_splitter.py index 1e51da3..c290815 100644 --- a/page_splitter.py +++ b/page_splitter.py @@ -79,6 +79,7 @@ class PDFPreviewer: self.master = master self.num = 0 self.global_rotation = 0 # Rotation appliquée à tous les fichiers + self.history = [] self.setup_next_file() self._resize_job = None # For debouncing resize events @@ -93,7 +94,7 @@ class PDFPreviewer: "← / → : Move line 1cm left/right\n" "'c': Rotate page 180°, 'C' : rotate all pages, ',' : rotate all files\n" "t s r n: keep left, next page, keep none, keep right\n" - "z: send this page to the end, 'R':restart file\n" + "z: send this page to the end, 'R':restart file, 'P':back to previous file\n" ) self.info_label = tk.Label(master, text=instructions, justify=tk.LEFT) self.info_label.pack(pady=5, side=tk.TOP) @@ -120,7 +121,8 @@ class PDFPreviewer: self.master.bind("s", self.confirm_and_next_page) self.master.bind("r", self.discard_page) self.master.bind("z", self.send_page_end) - self.master.bind("R", self.restart_current_file) # New binding + self.master.bind("R", self.restart_current_file) + self.master.bind("P", self.go_to_previous_file) # Bind the resize event on the canvas @@ -280,6 +282,7 @@ class PDFPreviewer: self.load_page() else: self.finish_and_process() + self.history.append(self.pdf_path) if self.setup_next_file(): self._initialize_current_page_settings() self.load_page() @@ -323,6 +326,42 @@ class PDFPreviewer: self.remove_dirs() + def _restore_original(self, path): + """Restores the original file from the 'Copies Originales' backup.""" + dir_name = os.path.dirname(os.path.abspath(path)) + file_name = os.path.basename(path) + backup_path = os.path.join(dir_name, "Copies Originales", file_name) + + if os.path.exists(backup_path): + try: + # Moving overwrites the generated PDF with the original backup + shutil.move(backup_path, path) + print(f"Restored original file from: {backup_path}") + except Exception as e: + print(f"Failed to restore original file: {e}") + + def go_to_previous_file(self, event=None): + """Goes back to the beginning of the previously completed file.""" + if not self.history: + return # Nowhere to go back to + + # Close the currently open document to avoid lock issues + if hasattr(self, 'doc'): + self.doc.close() + + # 1. Push current file back onto the stack so it processes next + self.inputs.append(self.pdf_path) + + # 2. Get the previous file, restore its original state, and push to stack + prev_file = self.history.pop() + self._restore_original(prev_file) + self.inputs.append(prev_file) + + # 3. Reload environment (setup_next_file will pop prev_file back off the stack) + self.setup_next_file() + self._initialize_current_page_settings() + self.load_page() + def split_filename_left(self, i): return os.path.join(self.split_dir, f"{self.base_name}_{i+1}l.pdf") def split_filename_right(self, i):