mirror of
https://github.com/storytold/photocraft.git
synced 2026-10-28 10:11:58 +01:00
fix(ui): expose custom paper dimensions in Print Settings (#3893)
* fix(ui): expose custom paper dimensions in Print Settings * fix(i18n): keep custom paper labels away from catalog tails * Custom print paper: Serbian rows; drop the env-gated capture test Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: zenjabba <679864+zenjabba@users.noreply.github.com> Co-authored-by: Brandon Thomas <echelon@gmail.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
zenjabba
Brandon Thomas
Claude Opus 5.5
parent
8c135457b4
commit
a80fefce5c
@@ -731,6 +731,10 @@ fn unit_pt(units: &str) -> f64 {
|
||||
|
||||
/// A number field in `units` for a value kept in points; true when edited.
|
||||
fn length_field(ui: &mut egui::Ui, label: &str, pt: &mut f64, units: &str) -> bool {
|
||||
length_field_prec(ui, label, pt, units, 0)
|
||||
}
|
||||
|
||||
fn length_field_prec(ui: &mut egui::Ui, label: &str, pt: &mut f64, units: &str, decimals: u32) -> bool {
|
||||
let t = Tokens::get(ui.ctx());
|
||||
let k = unit_pt(units);
|
||||
let mut v = (*pt / k) as f32;
|
||||
@@ -738,7 +742,7 @@ fn length_field(ui: &mut egui::Ui, label: &str, pt: &mut f64, units: &str) -> bo
|
||||
ui.horizontal(|ui| {
|
||||
ui.label(egui::RichText::new(label).color(t.text_dim));
|
||||
let before = v;
|
||||
crate::widgets::value_field(ui, &mut v, 0.0..=10000.0, units, 70.0);
|
||||
crate::widgets::value_field_prec(ui, &mut v, 0.0..=10000.0, units, 70.0, decimals);
|
||||
if (v - before).abs() > 1e-4 && v.is_finite() {
|
||||
*pt = f64::from(v) * k;
|
||||
changed = true;
|
||||
@@ -747,6 +751,53 @@ fn length_field(ui: &mut egui::Ui, label: &str, pt: &mut f64, units: &str) -> bo
|
||||
changed
|
||||
}
|
||||
|
||||
/// Unrotated paper dimensions in points, for either the current preset or a custom array.
|
||||
fn print_paper_size(value: Option<&Value>) -> (f64, f64) {
|
||||
let default = (612.0, 792.0);
|
||||
match value {
|
||||
Some(Value::Array(a)) => (a.first().and_then(Value::as_f64).unwrap_or(default.0), a.get(1).and_then(Value::as_f64).unwrap_or(default.1)),
|
||||
Some(Value::String(name)) => photocraft_engine::print_cmds::PAPERS.iter().find(|p| p.0.eq_ignore_ascii_case(name)).map_or(default, |p| (p.1, p.2)),
|
||||
_ => default,
|
||||
}
|
||||
}
|
||||
|
||||
fn print_paper_controls(ui: &mut egui::Ui, f: &mut Map<String, Value>) {
|
||||
let previous = f.get("paper").cloned();
|
||||
let mut selected = if previous.as_ref().is_some_and(Value::is_array) { "custom".to_string() } else { s(f, "paper", "letter") };
|
||||
ui.horizontal(|ui| {
|
||||
let mut papers: Vec<_> = photocraft_engine::print_cmds::PAPERS.iter().map(|p| (p.0.to_string(), p.0)).collect();
|
||||
papers.push(("custom".to_string(), tl!("Custom")));
|
||||
if crate::widgets::dropdown(ui, "print-paper", &mut selected, &papers, 110.0) {
|
||||
if selected == "custom" {
|
||||
let (w, h) = print_paper_size(f.get("__customPaper").or(previous.as_ref()));
|
||||
f.insert("paper".into(), json!([w, h]));
|
||||
} else {
|
||||
if let Some(paper @ Value::Array(_)) = previous {
|
||||
f.insert("__customPaper".into(), paper);
|
||||
}
|
||||
f.insert("paper".into(), json!(selected));
|
||||
}
|
||||
}
|
||||
dropdown_str(ui, "print-orient", f, "orientation", &[("portrait", tl!("Portrait")), ("landscape", tl!("Landscape"))], 110.0);
|
||||
});
|
||||
if f.get("paper").is_some_and(Value::is_array) {
|
||||
let (mut w, mut h) = print_paper_size(f.get("paper"));
|
||||
let units = s(f, "units", "cm");
|
||||
let changed = ui
|
||||
.horizontal(|ui| {
|
||||
let wc = length_field_prec(ui, tl!("Paper Width"), &mut w, &units, 2);
|
||||
let hc = length_field_prec(ui, tl!("Paper Height"), &mut h, &units, 2);
|
||||
wc || hc
|
||||
})
|
||||
.inner;
|
||||
if changed {
|
||||
// Keep points in the command, and let the engine apply orientation and validation.
|
||||
f.insert("paper".into(), json!([w, h]));
|
||||
f.insert("__customPaper".into(), json!([w, h]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn print_body(app: &mut PhotocraftApp, ui: &mut egui::Ui, f: &mut Map<String, Value>) {
|
||||
let t = Tokens::get(ui.ctx());
|
||||
let Some(doc) = app.session.active().map(|d| d.doc.clone()) else { return };
|
||||
@@ -834,11 +885,7 @@ fn print_body(app: &mut PhotocraftApp, ui: &mut egui::Ui, f: &mut Map<String, Va
|
||||
}
|
||||
});
|
||||
number(ui, f, "copies", tl!("Copies"), 1.0..=999.0, "", 1.0);
|
||||
ui.horizontal(|ui| {
|
||||
let papers: Vec<(&str, &str)> = photocraft_engine::print_cmds::PAPERS.iter().map(|p| (p.0, p.0)).collect();
|
||||
dropdown_str(ui, "print-paper", f, "paper", &papers, 110.0);
|
||||
dropdown_str(ui, "print-orient", f, "orientation", &[("portrait", tl!("Portrait")), ("landscape", tl!("Landscape"))], 110.0);
|
||||
});
|
||||
print_paper_controls(ui, f);
|
||||
head(ui, tl!("Color Management"));
|
||||
dropdown_str(
|
||||
ui,
|
||||
|
||||
@@ -20,6 +20,10 @@
|
||||
# dialog commands is kept.
|
||||
|
||||
# Guide layout dialog
|
||||
|
||||
# Custom print paper (#3820)
|
||||
Paper Width Šířka papíru
|
||||
Paper Height Výška papíru
|
||||
Columns Sloupce
|
||||
Rows Řádky
|
||||
Number Počet
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -16,6 +16,10 @@
|
||||
# letters; the trailing "…" of dialog commands is kept. Plural rule: one|other (n != 1 -> other).
|
||||
|
||||
# Guide layout dialog
|
||||
|
||||
# Custom print paper (#3820)
|
||||
Paper Width Papierbreite
|
||||
Paper Height Papierhöhe
|
||||
Columns Spalten
|
||||
Rows Zeilen
|
||||
Number Anzahl
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -4,6 +4,10 @@
|
||||
# Covers every source label the i18n coverage check lists.
|
||||
|
||||
# Guide layout dialog
|
||||
|
||||
# Custom print paper (#3820)
|
||||
Paper Width Πλάτος χαρτιού
|
||||
Paper Height Ύψος χαρτιού
|
||||
Rows Γραμμές
|
||||
Number Πλήθος
|
||||
Top: Επάνω:
|
||||
|
||||
|
@@ -13,6 +13,10 @@
|
||||
# letters; the trailing "…" of dialog commands is kept.
|
||||
|
||||
# Guide layout dialog
|
||||
|
||||
# Custom print paper (#3820)
|
||||
Paper Width Ancho del papel
|
||||
Paper Height Altura del papel
|
||||
Columns Columnas
|
||||
Rows Filas
|
||||
Number Número
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 4 and column 47.
|
@@ -20,6 +20,10 @@
|
||||
# dialog commands is kept.
|
||||
|
||||
# Guide layout dialog
|
||||
|
||||
# Custom print paper (#3820)
|
||||
Paper Width Largeur du papier
|
||||
Paper Height Hauteur du papier
|
||||
Rows Lignes
|
||||
Number Nombre
|
||||
Margin Marge
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -17,6 +17,10 @@
|
||||
# singular noun in Hungarian, so every @plural entry has a single form.
|
||||
|
||||
# Plural messages and command id overrides
|
||||
# Custom paper dimensions in Print Settings.
|
||||
Paper Width Papír szélessége
|
||||
Paper Height Papír magassága
|
||||
|
||||
@id edit.purge.undo Visszavonási adatok
|
||||
@id edit.stroke Körvonalazás…
|
||||
@id edit.transform.scale Méretezés
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -13,6 +13,10 @@
|
||||
# letters; the trailing "…" of dialog commands is kept.
|
||||
|
||||
# Guide layout dialog
|
||||
|
||||
# Custom print paper (#3820)
|
||||
Paper Width Lebar kertas
|
||||
Paper Height Tinggi kertas
|
||||
Rows Baris
|
||||
Number Jumlah
|
||||
Margin Margin
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 4 and column 47.
|
@@ -13,6 +13,10 @@
|
||||
# letters; the trailing … of dialog commands is kept.
|
||||
|
||||
# Guide layout dialog
|
||||
|
||||
# Custom print paper (#3820)
|
||||
Paper Width Larghezza della carta
|
||||
Paper Height Altezza della carta
|
||||
Columns Colonne
|
||||
Rows Righe
|
||||
Number Numero
|
||||
|
||||
|
@@ -16,6 +16,10 @@
|
||||
# letters; the trailing "…" of dialog commands is kept.
|
||||
|
||||
# Guide layout dialog
|
||||
|
||||
# Custom print paper (#3820)
|
||||
Paper Width 用紙の幅
|
||||
Paper Height 用紙の高さ
|
||||
Rows 行
|
||||
Number 数
|
||||
Top: 上:
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -8,6 +8,10 @@
|
||||
# Product names and technology names retain their spelling.
|
||||
|
||||
# Guide layout dialog
|
||||
|
||||
# Custom print paper (#3820)
|
||||
Paper Width 용지 너비
|
||||
Paper Height 용지 높이
|
||||
Columns 열
|
||||
Rows 행
|
||||
Number 개수
|
||||
|
||||
|
@@ -9,6 +9,10 @@
|
||||
# informally ("je") and uses sentence case.
|
||||
|
||||
# Guide layout dialog
|
||||
|
||||
# Custom print paper (#3820)
|
||||
Paper Width Papierbreedte
|
||||
Paper Height Papierhoogte
|
||||
Rows Rijen
|
||||
Number Aantal
|
||||
Top: Boven:
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 8 and column 34.
|
@@ -19,6 +19,10 @@
|
||||
# Zapisz jako…), sentence case as in the English source. Quotes: „…”.
|
||||
|
||||
# Guide layout dialog
|
||||
|
||||
# Custom print paper (#3820)
|
||||
Paper Width Szerokość papieru
|
||||
Paper Height Wysokość papieru
|
||||
Rows Wiersze
|
||||
Number Liczba
|
||||
Top: Góra:
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -16,6 +16,10 @@
|
||||
# stay as they are; the trailing "…" of dialog commands is kept.
|
||||
|
||||
# Guide layout dialog
|
||||
|
||||
# Custom print paper (#3820)
|
||||
Paper Width Largura do papel
|
||||
Paper Height Altura do papel
|
||||
Rows Linhas
|
||||
Number Número
|
||||
Margin Margem
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -20,6 +20,10 @@
|
||||
# Menus
|
||||
|
||||
# Guide layout dialog
|
||||
|
||||
# Custom print paper (#3820)
|
||||
Paper Width Ширина бумаги
|
||||
Paper Height Высота бумаги
|
||||
Rows Строки
|
||||
Number Количество
|
||||
Margin Поля
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -4185,3 +4185,7 @@ shape Appearance Izgled
|
||||
Import .GRD Uvezi .GRD
|
||||
Choose a gradient file (.grd). Izaberite datoteku gradijenta (.grd).
|
||||
Auto Add/Delete Automatsko dodavanje/brisanje
|
||||
|
||||
# Custom print paper (#3820)
|
||||
Paper Width Širina papira
|
||||
Paper Height Visina papira
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -7,6 +7,10 @@
|
||||
# entries the same way. Product and technology names (PhotoCraft, ArtCraft, OpenType, CMYK, Lab ...)
|
||||
# stay as they are; the trailing "…" of dialog commands is kept.
|
||||
#
|
||||
# Custom paper dimensions in Print Settings.
|
||||
Paper Width Kağıt Genişliği
|
||||
Paper Height Kağıt Yüksekliği
|
||||
|
||||
Rows Satırlar
|
||||
Number Sayı
|
||||
Top: Üst:
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 8 and column 34.
|
@@ -11,6 +11,10 @@
|
||||
# Menus
|
||||
|
||||
# Guide layout dialog
|
||||
|
||||
# Custom print paper (#3820)
|
||||
Paper Width Ширина паперу
|
||||
Paper Height Висота паперу
|
||||
Rows Рядки
|
||||
Number Кількість
|
||||
Top: Зверху:
|
||||
|
||||
|
@@ -21,6 +21,10 @@
|
||||
|
||||
|
||||
# Phase 3.1 — top-level menus, File menu, Edit menu
|
||||
# Custom paper dimensions in Print Settings.
|
||||
Paper Width Chiều rộng giấy
|
||||
Paper Height Chiều cao giấy
|
||||
|
||||
Again Lặp lại
|
||||
AI Integrations… Tích hợp AI…
|
||||
All Tất cả
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -12,6 +12,10 @@
|
||||
# Product and technology names retain their spelling. See docs/localization-zh-hans.md.
|
||||
|
||||
# Guide layout dialog
|
||||
|
||||
# Custom print paper (#3820)
|
||||
Paper Width 纸张宽度
|
||||
Paper Height 纸张高度
|
||||
Columns 列
|
||||
Rows 行
|
||||
Number 数量
|
||||
|
||||
|
@@ -20,6 +20,10 @@
|
||||
# separators as in the English.
|
||||
|
||||
# Guide layout dialog
|
||||
|
||||
# Custom print paper (#3820)
|
||||
Paper Width 紙張寬度
|
||||
Paper Height 紙張高度
|
||||
Columns 欄
|
||||
Rows 列
|
||||
Number 數量
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -0,0 +1,142 @@
|
||||
//! #3820: edit custom paper through the real Print dialog, preview it, and print safely to PDF.
|
||||
use egui::{Event, Key, Modifiers, PointerButton, vec2};
|
||||
use egui_kittest::{Harness, kittest::Queryable};
|
||||
use photocraft_ui_egui::{PhotocraftApp, file_ui::open_print};
|
||||
use serde_json::{Map, Value, json};
|
||||
|
||||
fn app() -> (PhotocraftApp, u64) {
|
||||
let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), photocraft_ui_egui::Services::default());
|
||||
app.run("file.new", json!({"width": 120, "height": 80, "name": "Custom paper"})).unwrap();
|
||||
let id = open_print(&mut app);
|
||||
// Every UI path in these fixtures is safe even if an unexpected Enter confirms the dialog.
|
||||
app.ui.dialog_mut(id).unwrap().fields.insert("dryRun".into(), json!(true));
|
||||
(app, id)
|
||||
}
|
||||
|
||||
fn show(ui: &mut egui::Ui, app: &mut PhotocraftApp) {
|
||||
if ui.ctx().fonts(|fonts| fonts.families().contains(&egui::FontFamily::Name("medium".into()))) {
|
||||
photocraft_ui_egui::dialogs::show(app, ui.ctx());
|
||||
}
|
||||
}
|
||||
|
||||
fn harness(app: PhotocraftApp) -> Harness<'static, PhotocraftApp> {
|
||||
let mut h = Harness::builder().with_size(vec2(1000.0, 900.0)).with_max_steps(64).build_ui_state(show, app);
|
||||
PhotocraftApp::setup_context(&h.ctx, Default::default());
|
||||
h.run_steps(4);
|
||||
h
|
||||
}
|
||||
|
||||
fn click(h: &mut Harness<'_, PhotocraftApp>, label: &str) {
|
||||
if let Some(node) = h.query_by_label(label) {
|
||||
node.click();
|
||||
} else {
|
||||
h.get_by_value(label).click();
|
||||
}
|
||||
h.run_steps(3);
|
||||
}
|
||||
|
||||
fn shown(h: &Harness<'_, PhotocraftApp>, text: &str) -> bool {
|
||||
h.query_by_label(text).is_some() || h.query_by_value(text).is_some()
|
||||
}
|
||||
|
||||
fn enter_length(h: &mut Harness<'_, PhotocraftApp>, label: &str, value: &str) {
|
||||
// Anchor the pointer to the real label; the existing length widget immediately follows it.
|
||||
let pos = h.get_by_label(label).rect().right_center() + vec2(35.0, 0.0);
|
||||
h.event(Event::PointerMoved(pos));
|
||||
h.event(Event::PointerButton { pos, button: PointerButton::Primary, pressed: true, modifiers: Modifiers::NONE });
|
||||
h.run_steps(1);
|
||||
h.event(Event::PointerButton { pos, button: PointerButton::Primary, pressed: false, modifiers: Modifiers::NONE });
|
||||
h.run_steps(1);
|
||||
h.key_press_modifiers(Modifiers::COMMAND, Key::A);
|
||||
h.event(Event::Text(value.into()));
|
||||
h.run_steps(1);
|
||||
h.key_press(Key::Tab);
|
||||
h.run_steps(3);
|
||||
}
|
||||
|
||||
fn fields(h: &Harness<'_, PhotocraftApp>, id: u64) -> Map<String, Value> {
|
||||
h.state().ui.dialogs.iter().find(|d| d.id == id).unwrap().fields.clone()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn custom_paper_ui_edits_reach_preview_and_pdf_and_restore_when_reopened() {
|
||||
let (mut app, id) = app();
|
||||
let output = std::env::temp_dir().join(format!("pc-custom-paper-{}.pdf", std::process::id()));
|
||||
let dialog = app.ui.dialog_mut(id).unwrap();
|
||||
dialog.fields.insert("output".into(), json!(output.to_string_lossy()));
|
||||
dialog.fields.insert("dryRun".into(), json!(true));
|
||||
let mut h = harness(app);
|
||||
click(&mut h, "letter");
|
||||
assert!(shown(&h, "a4"), "the real preset menu must be open");
|
||||
assert!(shown(&h, "Custom"), "the paper menu must offer editable custom dimensions");
|
||||
click(&mut h, "Custom");
|
||||
assert_eq!(fields(&h, id)["paper"], json!([612.0, 792.0]), "Custom starts at the current preset dimensions");
|
||||
click(&mut h, "Centimeters");
|
||||
click(&mut h, "Inches");
|
||||
enter_length(&mut h, "Paper Width", "7.25");
|
||||
enter_length(&mut h, "Paper Height", "9.25");
|
||||
let edited = fields(&h, id);
|
||||
assert_eq!(edited["paper"], json!([522.0, 666.0]), "the engine takes points, not the displayed units");
|
||||
click(&mut h, "Custom");
|
||||
click(&mut h, "a4");
|
||||
assert_eq!(fields(&h, id)["paper"], "a4");
|
||||
assert!(!shown(&h, "Paper Width"));
|
||||
click(&mut h, "a4");
|
||||
click(&mut h, "Custom");
|
||||
assert_eq!(fields(&h, id)["paper"], edited["paper"], "returning from a preset restores the custom dimensions");
|
||||
click(&mut h, "Inches");
|
||||
click(&mut h, "Millimeters");
|
||||
assert_eq!(fields(&h, id)["paper"], edited["paper"], "changing units must not change the physical paper");
|
||||
click(&mut h, "Millimeters");
|
||||
click(&mut h, "Inches");
|
||||
assert_eq!(fields(&h, id)["paper"], edited["paper"]);
|
||||
let preview = photocraft_engine::print_cmds::layout(&h.state().session.active().unwrap().doc, &Value::Object(edited.clone()), "file.print").unwrap();
|
||||
assert_eq!(preview.paper, (522.0, 666.0));
|
||||
click(&mut h, "Portrait");
|
||||
click(&mut h, "Landscape");
|
||||
let edited = fields(&h, id);
|
||||
assert_eq!(edited["paper"], json!([522.0, 666.0]), "orientation must not rewrite the unrotated custom dimensions");
|
||||
let preview = photocraft_engine::print_cmds::layout(&h.state().session.active().unwrap().doc, &Value::Object(edited), "file.print").unwrap();
|
||||
assert_eq!(preview.paper, (666.0, 522.0));
|
||||
click(&mut h, "Print");
|
||||
let pdf = std::fs::read(&output).unwrap();
|
||||
assert!(String::from_utf8_lossy(&pdf).contains("/MediaBox [0 0 666.00 522.00]"));
|
||||
assert_eq!(h.state().session.file_menu.last_print.as_ref().unwrap()["paper"], json!([522.0, 666.0]));
|
||||
let id = open_print(h.state_mut());
|
||||
h.state_mut().ui.dialog_mut(id).unwrap().fields.insert("dryRun".into(), json!(true));
|
||||
h.run_steps(3);
|
||||
assert!(shown(&h, "Custom"), "reopening array-valued settings must show Custom");
|
||||
assert_eq!(fields(&h, id)["paper"], json!([522.0, 666.0]));
|
||||
std::fs::remove_file(output).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn remembered_custom_paper_is_shown_without_becoming_a_preset() {
|
||||
let (mut app, id) = app();
|
||||
app.ui.dialog_mut(id).unwrap().fields.insert("paper".into(), json!([432.0, 576.0]));
|
||||
let h = harness(app);
|
||||
assert!(shown(&h, "Custom"), "an array paper size must not display as letter");
|
||||
assert!(shown(&h, "Paper Width"));
|
||||
assert!(shown(&h, "Paper Height"));
|
||||
assert_eq!(fields(&h, id)["paper"], json!([432.0, 576.0]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_custom_paper_is_rejected_without_printing_or_changing_the_document() {
|
||||
let (mut app, id) = app();
|
||||
let output = std::env::temp_dir().join(format!("pc-invalid-custom-paper-{}.pdf", std::process::id()));
|
||||
app.ui.dialog_mut(id).unwrap().fields.insert("output".into(), json!(output.to_string_lossy()));
|
||||
let before = app.session.active().unwrap().doc.clone();
|
||||
let mut h = harness(app);
|
||||
click(&mut h, "letter");
|
||||
click(&mut h, "Custom");
|
||||
enter_length(&mut h, "Paper Width", "0");
|
||||
let edited = fields(&h, id);
|
||||
assert!(photocraft_engine::print_cmds::layout(&h.state().session.active().unwrap().doc, &Value::Object(edited), "file.print").is_err());
|
||||
click(&mut h, "Print");
|
||||
let error = &h.state().ui.status;
|
||||
assert!(error.contains("paper is too small"), "{error}");
|
||||
assert_eq!(h.state().session.active().unwrap().doc, before);
|
||||
assert!(h.state().session.file_menu.last_print.is_none());
|
||||
assert!(!output.exists());
|
||||
}
|
||||
Reference in New Issue
Block a user