fix: printer match, landscape, margins, globs, layout CLI, sheet printer - #269
Conversation
#263) - #264: ResolveCliPrinter exact→prefix→substring; fail-fast unknown/ambiguous (including --what-if); SettingsContext passes installed list to ApplyOptions - #267: MAUI Windows XPS spool sets PrintTicket.PageOrientation; GDI re-applies landscape after paper size and on QueryPageSettings - #268: default sheet margins 0.33"; Proportional 2-Up page separator off - #263: FileArgumentExpander for * / ? on print, tui, and gui paths Test-first coverage for printer CLI resolve and glob expansion.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4ec44245f2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
- NamedChoiceResolver + CliOptionsResolver: resolve at SettingsContext/MAUI edge - ApplyOptions only applies already-resolved printer/paper (no null-list bypass) - MAUI shows DisplayAlert on resolve failure instead of crashing startup - Paper fail-fast when a paper list is supplied; TUI still omits paper list - Print ticket: orientation only (WindowsPrintTicketHelper + unit tests) - Spool takes PrintPageSetup; GDI unsubscribes QueryPageSettings on Dispose - ExpandSingle for TUI (exactly one file); PrintCommand PDF check only post-glob
- GetIntOrThrow: fail on non-integer option values with a glued-flag hint (e.g. --to-sheet 2--printer no longer silently means all sheets) - PrintCommand validates options and that every file exists before printing anything — stops partial jobs that hit default PDF then fail on a mis-parsed Brother name treated as a second file
…#3 #30) - #4: --rows / --columns on shared option surface + ApplyOptions - #3: header/footer on|off, text, font, border on|off flags; Font.TryParse - #30: SheetSettings.Printer / PaperSize applied on sheet select; CLI overrides - #268/#267/#263 already on this branch (margins, landscape ticket, globs)
1. CliOptionsApplier extracted; AppViewModel ApplyOptions is a thin delegate (~939 lines) 2. Collapse 16 border on/off flags to --header-borders / --footer-borders (none|all|top,bottom) 3. Invalid --header-font / --footer-font throw instead of silent skip 4. FileNotFound always hints about missing space before --printer (no vendor heuristic) 5. Sheet printer/paper only applied on userInitiated SelectSheet (content-type auto left alone)
Matches what scripts/verify-style.sh rewrites on CI (jb cleanupcode + format).
There was a problem hiding this comment.
Pull request overview
This PR improves WinPrint’s command-line and sheet configuration workflows across Core, TUI, and MAUI, focusing on fail-fast validation, more ergonomic printer selection, richer layout/header/footer CLI options, and Windows landscape correctness for physical printers.
Changes:
- Add CLI support for
--rows/--columnsand compact header/footer options (text/font/borders), with centralized apply/resolve helpers in Core. - Implement shell-agnostic glob expansion for positional file arguments and stricter option binding to prevent “glued flag” partial printing.
- Improve printing behavior and defaults: Windows XPS PrintTicket orientation for MAUI, GDI landscape re-apply for Core WindowsPrintJob, and updated default margins/page-separator defaults; allow sheets to bind preferred printer/paper size.
Reviewed changes
Copilot reviewed 41 out of 41 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/WinPrint.TUI.UnitTests/StickyPrinterRestoreTests.cs | Adds tests for CLI printer resolution (partial match / unknown printer fail-fast). |
| tests/WinPrint.TUI.UnitTests/PrintCommandValidationTests.cs | New tests ensuring print validation fails before any printer interaction on bad args. |
| tests/WinPrint.TUI.UnitTests/CommandOptionsBinderTests.cs | New tests for strict int parsing (GetIntOrThrow) to catch glued-flag cases. |
| tests/WinPrint.Maui.UnitTests/CommandLineOptionsConsistencyTests.cs | Extends MAUI/Core option catalog consistency checks to new CLI options. |
| tests/WinPrint.Core.UnitTests/WinPrintOptionsConsistencyTests.cs | Extends shared option mapping and updates reflection type assertions for nullable refs. |
| tests/WinPrint.Core.UnitTests/WinPrint.Core.UnitTests.csproj | Links Windows PrintTicket helper into Core tests and adds WindowsDesktop framework ref. |
| tests/WinPrint.Core.UnitTests/ViewModels/NamedChoiceResolveTests.cs | Adds coverage for exact/prefix/substring matching and ambiguous/no-match errors. |
| tests/WinPrint.Core.UnitTests/ViewModels/CliSheetAndLayoutOptionsTests.cs | Tests applying rows/cols, header/footer flags, and sheet-bound printer/paper behavior. |
| tests/WinPrint.Core.UnitTests/ViewModels/CliOptionsResolverTests.cs | Tests CLI edge resolution that rewrites printer/paper names or throws. |
| tests/WinPrint.Core.UnitTests/ViewModels/CliOptionsApplierTests.cs | Tests extracted applier logic: borders parsing, font parsing, and sheet printer gating. |
| tests/WinPrint.Core.UnitTests/ViewModels/AppViewModelTests.cs | Updates ApplyOptions tests to reflect new “resolve at edge, apply in VM” contract. |
| tests/WinPrint.Core.UnitTests/Printing/WindowsPrintTicketHelperTests.cs | Adds unit tests for PrintTicket orientation-only helper behavior. |
| tests/WinPrint.Core.UnitTests/Models/ProportionalSheetDefaultsTests.cs | Updates expectations for #268 margin defaults and proportional 2-up separator default. |
| tests/WinPrint.Core.UnitTests/Models/FontParseTests.cs | Adds tests for parsing CLI font strings into model Font instances. |
| tests/WinPrint.Core.UnitTests/Models/BorderSidesParseTests.cs | Adds tests for compact header/footer border side parsing. |
| tests/WinPrint.Core.UnitTests/Helpers/FileArgumentExpanderTests.cs | Adds tests for glob expansion semantics, ordering, and zero-match errors. |
| tests/WinPrint.Core.UnitTests/Helpers/FileArgumentExpanderSingleTests.cs | Adds tests for single-file glob expansion used by the TUI open path. |
| src/WinPrint.TUI/TuiCommand.cs | Uses glob expansion for TUI positional file argument (exactly one file). |
| src/WinPrint.TUI/SettingsContext.cs | Adds CLI-edge printer resolution before applying options (no “null list bypass”). |
| src/WinPrint.TUI/PrintCommand.cs | Adds preflight option validation, glob expansion, and “validate all paths first” printing behavior. |
| src/WinPrint.TUI/GuiCommand.cs | Expands globs before forwarding absolute paths to the GUI launcher. |
| src/WinPrint.TUI/CommandOptionsBinder.cs | Introduces strict GetIntOrThrow and binds new CLI options into Core Options. |
| src/WinPrint.Maui/Platforms/Windows/WindowsSkiaPrintJob.cs | Applies PrintTicket orientation for XPS spooling and refactors spool parameter passing. |
| src/WinPrint.Maui/Platforms/Windows/WindowsPrintTicketHelper.cs | Adds helper to apply orientation to PrintTicket without forcing media size. |
| src/WinPrint.Maui/MainPage.xaml.cs | Resolves partial printer/paper names on startup and shows UI error for invalid options. |
| src/WinPrint.Maui/CommandLineOptions.cs | Adds MAUI CLI options for rows/cols and header/footer configuration; maps into Core Options. |
| src/WinPrint.Core/WinPrintOptions.cs | Extends canonical shared option catalog with rows/cols and header/footer options. |
| src/WinPrint.Core/ViewModels/PrinterSelection.cs | Exposes a helper to resolve CLI printer queries via NamedChoiceResolver. |
| src/WinPrint.Core/ViewModels/NamedChoiceResolver.cs | Implements shared exact/prefix/substring name resolution with helpful errors. |
| src/WinPrint.Core/ViewModels/NamedChoiceMatch.cs | Adds result type representing success/failure of named-choice resolution. |
| src/WinPrint.Core/ViewModels/CliOptionsResolver.cs | Adds CLI-edge resolver that rewrites Options.Printer/PaperSize to canonical names or throws. |
| src/WinPrint.Core/ViewModels/CliOptionsApplier.cs | Extracts CLI application logic from AppViewModel for rows/cols and header/footer options. |
| src/WinPrint.Core/ViewModels/AppViewModel.cs | Applies sheet-bound printer/paper on user selection; delegates CLI apply; adds border/font setters. |
| src/WinPrint.Core/Printing/WindowsPrintJob.cs | Re-applies landscape after paper size selection and on QueryPageSettings per page. |
| src/WinPrint.Core/Models/SheetSettings.cs | Adds optional per-sheet Printer and PaperSize properties with telemetry copy support. |
| src/WinPrint.Core/Models/Settings.cs | Updates default margins to 0.33" and disables proportional 2-up page separator. |
| src/WinPrint.Core/Models/Options.cs | Adds Options fields for rows/cols and header/footer configuration flags/values. |
| src/WinPrint.Core/Models/Font.cs | Adds CLI font parsing (Font.TryParse). |
| src/WinPrint.Core/Models/BorderSidesParser.cs | Adds parser for compact border side lists. |
| src/WinPrint.Core/Models/BorderSides.cs | Adds flags enum representing border sides. |
| src/WinPrint.Core/Helpers/FileArgumentExpander.cs | Adds wildcard expansion helper for positional file arguments with deterministic ordering. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
LoadFileAsync was selecting the markdown Proportional sheet after ApplyOptions had already set --header-off/--footer-text on Default 2-Up, so print always used stock HF. Remember CLI Options and re-apply sheet-level overrides after the content-type SelectSheet. Regression test covers the print pipeline copy.
…lists - FileArgumentExpander: support wildcards in directory segments and ** recursion - PrintPageSetup.Clone for true STA spool snapshot (not reference copy) - NamedChoiceResolver: FormatAmbiguous truncates like FormatNoMatch (max 12)
Summary
Closes #264, #267, #268, #263, #4, #3, #30.
Already on branch
--printer+ fail-fastThis commit
--rows/--columns--header-off,--footer-text,--footer-font, border on/off, …)printer+paperSize; applied on select; CLI still winsTest plan
wp print … --rows 1 --columns 2 --footer-off --header-text CLI --what-if