From 9406de237dd3d7ade70f044c83d0dc48a2a75883 Mon Sep 17 00:00:00 2001 From: jessikitty Date: Mon, 12 Oct 2026 22:11:09 +1100 Subject: [PATCH] Keep tape options across the print redirect, honour saved rotation Printing redirected back to a bare tape page, so every option - rotation most visibly - reverted to the default the moment you pressed Print. Carry the chosen options through the redirect instead. Also read tape_rotate_default so an untick can be made permanent in Settings; it only applies to a fresh arrival, never over an explicit choice on the page. --- app/routes/labels_tape.py | 58 +++++++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/app/routes/labels_tape.py b/app/routes/labels_tape.py index 2862c3a..8e839ba 100644 --- a/app/routes/labels_tape.py +++ b/app/routes/labels_tape.py @@ -36,9 +36,38 @@ def printer_config(): or '/ipp/print'), 'format': (SiteSetting.get('tape_printer_format', '') or '').strip(), 'tape': SiteSetting.get('tape_default', tape_printer.DEFAULT_TAPE), + 'rotate': SiteSetting.get_bool('tape_rotate_default', True), } +def _options_query(options, labels): + """ + The chosen options as query args, so a redirect back to the tape page + comes back exactly as the user left it. Without this, printing bounced + you to a fresh page and every choice - rotation especially - reverted + to the default. + """ + query = { + 'ids': ','.join(str(l.id) for l in labels), + tape_printer.FORM_MARKER: '1', + 'tape': options.tape, + 'copies': options.copies, + 'font_scale': options.font_scale, + 'image_percent': options.image_percent, + 'padding_mm': options.padding_mm, + 'align': options.align, + 'fields': options.fields, + } + # Checkboxes: only present when on, which is what the parser expects. + if options.rotate: + query['rotate'] = '1' + if options.outline: + query['outline'] = '1' + if options.fixed_length_mm: + query['fixed_length_mm'] = options.fixed_length_mm + return query + + def _selected_labels(): """Resolve the selection from ids= or category=, same as sheet printing.""" ids = request.values.getlist('ids') @@ -69,10 +98,14 @@ def index(): flash('Select some labels to print first.', 'warning') return redirect(url_for('labels.index')) + config = printer_config() source = request.form if request.method == 'POST' else request.args - options = tape_printer.options_from_form(source) + # rotate_default only applies when the form was not submitted, so an + # explicit untick on the page always wins over the saved preference. + options = tape_printer.options_from_form( + source, rotate_default=config['rotate']) if not source.get('tape'): - options.tape = printer_config()['tape'] + options.tape = config['tape'] return render_template( 'admin/labels/tape.html', @@ -88,7 +121,7 @@ def index(): ('category_code', 'Category code'), ('location', 'Drawer'), ('colour', 'Colour name'), ('accent', 'Colour stripe'), ], - printer=printer_config(), + printer=config, ) @@ -100,7 +133,8 @@ def preview(): if not label_id: abort(400, 'preview.png needs an ?id= of a label.') label = PartLabel.query.get_or_404(label_id) - options = tape_printer.options_from_form(request.args) + options = tape_printer.options_from_form( + request.args, rotate_default=printer_config()['rotate']) buffer = tape_printer.preview_png( label, options, current_app.config['UPLOAD_FOLDER']) return send_file(buffer, mimetype='image/png') @@ -151,8 +185,9 @@ def print_tape(): flash('Nothing selected to print.', 'warning') return redirect(url_for('labels.index')) - options = tape_printer.options_from_form(request.form) config = printer_config() + options = tape_printer.options_from_form( + request.form, rotate_default=config['rotate']) host = config['host'] if not host: flash('No tape printer address configured. Set it in Label ' @@ -169,13 +204,13 @@ def print_tape(): mime_type = info.get('usable_format') except ipp_client.IPPError as exc: flash(f'Could not reach the printer: {exc}', 'danger') - return redirect(url_for('tape.index', ids=','.join( - str(l.id) for l in labels))) + return redirect(url_for('tape.index', + **_options_query(options, labels))) if not mime_type: flash('The printer did not offer a format LIM can produce. Use ' 'Download PDF instead.', 'warning') return redirect(url_for('tape.index', - ids=','.join(str(l.id) for l in labels))) + **_options_query(options, labels))) upload_folder = current_app.config['UPLOAD_FOLDER'] sent = 0 @@ -205,9 +240,7 @@ def print_tape(): for problem in failures[:5]: flash(problem, 'danger') - return redirect(url_for('tape.index', - ids=','.join(str(l.id) for l in labels), - tape=options.tape)) + return redirect(url_for('tape.index', **_options_query(options, labels))) @tape_bp.route('/download.pdf', methods=['GET', 'POST']) @@ -221,7 +254,8 @@ def download_pdf(): return redirect(url_for('labels.index')) source = request.form if request.method == 'POST' else request.args - options = tape_printer.options_from_form(source) + options = tape_printer.options_from_form( + source, rotate_default=printer_config()['rotate']) buffer = tape_printer.render_batch_pdf( labels, options, current_app.config['UPLOAD_FOLDER']) if buffer is None: