[Feature/Medium] Stage 2: Add paper size and print quality selection to printer details #183

Open
opened 2026-09-15 10:20:29 +01:00 by gronod · 2 comments
Owner

Summary

Stage 2 printer details selection allows selection of the printer, media type, and orientation, but not quality or paper size settings from the ICCery screen. The paper size should follow the setting selected at the top of Stage 1 (defaults to A4) and default to portrait orientation. Print quality options should be populated from the printer's capabilities (lpoptions -l / PPD).

Spec refs

  • 09 — Stage 2 printtarg UI & argv builder
  • 10 — Print system shared types (PrinterPaperSize, PrintOptions.paperSize — the spec names it paper_size; the Swift field is camelCase, PrinterModels.swift:100)
  • 11 — macOS printing and ColorSync suppression

Scope

  1. Stage 2 UI: Add paper size picker and print quality picker to the print panel (below/beside tray/media/orientation)
  2. PrintSessionViewModel: Add selectedPaperSize and selectedQuality @Published properties
  3. PrinterCapabilities: Already has paperSizes: [PrinterPaperSize] — wire it to the UI
  4. Quality options: Extract from lpoptions -l (keys like EPIJ_Qual, cupsPrintQuality, Quality, CNIJQuality, StpQuality, OutputMode, Resolution) and/or PPD *OpenUI entries
  5. PrintOptions: Pass paperSize and quality through captured cupsOptions when opening printer properties
  6. Printer properties dialog: Pre-select the chosen paper size and quality in the NSPrintPanel — paper size + quality only here; media type + orientation preselect, capture-return of all fields, and binding verification are #186 scope

