Fix: unticking "Rotate for tape feed" had no effect
An unticked checkbox is absent from a form submission entirely, so "rotate unticked" and "rotate never mentioned" arrived at the parser looking identical - and rotate defaults to on, so it snapped straight back every time. Add a hidden marker the options form always sends, so absent-but-submitted can be read as unticked. Same bug silently reset the field list when every field was unticked; that is fixed by the same marker. rotate_default lets a saved site-wide preference apply on a fresh arrival without overriding an explicit untick on the page.
This commit is contained in:
1 parent
bad4787e00
commit
4a1bfc4acd
1 file changed
+39
-13
@@ -14,9 +14,9 @@ VC-500W facts this is built around:
|
|||||||
|
|
||||||
ORIENTATION: the tape feeds lengthwise, so the raster sent to the printer is
|
ORIENTATION: the tape feeds lengthwise, so the raster sent to the printer is
|
||||||
normally rotated 90 degrees - the image is tape-width across and
|
normally rotated 90 degrees - the image is tape-width across and
|
||||||
label-length tall. That is the default. If your first test print comes out
|
label-length tall. That is the default. If your prints come out sideways,
|
||||||
sideways, untick "Rotate for tape feed" and print again; it is the one
|
untick "Rotate for tape feed"; to make that permanent, turn off the default
|
||||||
setting worth checking on a new printer.
|
orientation in Label Settings.
|
||||||
|
|
||||||
Created by: Jess Rogerson (yelling commands at Claude.AI)
|
Created by: Jess Rogerson (yelling commands at Claude.AI)
|
||||||
"""
|
"""
|
||||||
@@ -73,6 +73,16 @@ TAPE_PRESETS = {
|
|||||||
|
|
||||||
DEFAULT_TAPE = 'cz25'
|
DEFAULT_TAPE = 'cz25'
|
||||||
|
|
||||||
|
# What a label shows when you have not said otherwise. Defined once: the
|
||||||
|
# dataclass default and the form parser both read it, so they cannot drift.
|
||||||
|
DEFAULT_TAPE_FIELDS = ['image', 'name', 'dimensions', 'part_number', 'accent']
|
||||||
|
|
||||||
|
# Hidden marker every options form submits. Its presence is how we tell
|
||||||
|
# "submitted with the box unticked" from "arrived here with no options at
|
||||||
|
# all" - an unticked checkbox sends nothing, so without this they look
|
||||||
|
# identical and a default-on box can never be turned off.
|
||||||
|
FORM_MARKER = '_opts'
|
||||||
|
|
||||||
FONT_CANDIDATES = {
|
FONT_CANDIDATES = {
|
||||||
False: [ # regular
|
False: [ # regular
|
||||||
'C:\\Windows\\Fonts\\segoeui.ttf',
|
'C:\\Windows\\Fonts\\segoeui.ttf',
|
||||||
@@ -114,8 +124,8 @@ def load_font(size_px, bold=False):
|
|||||||
@dataclass
|
@dataclass
|
||||||
class TapeOptions:
|
class TapeOptions:
|
||||||
tape: str = DEFAULT_TAPE
|
tape: str = DEFAULT_TAPE
|
||||||
fields: List[str] = field(default_factory=lambda: [
|
fields: List[str] = field(
|
||||||
'image', 'name', 'dimensions', 'part_number', 'accent'])
|
default_factory=lambda: list(DEFAULT_TAPE_FIELDS))
|
||||||
rotate: bool = True
|
rotate: bool = True
|
||||||
copies: int = 1
|
copies: int = 1
|
||||||
# Fixed length in mm, or None to size each label to its content.
|
# Fixed length in mm, or None to size each label to its content.
|
||||||
@@ -131,8 +141,21 @@ def get_tape(key):
|
|||||||
return TAPE_PRESETS.get(key or DEFAULT_TAPE, TAPE_PRESETS[DEFAULT_TAPE])
|
return TAPE_PRESETS.get(key or DEFAULT_TAPE, TAPE_PRESETS[DEFAULT_TAPE])
|
||||||
|
|
||||||
|
|
||||||
def options_from_form(form):
|
def options_from_form(form, rotate_default=True):
|
||||||
"""Build TapeOptions from request.form / request.args."""
|
"""
|
||||||
|
Build TapeOptions from request.form / request.args.
|
||||||
|
|
||||||
|
An unticked checkbox is simply absent from a form submission - the
|
||||||
|
browser sends nothing for it. So "rotate unticked" and "rotate never
|
||||||
|
mentioned" arrive here looking exactly the same, and a box that
|
||||||
|
defaults to on could never be turned off. FORM_MARKER is a hidden
|
||||||
|
field the options form always sends: when it is present we know every
|
||||||
|
checkbox was on screen, so absent means the user unticked it.
|
||||||
|
|
||||||
|
rotate_default applies only when the form was NOT submitted (a fresh
|
||||||
|
arrival), so the saved site-wide preference is honoured there.
|
||||||
|
"""
|
||||||
|
submitted = FORM_MARKER in form
|
||||||
|
|
||||||
def number(key, default, cast=float):
|
def number(key, default, cast=float):
|
||||||
try:
|
try:
|
||||||
@@ -141,11 +164,15 @@ def options_from_form(form):
|
|||||||
return default
|
return default
|
||||||
|
|
||||||
def flag(key, default=False):
|
def flag(key, default=False):
|
||||||
if key not in form:
|
if key in form:
|
||||||
return default
|
|
||||||
return str(form.get(key, '')).lower() in ('1', 'true', 'on', 'yes')
|
return str(form.get(key, '')).lower() in ('1', 'true', 'on', 'yes')
|
||||||
|
# Submitted without it: the user unticked it. Not submitted: default.
|
||||||
|
return False if submitted else default
|
||||||
|
|
||||||
|
fields = list(form.getlist('fields')) if hasattr(form, 'getlist') else []
|
||||||
|
if not fields and not submitted:
|
||||||
|
fields = list(DEFAULT_TAPE_FIELDS)
|
||||||
|
|
||||||
fields = form.getlist('fields') if hasattr(form, 'getlist') else None
|
|
||||||
length = (form.get('fixed_length_mm') or '').strip() if hasattr(form, 'get') else ''
|
length = (form.get('fixed_length_mm') or '').strip() if hasattr(form, 'get') else ''
|
||||||
try:
|
try:
|
||||||
fixed = float(length) if length else None
|
fixed = float(length) if length else None
|
||||||
@@ -154,9 +181,8 @@ def options_from_form(form):
|
|||||||
|
|
||||||
return TapeOptions(
|
return TapeOptions(
|
||||||
tape=form.get('tape') or DEFAULT_TAPE,
|
tape=form.get('tape') or DEFAULT_TAPE,
|
||||||
fields=fields if fields else ['image', 'name', 'dimensions',
|
fields=fields,
|
||||||
'part_number', 'accent'],
|
rotate=flag('rotate', rotate_default),
|
||||||
rotate=flag('rotate', True),
|
|
||||||
copies=max(1, min(99, number('copies', 1, int))),
|
copies=max(1, min(99, number('copies', 1, int))),
|
||||||
fixed_length_mm=fixed,
|
fixed_length_mm=fixed,
|
||||||
padding_mm=max(0.0, min(10.0, number('padding_mm', 1.5))),
|
padding_mm=max(0.0, min(10.0, number('padding_mm', 1.5))),
|
||||||
|
|||||||
Reference in new issue
Block a user