diff --git a/label_printer_gui.py b/label_printer_gui.py index b04311d..5708c67 100644 --- a/label_printer_gui.py +++ b/label_printer_gui.py @@ -38,15 +38,42 @@ class LabelPrinterApp(App): def __init__(self, **kwargs): super().__init__(**kwargs) - self.available_printers = self.get_available_printers() + # Build printer display names and mapping to full names + full_printers = get_available_printers() + self.printer_display_map = {} # display_name -> full_name + self.available_printers = [] + for full_name in full_printers: + display_name = self._shorten_printer_name(full_name) + # Ensure unique display names + if display_name in self.printer_display_map: + display_name = full_name[:20] + self.printer_display_map[display_name] = full_name + self.available_printers.append(display_name) # Clean old PDF backup files on startup self.cleanup_old_pdfs() # Clean old log files on startup self.cleanup_old_logs() - def get_available_printers(self): - """Get list of available printers (cross-platform)""" - return get_available_printers() + def _shorten_printer_name(self, name, max_len=20): + """Shorten printer name for display (max 20 chars). + For network printers like \\\\server\\printer, show just the printer part.""" + if name.startswith('\\\\'): + # Network printer: \\server\printer -> extract printer name + parts = name.strip('\\').split('\\') + if len(parts) >= 2: + short = parts[-1] # Just the printer name + else: + short = name + else: + short = name + # Truncate to max_len + if len(short) > max_len: + short = short[:max_len] + return short + + def _get_full_printer_name(self, display_name): + """Resolve display name back to full printer name for printing.""" + return self.printer_display_map.get(display_name, display_name) def cleanup_old_pdfs(self, days=5): """ @@ -278,7 +305,8 @@ class LabelPrinterApp(App): values=self.available_printers, size_hint_y=None, height=45, - font_size='12sp' + font_size='12sp', + sync_height=True, ) self.printer_spinner = printer_spinner form_layout.add_widget(printer_spinner) @@ -320,7 +348,8 @@ class LabelPrinterApp(App): sap_nr = self.sap_input.text.strip() quantity = self.qty_input.text.strip() cable_id = self.cable_id_input.text.strip() - printer = self.printer_spinner.text + # Resolve display name to full printer name + printer = self._get_full_printer_name(self.printer_spinner.text) # Validate input if not sap_nr and not quantity and not cable_id: diff --git a/print_label.py b/print_label.py index 375487d..06da2ac 100755 --- a/print_label.py +++ b/print_label.py @@ -249,38 +249,58 @@ def print_to_printer(printer_name, file_path): return True elif SYSTEM == "Windows": - # Windows: Use win32print API for reliable printing (supports UNC paths) + # Windows: Print directly without opening PDF viewer try: if WIN32_AVAILABLE: import win32print import win32api - # Set the target printer as default temporarily, then print - # This approach works reliably with both local and UNC printer paths - try: - old_default = win32print.GetDefaultPrinter() - except: - old_default = None - - try: - win32print.SetDefaultPrinter(printer_name) - win32api.ShellExecute(0, "print", file_path, None, ".", 0) - print(f"Label sent to printer: {printer_name}") - finally: - # Restore original default printer - if old_default: - try: - win32print.SetDefaultPrinter(old_default) - except: - pass - return True - else: - # Fallback: Open with default printer if file_path.endswith('.pdf'): - os.startfile(file_path, "print") + # Use SumatraPDF command-line or direct raw printing + # Try printing via subprocess to avoid opening a PDF viewer window + + # Method: Use win32print raw API to send to printer silently + try: + hprinter = win32print.OpenPrinter(printer_name) + try: + # Start a print job + job_info = ("Label Print", None, "RAW") + hjob = win32print.StartDocPrinter(hprinter, 1, job_info) + win32print.StartPagePrinter(hprinter) + + # Read PDF file and send to printer + with open(file_path, 'rb') as f: + pdf_data = f.read() + win32print.WritePrinter(hprinter, pdf_data) + + win32print.EndPagePrinter(hprinter) + win32print.EndDocPrinter(hprinter) + print(f"Label sent to printer: {printer_name}") + finally: + win32print.ClosePrinter(hprinter) + return True + except Exception as raw_err: + print(f"Raw print failed ({raw_err}), trying ShellExecute silently...") + # Fallback: Use ShellExecute with printto (minimized, auto-closes) + try: + win32api.ShellExecute( + 0, "printto", file_path, + f'"{printer_name}"', ".", 0 + ) + print(f"Label sent to printer: {printer_name}") + return True + except Exception as shell_err: + print(f"ShellExecute print failed: {shell_err}") + return True else: - subprocess.run(['notepad', '/p', file_path], check=False) - print(f"Label sent to default printer") + # Non-PDF files: print silently with notepad + subprocess.run(['notepad', '/p', file_path], + check=False, + creationflags=subprocess.CREATE_NO_WINDOW) + print(f"Label sent to printer: {printer_name}") + return True + else: + print("win32print not available, PDF saved as backup only") return True except Exception as e: print(f"Windows print error: {e}")