Implementation notes

  • The Stage 2 paper picker is an editable picker that re-mirrors Stage 1's workflow.pageSize: it seeds from pageSize and re-seeds on pageSize change or capabilities reload, but remains user-editable otherwise
  • Custom page size from Stage 1 (customPageW/customPageH) maps to a custom PageSize entry: the PPD token Custom.WIDTHxHEIGHT is a template — emit Custom.<w>x<h> in points (mm × 72/25.4); synthetic picker entry id: 0, label Custom (W×H mm)
  • Quality options come from the printer driver — enumerate via lpoptions -p <queue> -l and PPD parsing
  • The PrinterCapabilities.paperSizes array is already populated but unused by Stage 2 UI (docs/10 §PrinterPaperSize gap)
  • When opening printer properties (NSPrintPanel), pre-set PMPageFormat paper size and PMPrintSettings quality before runModal
  • Quality key detection: the capture-relevance roster is CupsOptionsFilter.relevantKeys (Packages/ICCeryCore/Sources/ICCeryCore/Print/CupsOptionsFilter.swift:16-32). CupsParsers holds mediaTypeKeys, bypassKeys, detectMediaTypeKey, detectDriverColorBypass only (CupsParsers.swift:217-263) — a new quality-key roster/detector is needed. Include EPIJ_Qual (see issue #180)

Rewrite invariants

  • Never search $PATH for binaries (use /usr/bin/lpoptions via CupsService)
  • Atomic writes = .tmp + rename (#213)
  • User-supplied strings via SwiftUI Text only (#114)
  • ARGYLL_NOT_INTERACTIVE=1 on every spawn
  • No blocking subprocess I/O on @MainActor

Dependencies

  • Depends on: Issues 12, 13, 14, 17 (M3 printing infrastructure — already complete)
  • Blocks: #180, #181, #186 (bug fixes that need the quality/media pickers to exist)
  • Scope split with #186: this issue wires the showProperties initial-selections plumbing for paper size + quality only; #186 completes media type + orientation preselect, capture-return of all fields, and binding verification

Test

  • CI/mock: Fixture lpoptions -l output with multiple paper sizes and quality options; verify UI populates pickers; verify PrintOptions carries values to build_lp_args
  • Hardware: Real Epson/Canon queue — verify paper size and quality pickers show driver options; verify printer properties dialog pre-selects chosen values

Acceptance criteria

  • Stage 2 print panel shows paper size picker (populated from printer capabilities; seeded from Stage 1 pageSize and re-mirroring on pageSize change / caps reload, editable otherwise)
  • Stage 2 print panel shows print quality picker (populated from printer driver options)
  • Selected paper size and quality are passed to PrintOptions when printing
  • Printer properties dialog (NSPrintPanel) opens with selected printer pre-bound AND paper size/quality pre-selected (media type + orientation preselect is #186 scope)
  • Custom page size from Stage 1 maps to a custom paper size entry (Custom.<w>x<h> in points)
## Summary Stage 2 printer details selection allows selection of the printer, media type, and orientation, but not quality or paper size settings from the ICCery screen. The paper size should follow the setting selected at the top of Stage 1 (defaults to A4) and default to portrait orientation. Print quality options should be populated from the printer's capabilities (lpoptions -l / PPD). ## Spec refs - [09](09-stage2-printtarg.md) — Stage 2 printtarg UI & argv builder - [10](10-print-system.md) — Print system shared types (PrinterPaperSize, `PrintOptions.paperSize` — the spec names it `paper_size`; the Swift field is camelCase, PrinterModels.swift:100) - [11](11-print-macos.md) — macOS printing and ColorSync suppression ## Scope 1. **Stage 2 UI**: Add paper size picker and print quality picker to the print panel (below/beside tray/media/orientation) 2. **PrintSessionViewModel**: Add `selectedPaperSize` and `selectedQuality` @Published properties 3. **PrinterCapabilities**: Already has `paperSizes: [PrinterPaperSize]` — wire it to the UI 4. **Quality options**: Extract from `lpoptions -l` (keys like `EPIJ_Qual`, `cupsPrintQuality`, `Quality`, `CNIJQuality`, `StpQuality`, `OutputMode`, `Resolution`) and/or PPD `*OpenUI` entries 5. **PrintOptions**: Pass `paperSize` and quality through captured `cupsOptions` when opening printer properties 6. **Printer properties dialog**: Pre-select the chosen paper size and quality in the NSPrintPanel — **paper size + quality only here**; media type + orientation preselect, capture-return of all fields, and binding verification are #186 scope ## Implementation notes - The Stage 2 paper picker is an **editable picker that re-mirrors** Stage 1's `workflow.pageSize`: it seeds from `pageSize` and re-seeds on pageSize change or capabilities reload, but remains user-editable otherwise - Custom page size from Stage 1 (`customPageW`/`customPageH`) maps to a custom `PageSize` entry: the PPD token `Custom.WIDTHxHEIGHT` is a template — emit `Custom.<w>x<h>` in **points** (mm × 72/25.4); synthetic picker entry `id: 0`, label `Custom (W×H mm)` - Quality options come from the printer driver — enumerate via `lpoptions -p <queue> -l` and PPD parsing - The `PrinterCapabilities.paperSizes` array is already populated but unused by Stage 2 UI (docs/10 §PrinterPaperSize gap) - When opening printer properties (NSPrintPanel), pre-set `PMPageFormat` paper size and `PMPrintSettings` quality before `runModal` - Quality key detection: the capture-relevance roster is `CupsOptionsFilter.relevantKeys` (Packages/ICCeryCore/Sources/ICCeryCore/Print/CupsOptionsFilter.swift:16-32). `CupsParsers` holds `mediaTypeKeys`, `bypassKeys`, `detectMediaTypeKey`, `detectDriverColorBypass` only (CupsParsers.swift:217-263) — a new quality-key roster/detector is needed. Include `EPIJ_Qual` (see issue #180) ## Rewrite invariants - Never search `$PATH` for binaries (use `/usr/bin/lpoptions` via CupsService) - Atomic writes = `.tmp` + rename (#213) - User-supplied strings via SwiftUI `Text` only (#114) - `ARGYLL_NOT_INTERACTIVE=1` on every spawn - No blocking subprocess I/O on `@MainActor` ## Dependencies - **Depends on:** Issues 12, 13, 14, 17 (M3 printing infrastructure — already complete) - **Blocks:** #180, #181, #186 (bug fixes that need the quality/media pickers to exist) - **Scope split with #186:** this issue wires the `showProperties` initial-selections plumbing for **paper size + quality only**; #186 completes media type + orientation preselect, capture-return of all fields, and binding verification ## Test - CI/mock: Fixture `lpoptions -l` output with multiple paper sizes and quality options; verify UI populates pickers; verify `PrintOptions` carries values to `build_lp_args` - Hardware: Real Epson/Canon queue — verify paper size and quality pickers show driver options; verify printer properties dialog pre-selects chosen values ## Acceptance criteria - [ ] Stage 2 print panel shows paper size picker (populated from printer capabilities; seeded from Stage 1 `pageSize` and re-mirroring on pageSize change / caps reload, editable otherwise) - [ ] Stage 2 print panel shows print quality picker (populated from printer driver options) - [ ] Selected paper size and quality are passed to `PrintOptions` when printing - [ ] Printer properties dialog (NSPrintPanel) opens with selected printer pre-bound AND paper size/quality pre-selected (media type + orientation preselect is #186 scope) - [ ] Custom page size from Stage 1 maps to a custom paper size entry (`Custom.<w>x<h>` in points)
gronod added this to the M11 — Printer settings completeness & dialog binding milestone 2026-09-15 11:58:22 +01:00
Author
Owner

Planning errata for the implementation contract (verified on develop@736fd08 — code is ground truth):

  1. "reuse CupsParsers.relevantKeys" — the roster is CupsOptionsFilter.relevantKeys (Packages/ICCeryCore/Sources/ICCeryCore/Print/CupsOptionsFilter.swift:16–32). CupsParsers holds mediaTypeKeys, bypassKeys, detectMediaTypeKey, detectDriverColorBypass only (CupsParsers.swift:217–263).
  2. PrintOptions.paper_size — the Swift field is paperSize (camelCase, PrinterModels.swift:100); paper_size is docs/10 spec naming.
  3. Scope split with #186: the AC "dialog … paper size/quality pre-selected" is satisfied here for paper size + quality only — this issue wires the showProperties initial-selections plumbing for those two. #186 completes media type + orientation preselect, capture-return of all fields, and binding verification.
  4. "mirror … not be independent" vs AC "defaulting to" — resolved: the Stage 2 paper picker is an editable picker that re-mirrors workflow.pageSize on pageSize change or caps reload.
  5. Custom mapping: the PPD token Custom.WIDTHxHEIGHT is a template — emit Custom.<w>x<h> in points (mm × 72/25.4); synthetic picker entry id: 0, label Custom (W×H mm).
Planning errata for the implementation contract (verified on develop@736fd08 — code is ground truth): 1. "reuse `CupsParsers.relevantKeys`" — the roster is `CupsOptionsFilter.relevantKeys` (Packages/ICCeryCore/Sources/ICCeryCore/Print/CupsOptionsFilter.swift:16–32). `CupsParsers` holds `mediaTypeKeys`, `bypassKeys`, `detectMediaTypeKey`, `detectDriverColorBypass` only (CupsParsers.swift:217–263). 2. `PrintOptions.paper_size` — the Swift field is `paperSize` (camelCase, PrinterModels.swift:100); `paper_size` is docs/10 spec naming. 3. Scope split with #186: the AC "dialog … paper size/quality pre-selected" is satisfied here for **paper size + quality only** — this issue wires the `showProperties` initial-selections plumbing for those two. #186 completes media type + orientation preselect, capture-return of all fields, and binding verification. 4. "mirror … not be independent" vs AC "defaulting to" — resolved: the Stage 2 paper picker is an **editable picker that re-mirrors** `workflow.pageSize` on pageSize change or caps reload. 5. Custom mapping: the PPD token `Custom.WIDTHxHEIGHT` is a template — emit `Custom.<w>x<h>` in **points** (mm × 72/25.4); synthetic picker entry `id: 0`, label `Custom (W×H mm)`.
gronod added the Feature/UIKind/Feature
Priority
Medium
3
Project/ICCery-v2
labels 2026-09-15 17:47:20 +01:00
Author
Owner

Errata above incorporated into the issue body — the ticket itself is now the corrected contract.

Errata above incorporated into the issue body — the ticket itself is now the corrected contract.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Reference: gronod/iccery-v2-mac#183